diff --git a/DEPS b/DEPS index 4528b20..09cd77e2 100644 --- a/DEPS +++ b/DEPS
@@ -30,6 +30,7 @@ gclient_gn_args = [ 'checkout_libaom', 'checkout_nacl', + 'checkout_oculus_sdk', ] @@ -56,6 +57,9 @@ # libaom provides support for AV1 but the bitstream is not frozen. 'checkout_libaom': True, + # By default do not check out the Oculus SDK. Only available for Googlers. + 'checkout_oculus_sdk' : False, + # TODO(dpranke): change to != "small" once != is supported. 'checkout_traffic_annotation_tools': 'checkout_configuration == "default"', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', @@ -74,11 +78,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '84bfc9589878a95c2a017698398f153a53e54412', + 'skia_revision': '6613cc5186c200e053c5df9bd8f051ffba6e3564', # 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': '731ae996267793630be9d181e28c19c7a517579f', + 'v8_revision': '21824e4460224c1c0fd36005f6bff868de1a11b5', # 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. @@ -86,7 +90,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'ae4dbf32ba112c767d6e67d6e5734fc81d8c2d8c', + 'angle_revision': 'ca71c75dce600b2a0fde5a72c15c2b437cb961db', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -130,7 +134,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': '6abc09e80f31d1761009c10abcc3e21198cfa669', + 'catapult_revision': '86f49a7f8f7653d8d9bcd77106a388673a4d4b9c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -1294,6 +1298,20 @@ 'src/third_party/gvr-android-sdk/test-apks/update.py', ], }, + # Download Oculus SDK if appropriate. + { + 'name': 'libovr', + 'pattern': '.', + 'condition': 'checkout_oculus_sdk', + 'action': ['vpython', + 'src/third_party/depot_tools/download_from_google_storage.py', + '--bucket', 'chrome-oculus-sdk', + '--recursive', + '--num_threads=10', + '--directory', + 'src/third_party/libovr/src', + ], + }, { # Pull doclava binaries if building for Android. 'name': 'doclava',
diff --git a/ash/utility/screenshot_controller.cc b/ash/utility/screenshot_controller.cc index b9d801f..d48c743 100644 --- a/ash/utility/screenshot_controller.cc +++ b/ash/utility/screenshot_controller.cc
@@ -126,7 +126,7 @@ kSelectedAreaOverlayColor); } - DrawPseudoCursor(recorder.canvas()); + DrawPseudoCursor(recorder.canvas(), context.device_scale_factor()); if (!region_.IsEmpty()) recorder.canvas()->FillRect(region_, SK_ColorBLACK, SkBlendMode::kClear); @@ -137,7 +137,7 @@ // Mouse cursor may move sub DIP, so paint pseudo cursor instead of // using platform cursor so that it's aliend with the region. - void DrawPseudoCursor(gfx::Canvas* canvas) { + void DrawPseudoCursor(gfx::Canvas* canvas, float device_scale_factor) { // Don't draw if window selection mode. if (cursor_location_in_root_.IsOrigin()) return; @@ -152,10 +152,26 @@ pseudo_cursor_point.Offset(0, -1); cc::PaintFlags flags; - flags.setAntiAlias(false); - flags.setStrokeWidth(1); - flags.setColor(SK_ColorWHITE); flags.setBlendMode(SkBlendMode::kSrc); + + // Circle fill. + flags.setStyle(cc::PaintFlags::kFill_Style); + flags.setColor(SK_ColorGRAY); + flags.setAntiAlias(true); + const int stroke_width = 1; + flags.setStrokeWidth(stroke_width); + gfx::PointF circle_center(pseudo_cursor_point); + // For the circle to be exactly centered in the middle of the crosshairs, we + // need to take into account the stroke width of the crosshair as well as + // the device scale factor. + const float center_offset = + stroke_width / (2.0f * device_scale_factor * device_scale_factor); + circle_center.Offset(center_offset, center_offset); + const float circle_radius = (kCursorSize / 2.0f) - 2.5f; + canvas->DrawCircle(circle_center, circle_radius, flags); + + flags.setAntiAlias(false); + flags.setColor(SK_ColorWHITE); gfx::Vector2d width(kCursorSize / 2, 0); gfx::Vector2d height(0, kCursorSize / 2); gfx::Vector2d white_x_offset(1, -1); @@ -163,7 +179,6 @@ // Horizontal canvas->DrawLine(pseudo_cursor_point - width + white_x_offset, pseudo_cursor_point + width + white_x_offset, flags); - flags.setStrokeWidth(1); // Vertical canvas->DrawLine(pseudo_cursor_point - height + white_y_offset, pseudo_cursor_point + height + white_y_offset, flags); @@ -175,6 +190,12 @@ // Vertical canvas->DrawLine(pseudo_cursor_point - height, pseudo_cursor_point + height, flags); + + // Circle stroke. + flags.setColor(SK_ColorDKGRAY); + flags.setStyle(cc::PaintFlags::kStroke_Style); + flags.setAntiAlias(true); + canvas->DrawCircle(circle_center, circle_radius, flags); } bool draw_inactive_overlay_;
diff --git a/ash/wallpaper/wallpaper_controller.cc b/ash/wallpaper/wallpaper_controller.cc index 38608b1..2b49438 100644 --- a/ash/wallpaper/wallpaper_controller.cc +++ b/ash/wallpaper/wallpaper_controller.cc
@@ -506,6 +506,7 @@ void WallpaperController::SetWallpaperImage(const gfx::ImageSkia& image, const WallpaperInfo& info) { + current_user_wallpaper_info_ = info; wallpaper::WallpaperLayout layout = info.layout; VLOG(1) << "SetWallpaper: image_id=" << wallpaper::WallpaperResizer::GetImageId(image) @@ -516,7 +517,6 @@ return; } - current_location_ = info.location; // Cancel any in-flight color calculation because we have a new wallpaper. if (color_calculator_) { color_calculator_->RemoveObserver(this); @@ -664,6 +664,9 @@ void WallpaperController::SetUserWallpaperInfo(const AccountId& account_id, const WallpaperInfo& info, bool is_persistent) { + // TODO(xdai): Remove this line after wallpaper refactoring is done. + // |current_user_wallpaper_info_| will be later updated in SetWallpaperImage() + // so theoretically it should be safe to remove the udpate here. current_user_wallpaper_info_ = info; if (!is_persistent) return; @@ -906,8 +909,8 @@ color_calculator_.reset(); // TODO(crbug.com/787134): The prominent colors of wallpapers with empty // location should be cached as well. - if (!current_location_.empty()) - CacheProminentColors(colors, current_location_); + if (!current_user_wallpaper_info_.location.empty()) + CacheProminentColors(colors, current_user_wallpaper_info_.location); SetProminentColors(colors); } @@ -1117,9 +1120,9 @@ color_calculator_.reset(); } - if (!current_location_.empty()) { + if (!current_user_wallpaper_info_.location.empty()) { base::Optional<std::vector<SkColor>> cached_colors = - GetCachedColors(current_location_); + GetCachedColors(current_user_wallpaper_info_.location); if (cached_colors.has_value()) { SetProminentColors(cached_colors.value()); return;
diff --git a/ash/wallpaper/wallpaper_controller.h b/ash/wallpaper/wallpaper_controller.h index cdba53dd..c981c54 100644 --- a/ash/wallpaper/wallpaper_controller.h +++ b/ash/wallpaper/wallpaper_controller.h
@@ -460,7 +460,9 @@ // Caches the color profiles that need to do wallpaper color extracting. const std::vector<color_utils::ColorProfile> color_profiles_; - // Cached logged-in user wallpaper info. + // Cached current user wallpaper info. Note its location is used as a key for + // storing |prominent_colors_| in the wallpaper::kWallpaperColors pref. An + // empty string disables color caching. wallpaper::WallpaperInfo current_user_wallpaper_info_; // Cached wallpapers of users. @@ -473,11 +475,6 @@ base::FilePath customized_default_wallpaper_small_; base::FilePath customized_default_wallpaper_large_; - // Location (see WallpaperInfo::location) used by the current wallpaper. - // Used as a key for storing |prominent_colors_| in the - // wallpaper::kWallpaperColors pref. An empty string disables color caching. - std::string current_location_; - gfx::Size current_max_display_size_; base::OneShotTimer timer_;
diff --git a/build/android/gyp/process_resources.py b/build/android/gyp/process_resources.py index 31a87de..c6f74aa9 100755 --- a/build/android/gyp/process_resources.py +++ b/build/android/gyp/process_resources.py
@@ -101,7 +101,21 @@ ), } +class _ResourceWhitelist(object): + def __init__(self, entries=None): + self._entries = None + if entries: + self._entries = set(self._Key(x) for x in entries) + def __contains__(self, entry): + return self._entries is None or self._Key(entry) in self._entries + + @staticmethod + def _Key(entry): + # Whitelists should only care about the name of the resource rather than the + # resource ID (since the whitelist is from another compilation unit, the + # resource IDs may not match). + return (entry.java_type, entry.resource_type, entry.name) def _ParseArgs(args): @@ -130,6 +144,11 @@ '--app-as-shared-lib', action='store_true', help='Make a resource package that can be loaded as shared library.') + parser.add_option( + '--shared-resources-whitelist', + help='An R.txt file acting as a whitelist for resources that should be ' + 'non-final and have their package ID changed at runtime in R.java. If no ' + 'whitelist is provided, then everything is whitelisted.') parser.add_option('--resource-dirs', default='[]', @@ -244,7 +263,7 @@ def _CreateRJavaFiles(srcjar_dir, main_r_txt_file, packages, r_txt_files, - shared_resources, non_constant_id): + shared_resources, non_constant_id, whitelist_r_txt_file, is_apk): assert len(packages) == len(r_txt_files), 'Need one R.txt file per package' # Map of (resource_type, name) -> Entry. @@ -254,6 +273,12 @@ entry = entry._replace(value=_FixPackageIds(entry.value)) all_resources[(entry.resource_type, entry.name)] = entry + if whitelist_r_txt_file: + whitelisted_resources = _ResourceWhitelist( + _ParseTextSymbolsFile(whitelist_r_txt_file)) + else: + whitelisted_resources = _ResourceWhitelist() + # Map of package_name->resource_type->entry resources_by_package = ( collections.defaultdict(lambda: collections.defaultdict(list))) @@ -292,8 +317,8 @@ package_r_java_dir = os.path.join(srcjar_dir, *package.split('.')) build_utils.MakeDirectory(package_r_java_dir) package_r_java_path = os.path.join(package_r_java_dir, 'R.java') - java_file_contents = _CreateRJavaFile( - package, resources_by_type, shared_resources, non_constant_id) + java_file_contents = _CreateRJavaFile(package, resources_by_type, + shared_resources, non_constant_id, whitelisted_resources, is_apk) with open(package_r_java_path, 'w') as f: f.write(java_file_contents) @@ -324,8 +349,30 @@ def _CreateRJavaFile(package, resources_by_type, shared_resources, - non_constant_id): + non_constant_id, whitelisted_resources, is_apk): """Generates the contents of a R.java file.""" + final_resources_by_type = collections.defaultdict(list) + non_final_resources_by_type = collections.defaultdict(list) + if shared_resources or non_constant_id: + for res_type, resources in resources_by_type.iteritems(): + for entry in resources: + # Entries in stylable that are not int[] are not actually resource ids + # but constants. If we are creating an apk there is no reason for them + # to be non-final. However for libraries, they may be clobbered later on + # and thus should remain non-final. This is regardless of the + # whitelisting rules (since they are not actually resources). + if entry.resource_type == 'styleable' and entry.java_type != 'int[]': + if is_apk: + final_resources_by_type[res_type].append(entry) + else: + non_final_resources_by_type[res_type].append(entry) + elif entry in whitelisted_resources: + non_final_resources_by_type[res_type].append(entry) + else: + final_resources_by_type[res_type].append(entry) + else: + final_resources_by_type = resources_by_type + # Keep these assignments all on one line to make diffing against regular # aapt-generated files easier. create_id = ('{{ e.resource_type }}.{{ e.name }} ^= packageIdTransform;') @@ -343,8 +390,11 @@ private static boolean sResourcesDidLoad; {% for resource_type in resource_types %} public static final class {{ resource_type }} { - {% for e in resources[resource_type] %} - public static {{ final }}{{ e.java_type }} {{ e.name }} = {{ e.value }}; + {% for e in final_resources[resource_type] %} + public static final {{ e.java_type }} {{ e.name }} = {{ e.value }}; + {% endfor %} + {% for e in non_final_resources[resource_type] %} + public static {{ e.java_type }} {{ e.name }} = {{ e.value }}; {% endfor %} } {% endfor %} @@ -355,7 +405,7 @@ int packageIdTransform = (packageId ^ 0x7f) << 24; {% for resource_type in resource_types %} onResourcesLoaded{{ resource_type|title }}(packageIdTransform); - {% for e in resources[resource_type] %} + {% for e in non_final_resources[resource_type] %} {% if e.java_type == 'int[]' %} for(int i = 0; i < {{ e.resource_type }}.{{ e.name }}.length; ++i) { """ + create_id_arr + """ @@ -367,7 +417,7 @@ {% for res_type in resource_types %} private static void onResourcesLoaded{{ res_type|title }} ( int packageIdTransform) { - {% for e in resources[res_type] %} + {% for e in non_final_resources[res_type] %} {% if res_type != 'styleable' and e.java_type != 'int[]' %} """ + create_id + """ {% endif %} @@ -378,12 +428,11 @@ } """, trim_blocks=True, lstrip_blocks=True) - final = '' if shared_resources or non_constant_id else 'final ' return template.render(package=package, - resources=resources_by_type, resource_types=sorted(resources_by_type), shared_resources=shared_resources, - final=final) + final_resources=final_resources_by_type, + non_final_resources=non_final_resources_by_type) def _CrunchDirectory(aapt, input_dir, output_dir): @@ -733,7 +782,8 @@ if packages: shared_resources = options.shared_resources or options.app_as_shared_lib _CreateRJavaFiles(srcjar_dir, r_txt_path, packages, r_txt_files, - shared_resources, options.non_constant_id) + shared_resources, options.non_constant_id, + options.shared_resources_whitelist, bool(options.apk_path)) if options.srcjar_out: build_utils.ZipDir(options.srcjar_out, srcjar_dir) @@ -839,11 +889,13 @@ if options.apk_path: input_strings.extend(_CreatePackageApkArgs(options)) - input_paths = [ + possible_input_paths = [ options.aapt_path, options.android_manifest, options.android_sdk_jar, + options.shared_resources_whitelist, ] + input_paths = [x for x in possible_input_paths if x] input_paths.extend(options.dependencies_res_zips) input_paths.extend(options.extra_r_text_files)
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 3c88a0e..cceb26f254 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -1509,6 +1509,14 @@ args += [ "--resource-dirs=$_rebased_all_resource_dirs" ] } + if (defined(invoker.shared_resources_whitelist)) { + inputs += [ invoker.shared_resources_whitelist ] + args += [ + "--shared-resources-whitelist", + rebase_path(invoker.shared_resources_whitelist, root_build_dir), + ] + } + if (defined(invoker.version_code)) { args += [ "--version-code",
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 4fbfb56..f7f4fb7 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -1952,6 +1952,19 @@ ":$_merge_manifest_target", ":$_build_config_target", ] + if (defined(invoker.shared_resources_whitelist_target)) { + _whitelist_gen_dir = + get_label_info(invoker.shared_resources_whitelist_target, + "target_gen_dir") + _whitelist_target_name = + get_label_info(invoker.shared_resources_whitelist_target, "name") + shared_resources_whitelist = + "${_whitelist_gen_dir}/${_whitelist_target_name}" + + "__process_resources_R.txt" + deps += [ + "${invoker.shared_resources_whitelist_target}__process_resources", + ] + } } _srcjar_deps += [ ":$_process_resources_target" ]
diff --git a/cc/test/test_context_provider.cc b/cc/test/test_context_provider.cc index ac385c7..628968f 100644 --- a/cc/test/test_context_provider.cc +++ b/cc/test/test_context_provider.cc
@@ -74,6 +74,9 @@ case GL_MAX_RENDERBUFFER_SIZE: *params = 2048; break; + case GL_MAX_VERTEX_ATTRIBS: + *params = 8; + break; default: break; }
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index a8677467..207ea16f 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -1080,6 +1080,10 @@ android_manifest_dep = ":monochrome_public_android_manifest" apk_name = "MonochromePublic" + # Resource whitelist used when generating R.java files and causes + # only the webview subset of resources to be marked as non-final. + shared_resources_whitelist_target = "//android_webview:system_webview_apk" + deps = [ ":monochrome_java", "//base:base_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 90a9084..d2b60139 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1017,19 +1017,24 @@ return false; } - if (mLayoutManager != null && mLayoutManager.overviewVisible()) { + if (isInOverviewMode()) { if (reuseOrCreateNewNtp()) { - // Since reusing/creating a new NTP when using Chrome Home brings up the bottom - // sheet, we need to record it in our metrics. + // Since reusing/creating a new NTP when using Chrome Home brings up the + // bottom sheet, we need to record it in our metrics. bottomSheet.getBottomSheetMetrics().recordSheetOpenReason( StateChangeReason.STARTUP); return true; } return false; } - bottomSheet.setSheetState( - BottomSheet.SHEET_STATE_HALF, true, StateChangeReason.STARTUP); - return true; + + boolean hasTabs = getCurrentTabModel().getCount() > 0 + || mTabModelSelectorImpl.getRestoredTabCount() > 0; + if (hasTabs) { + bottomSheet.setSheetState( + BottomSheet.SHEET_STATE_HALF, true, StateChangeReason.STARTUP); + } + return false; } if (!ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_LAUNCH_AFTER_INACTIVITY)) { @@ -1056,7 +1061,7 @@ return false; } - if (mLayoutManager != null && mLayoutManager.overviewVisible() && !isTablet()) { + if (isInOverviewMode() && !isTablet()) { mLayoutManager.hideOverview(false); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java index 89a094f..cba164d0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
@@ -33,6 +33,7 @@ import org.chromium.chrome.browser.download.ui.DownloadHistoryAdapter; import org.chromium.chrome.browser.externalnav.ExternalNavigationDelegateImpl; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; +import org.chromium.chrome.browser.media.MediaViewerUtils; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.components.feature_engagement.EventConstants; import org.chromium.components.feature_engagement.Tracker; @@ -768,10 +769,9 @@ // the real file path to the user instead of a content:// download ID. Uri fileUri = contentUri; if (filePath != null) fileUri = Uri.fromFile(new File(filePath)); - return DownloadUtils.getMediaViewerIntentForDownloadItem(fileUri, contentUri, mimeType); + return MediaViewerUtils.getMediaViewerIntent(fileUri, contentUri, mimeType); } - return DownloadUtils.createViewIntentForDownloadItem( - contentUri, mimeType, originalUrl, referrer); + return MediaViewerUtils.createViewIntentForUri(contentUri, mimeType, originalUrl, referrer); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationFactory.java index affdf1f..13909a7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationFactory.java
@@ -29,6 +29,7 @@ import com.google.ipc.invalidation.util.Preconditions; import org.chromium.chrome.R; +import org.chromium.chrome.browser.media.MediaViewerUtils; import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder; import org.chromium.chrome.browser.notifications.NotificationBuilderFactory; import org.chromium.chrome.browser.notifications.NotificationConstants; @@ -197,7 +198,7 @@ downloadUpdate.getContentId().namespace); intent.putExtra(NotificationConstants.EXTRA_NOTIFICATION_ID, downloadUpdate.getNotificationId()); - DownloadUtils.setOriginalUrlAndReferralExtraToIntent(intent, + MediaViewerUtils.setOriginalUrlAndReferralExtraToIntent(intent, downloadUpdate.getOriginalUrl(), downloadUpdate.getReferrer()); } else { intent = buildActionIntent(context, ACTION_DOWNLOAD_OPEN,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java index ab34e34..1272dcc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java
@@ -48,6 +48,7 @@ import org.chromium.chrome.browser.init.BrowserParts; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.init.EmptyBrowserParts; +import org.chromium.chrome.browser.media.MediaViewerUtils; import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder; import org.chromium.chrome.browser.notifications.NotificationBuilderFactory; import org.chromium.chrome.browser.notifications.NotificationConstants; @@ -964,7 +965,8 @@ intent.putExtra(EXTRA_DOWNLOAD_CONTENTID_ID, id.id); intent.putExtra(EXTRA_DOWNLOAD_CONTENTID_NAMESPACE, id.namespace); intent.putExtra(NotificationConstants.EXTRA_NOTIFICATION_ID, notificationId); - DownloadUtils.setOriginalUrlAndReferralExtraToIntent(intent, originalUrl, referrer); + MediaViewerUtils.setOriginalUrlAndReferralExtraToIntent( + intent, originalUrl, referrer); } else { intent = buildActionIntent(mContext, ACTION_DOWNLOAD_OPEN, id, false); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java index f9d4809e..f8a80e7c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
@@ -5,21 +5,14 @@ package org.chromium.chrome.browser.download; import android.app.Activity; -import android.app.PendingIntent; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.res.ColorStateList; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Color; import android.net.Uri; -import android.os.Build; import android.os.StrictMode; -import android.provider.Browser; import android.support.annotation.IntDef; import android.support.annotation.Nullable; -import android.support.customtabs.CustomTabsIntent; import android.text.TextUtils; import org.chromium.base.ApiCompatibilityUtils; @@ -35,13 +28,12 @@ import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.UrlConstants; -import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider; -import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.browser.download.ui.BackendProvider; import org.chromium.chrome.browser.download.ui.BackendProvider.DownloadDelegate; import org.chromium.chrome.browser.download.ui.DownloadFilter; import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; +import org.chromium.chrome.browser.media.MediaViewerUtils; import org.chromium.chrome.browser.offlinepages.DownloadUiActionFlags; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.offlinepages.OfflinePageOrigin; @@ -339,43 +331,6 @@ } /** - * Creates an Intent to open the file in another app by firing an Intent to Android. - * @param fileUri Uri pointing to the file. - * @param mimeType MIME type for the file. - * @param originalUrl The original url of the downloaded file. - * @param referrer Referrer of the downloaded file. - * @return Intent that can be used to start an Activity for the file. - */ - public static Intent createViewIntentForDownloadItem(Uri fileUri, String mimeType, - String originalUrl, String referrer) { - Intent fileIntent = new Intent(Intent.ACTION_VIEW); - String normalizedMimeType = Intent.normalizeMimeType(mimeType); - if (TextUtils.isEmpty(normalizedMimeType)) { - fileIntent.setData(fileUri); - } else { - fileIntent.setDataAndType(fileUri, normalizedMimeType); - } - fileIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - fileIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - fileIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - setOriginalUrlAndReferralExtraToIntent(fileIntent, originalUrl, referrer); - return fileIntent; - } - - /** - * Adds the originating Uri and referrer extras to an intent if they are not null. - * @param intent Intent for adding extras. - * @param originalUrl The original url of the downloaded file. - * @param referrer Referrer of the downloaded file. - */ - public static void setOriginalUrlAndReferralExtraToIntent( - Intent intent, String originalUrl, String referrer) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) return; - if (originalUrl != null) intent.putExtra(Intent.EXTRA_ORIGINATING_URI, originalUrl); - if (referrer != null) intent.putExtra(Intent.EXTRA_REFERRER, referrer); - } - - /** * Creates an Intent to share {@code items} with another app by firing an Intent to Android. * * Sharing a DownloadItem shares the file itself, while sharing an OfflinePageItem shares the @@ -480,86 +435,6 @@ return shareIntent; } - private static Intent createShareIntent(Uri fileUri, String mimeType) { - if (TextUtils.isEmpty(mimeType)) mimeType = DEFAULT_MIME_TYPE; - - Intent intent = new Intent(Intent.ACTION_SEND); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - intent.putExtra(Intent.EXTRA_STREAM, fileUri); - intent.setType(mimeType); - return intent; - } - - /** - * Creates an Intent that allows viewing the given file in an internal media viewer. - * @param fileUri URI pointing at the file, ideally in file:// form. Used only when - * the media viewer is trying to locate the file on disk. - * @param contentUri content:// URI pointing at the file. - * @param mimeType MIME type of the file. - * @return Intent that can be fired to open the file. - */ - public static Intent getMediaViewerIntentForDownloadItem( - Uri fileUri, Uri contentUri, String mimeType) { - Context context = ContextUtils.getApplicationContext(); - Intent viewIntent = createViewIntentForDownloadItem(contentUri, mimeType, null, null); - - Bitmap closeIcon = BitmapFactory.decodeResource( - context.getResources(), R.drawable.ic_arrow_back_white_24dp); - Bitmap shareIcon = BitmapFactory.decodeResource( - context.getResources(), R.drawable.ic_share_white_24dp); - - CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); - builder.setToolbarColor(Color.BLACK); - builder.setCloseButtonIcon(closeIcon); - builder.setShowTitle(true); - - // Create a PendingIntent that can be used to view the file externally. - // TODO(dfalcantara): Check if this is problematic in multi-window mode, where two - // different viewers could be visible at the same time. - Intent chooserIntent = Intent.createChooser(viewIntent, null); - chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - String openWithStr = context.getString(R.string.download_manager_open_with); - PendingIntent pendingViewIntent = PendingIntent.getActivity( - context, 0, chooserIntent, PendingIntent.FLAG_CANCEL_CURRENT); - builder.addMenuItem(openWithStr, pendingViewIntent); - - // Create a PendingIntent that shares the file with external apps. - PendingIntent pendingShareIntent = PendingIntent.getActivity( - context, 0, createShareIntent(contentUri, mimeType), - PendingIntent.FLAG_CANCEL_CURRENT); - builder.setActionButton( - shareIcon, context.getString(R.string.share), pendingShareIntent, true); - - // The color of the media viewer is dependent on the file type. - int backgroundRes; - if (DownloadFilter.fromMimeType(mimeType) == DownloadFilter.FILTER_IMAGE) { - backgroundRes = R.color.image_viewer_bg; - } else { - backgroundRes = R.color.media_viewer_bg; - } - int mediaColor = ApiCompatibilityUtils.getColor(context.getResources(), backgroundRes); - - // Build up the Intent further. - Intent intent = builder.build().intent; - intent.setPackage(context.getPackageName()); - intent.setData(contentUri); - intent.putExtra(CustomTabIntentDataProvider.EXTRA_UI_TYPE, - CustomTabIntentDataProvider.CUSTOM_TABS_UI_TYPE_MEDIA_VIEWER); - intent.putExtra(CustomTabIntentDataProvider.EXTRA_MEDIA_VIEWER_URL, fileUri.toString()); - intent.putExtra(CustomTabIntentDataProvider.EXTRA_ENABLE_EMBEDDED_MEDIA_EXPERIENCE, true); - intent.putExtra( - CustomTabIntentDataProvider.EXTRA_INITIAL_BACKGROUND_COLOR, mediaColor); - intent.putExtra( - CustomTabsIntent.EXTRA_TOOLBAR_COLOR, mediaColor); - intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()); - IntentHandler.addTrustedIntentExtras(intent); - - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.setClass(context, ChromeLauncherActivity.class); - return intent; - } - /** * Returns a URI that points at the file. * @param file File to get a URI for. @@ -605,7 +480,7 @@ String normalizedMimeType = Intent.normalizeMimeType(mimeType); Intent intent = - getMediaViewerIntentForDownloadItem(fileUri, contentUri, normalizedMimeType); + MediaViewerUtils.getMediaViewerIntent(fileUri, contentUri, normalizedMimeType); IntentHandler.startActivityForTrustedIntent(intent); service.updateLastAccessTime(downloadGuid, isOffTheRecord); return true; @@ -617,8 +492,8 @@ StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); Uri uri = ApiCompatibilityUtils.getUriForDownloadedFile(file); StrictMode.setThreadPolicy(oldPolicy); - Intent viewIntent = createViewIntentForDownloadItem( - uri, mimeType, originalUrl, referrer); + Intent viewIntent = + MediaViewerUtils.createViewIntentForUri(uri, mimeType, originalUrl, referrer); context.startActivity(viewIntent); service.updateLastAccessTime(downloadGuid, isOffTheRecord); return true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java new file mode 100644 index 0000000..6752208e --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java
@@ -0,0 +1,156 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.media; + +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.net.Uri; +import android.os.Build; +import android.provider.Browser; +import android.support.customtabs.CustomTabsIntent; +import android.text.TextUtils; + +import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.ContextUtils; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.IntentHandler; +import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider; +import org.chromium.chrome.browser.document.ChromeLauncherActivity; + +import java.util.Locale; + +/** + * A class containing some utility static methods. + */ +public class MediaViewerUtils { + private static final String DEFAULT_MIME_TYPE = "*/*"; + private static final String MIMETYPE_IMAGE = "image"; + + /** + * Creates an Intent that allows viewing the given file in an internal media viewer. + * @param displayUri URI to display to the user, ideally in file:// form. + * @param contentUri content:// URI pointing at the file. + * @param mimeType MIME type of the file. + * @return Intent that can be fired to open the file. + */ + public static Intent getMediaViewerIntent(Uri displayUri, Uri contentUri, String mimeType) { + Context context = ContextUtils.getApplicationContext(); + Intent viewIntent = createViewIntentForUri(contentUri, mimeType, null, null); + + Bitmap closeIcon = BitmapFactory.decodeResource( + context.getResources(), R.drawable.ic_arrow_back_white_24dp); + Bitmap shareIcon = BitmapFactory.decodeResource( + context.getResources(), R.drawable.ic_share_white_24dp); + + CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); + builder.setToolbarColor(Color.BLACK); + builder.setCloseButtonIcon(closeIcon); + builder.setShowTitle(true); + + // Create a PendingIntent that can be used to view the file externally. + // TODO(https://crbug.com/795968): Check if this is problematic in multi-window mode, + // where two different viewers could be visible at the + // same time. + Intent chooserIntent = Intent.createChooser(viewIntent, null); + chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + String openWithStr = context.getString(R.string.download_manager_open_with); + PendingIntent pendingViewIntent = PendingIntent.getActivity( + context, 0, chooserIntent, PendingIntent.FLAG_CANCEL_CURRENT); + builder.addMenuItem(openWithStr, pendingViewIntent); + + // Create a PendingIntent that shares the file with external apps. + PendingIntent pendingShareIntent = PendingIntent.getActivity(context, 0, + createShareIntent(contentUri, mimeType), PendingIntent.FLAG_CANCEL_CURRENT); + builder.setActionButton( + shareIcon, context.getString(R.string.share), pendingShareIntent, true); + + // The color of the media viewer is dependent on the file type. + int backgroundRes; + if (isImageType(mimeType)) { + backgroundRes = R.color.image_viewer_bg; + } else { + backgroundRes = R.color.media_viewer_bg; + } + int mediaColor = ApiCompatibilityUtils.getColor(context.getResources(), backgroundRes); + + // Build up the Intent further. + Intent intent = builder.build().intent; + intent.setPackage(context.getPackageName()); + intent.setData(contentUri); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_UI_TYPE, + CustomTabIntentDataProvider.CUSTOM_TABS_UI_TYPE_MEDIA_VIEWER); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_MEDIA_VIEWER_URL, displayUri.toString()); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_ENABLE_EMBEDDED_MEDIA_EXPERIENCE, true); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_INITIAL_BACKGROUND_COLOR, mediaColor); + intent.putExtra(CustomTabsIntent.EXTRA_TOOLBAR_COLOR, mediaColor); + intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()); + IntentHandler.addTrustedIntentExtras(intent); + + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setClass(context, ChromeLauncherActivity.class); + return intent; + } + + /** + * Creates an Intent to open the file in another app by firing an Intent to Android. + * @param fileUri Uri pointing to the file. + * @param mimeType MIME type for the file. + * @param originalUrl The original url of the downloaded file. + * @param referrer Referrer of the downloaded file. + * @return Intent that can be used to start an Activity for the file. + */ + public static Intent createViewIntentForUri( + Uri fileUri, String mimeType, String originalUrl, String referrer) { + Intent fileIntent = new Intent(Intent.ACTION_VIEW); + String normalizedMimeType = Intent.normalizeMimeType(mimeType); + if (TextUtils.isEmpty(normalizedMimeType)) { + fileIntent.setData(fileUri); + } else { + fileIntent.setDataAndType(fileUri, normalizedMimeType); + } + fileIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + fileIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + fileIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + setOriginalUrlAndReferralExtraToIntent(fileIntent, originalUrl, referrer); + return fileIntent; + } + + /** + * Adds the originating Uri and referrer extras to an intent if they are not null. + * @param intent Intent for adding extras. + * @param originalUrl The original url of the downloaded file. + * @param referrer Referrer of the downloaded file. + */ + public static void setOriginalUrlAndReferralExtraToIntent( + Intent intent, String originalUrl, String referrer) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) return; + if (originalUrl != null) intent.putExtra(Intent.EXTRA_ORIGINATING_URI, originalUrl); + if (referrer != null) intent.putExtra(Intent.EXTRA_REFERRER, referrer); + } + + private static Intent createShareIntent(Uri fileUri, String mimeType) { + if (TextUtils.isEmpty(mimeType)) mimeType = DEFAULT_MIME_TYPE; + + Intent intent = new Intent(Intent.ACTION_SEND); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.putExtra(Intent.EXTRA_STREAM, fileUri); + intent.setType(mimeType); + return intent; + } + + private static boolean isImageType(String mimeType) { + if (TextUtils.isEmpty(mimeType)) return false; + + String[] pieces = mimeType.toLowerCase(Locale.getDefault()).split("/"); + if (pieces.length != 2) return false; + + return MIMETYPE_IMAGE.equals(pieces[0]); + } +}
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 4891e18..3f129b7 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -570,6 +570,7 @@ "java/src/org/chromium/chrome/browser/locale/SogouPromoDialog.java", "java/src/org/chromium/chrome/browser/locale/SpecialLocaleHandler.java", "java/src/org/chromium/chrome/browser/media/MediaCaptureNotificationService.java", + "java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java", "java/src/org/chromium/chrome/browser/media/PictureInPictureController.java", "java/src/org/chromium/chrome/browser/media/cdm/MediaDrmCredentialManager.java", "java/src/org/chromium/chrome/browser/media/remote/AbstractMediaRouteController.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/VideoFullscreenOrientationLockChromeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/VideoFullscreenOrientationLockChromeTest.java index cf4f727a..6ddd1e9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/VideoFullscreenOrientationLockChromeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/VideoFullscreenOrientationLockChromeTest.java
@@ -21,7 +21,7 @@ import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.base.test.util.UrlUtils; -import org.chromium.chrome.browser.download.DownloadUtils; +import org.chromium.chrome.browser.media.MediaViewerUtils; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; @@ -132,8 +132,7 @@ // Orientation lock should be disabled when download viewer activity is started. Uri fileUri = Uri.parse(UrlUtils.getIsolatedTestFileUrl(VIDEO_URL)); String mimeType = "video/mp4"; - Intent intent = - DownloadUtils.getMediaViewerIntentForDownloadItem(fileUri, fileUri, mimeType); + Intent intent = MediaViewerUtils.getMediaViewerIntent(fileUri, fileUri, mimeType); IntentHandler.startActivityForTrustedIntent(intent); waitUntilUnlocked();
diff --git a/chrome/browser/autofill/risk_util.cc b/chrome/browser/autofill/risk_util.cc index 71dd999..3fee1881 100644 --- a/chrome/browser/autofill/risk_util.cc +++ b/chrome/browser/autofill/risk_util.cc
@@ -66,9 +66,11 @@ } // namespace -void LoadRiskData(uint64_t obfuscated_gaia_id, - content::WebContents* web_contents, - const base::Callback<void(const std::string&)>& callback) { +void LoadRiskData( + uint64_t obfuscated_gaia_id, + content::WebContents* web_contents, + const base::RepeatingCallback<void(const std::string&)>& callback, + service_manager::Connector* connector) { // No easy way to get window bounds on Android, and that signal isn't very // useful anyway (given that we're also including the bounds of the web // contents). @@ -88,8 +90,10 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK(content::ServiceManagerConnection::GetForProcess()); - service_manager::Connector* connector = - content::ServiceManagerConnection::GetForProcess()->GetConnector(); + if (!connector) { + connector = + content::ServiceManagerConnection::GetForProcess()->GetConnector(); + } risk::GetFingerprint( obfuscated_gaia_id, window_bounds, web_contents,
diff --git a/chrome/browser/autofill/risk_util.h b/chrome/browser/autofill/risk_util.h index 35eb869..7788e57 100644 --- a/chrome/browser/autofill/risk_util.h +++ b/chrome/browser/autofill/risk_util.h
@@ -15,11 +15,24 @@ class WebContents; } +namespace service_manager { +class Connector; +} + namespace autofill { -void LoadRiskData(uint64_t obfuscated_gaia_id, - content::WebContents* web_contents, - const base::Callback<void(const std::string&)>& callback); +// Loads risk data for the client, getting the device's risk fingerprint before +// calling |callback|. |obfuscated_gaia_id| is used in the fingerprinting +// process if provided. |web_contents| is used during fingerprinting as well, +// when retrieving user prefs, and in determining window bounds when not on +// Android. |connector| is an optional parameter that, if set, is used instead +// of content::ServiceManagerConnection::GetForProcess()->GetConnector() (for +// testing purposes). +void LoadRiskData( + uint64_t obfuscated_gaia_id, + content::WebContents* web_contents, + const base::RepeatingCallback<void(const std::string&)>& callback, + service_manager::Connector* connector = nullptr); } // namespace autofill
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc index 13de1a2..6a5b083 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -934,14 +934,19 @@ NOTREACHED(); } - void RemoveBrowsingData( - int data_type_mask, - base::Callback<bool(const GURL&)> origin_filter) override { + void RemoveBrowsingData(int data_type_mask, + const base::RepeatingCallback<bool(const GURL&)>& + origin_filter) override { ++remove_calls_; last_data_type_mask_ = data_type_mask; last_origin_filter_ = origin_filter; } + bool RequestIsUpload(const net::URLRequest& request) override { + NOTREACHED(); + return true; + } + int remove_calls() const { return remove_calls_; } int last_data_type_mask() const { return last_data_type_mask_; } base::Callback<bool(const GURL&)> last_origin_filter() const {
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc index 13c260a..53c4783 100644 --- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc +++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
@@ -790,7 +790,6 @@ } gfx::ImageSkia user_wallpaper; - *GetCachedWallpaperInfo() = info; if (GetWallpaperFromCache(account_id, &user_wallpaper)) { GetPendingWallpaper()->SetWallpaperFromImage(account_id, user_wallpaper, info);
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_policy_browsertest.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_policy_browsertest.cc index de49627..48b8ecf 100644 --- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_policy_browsertest.cc +++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_policy_browsertest.cc
@@ -489,8 +489,10 @@ // Log in a test user and set the user wallpaper policy. The user policy // controlled wallpaper shows up in the user session. LoginUser(testUsers_[0]); - InjectPolicy(0, kGreenImageFileName); RunUntilWallpaperChangeCount(3); + + InjectPolicy(0, kGreenImageFileName); + RunUntilWallpaperChangeCount(4); EXPECT_EQ(kGreenImageColor, GetAverageWallpaperColor()); // Set the device wallpaper policy inside the user session. That that the
diff --git a/chrome/browser/chromeos/system/timezone_util.cc b/chrome/browser/chromeos/system/timezone_util.cc index e6df712..660d7f5 100644 --- a/chrome/browser/chromeos/system/timezone_util.cc +++ b/chrome/browser/chromeos/system/timezone_util.cc
@@ -347,8 +347,8 @@ } bool FineGrainedTimeZoneDetectionEnabled() { - return !base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableFineGrainedTimeZoneDetection); + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableFineGrainedTimeZoneDetection); } } // namespace system
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc index 5033f0b..22968fc 100644 --- a/chrome/browser/media/encrypted_media_browsertest.cc +++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -377,19 +377,6 @@ command_line); } }; - -#if defined(WIDEVINE_CDM_AVAILABLE) -// Tests encrypted media playback using Widevine key system. -class WVEncryptedMediaTest : public EncryptedMediaTestBase { - protected: - void SetUpCommandLine(base::CommandLine* command_line) override { - EncryptedMediaTestBase::SetUpCommandLine(command_line); - SetUpCommandLineForKeySystem(kWidevineKeySystem, CdmHostType::kPepper, - command_line); - } -}; - -#endif // defined(WIDEVINE_CDM_AVAILABLE) #endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) // Tests encrypted media playback with a combination of parameters: @@ -727,15 +714,6 @@ #endif // BUILDFLAG(USE_PROPRIETARY_CODECS) #if BUILDFLAG(ENABLE_LIBRARY_CDMS) -#if defined(WIDEVINE_CDM_AVAILABLE) -// The parent key system cannot be used when creating MediaKeys. -IN_PROC_BROWSER_TEST_F(WVEncryptedMediaTest, ParentThrowsException) { - RunEncryptedMediaTest(kDefaultEmePlayer, "bear-a_enc-a.webm", - kWebMVorbisAudioOnly, "com.widevine", SrcType::MSE, - kNoSessionToLoad, false, PlayCount::ONCE, - kEmeNotSupportedError); -} -#endif // defined(WIDEVINE_CDM_AVAILABLE) INSTANTIATE_TEST_CASE_P(Pepper, ECKEncryptedMediaTest,
diff --git a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc index fb3e342..d922316e 100644 --- a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc +++ b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
@@ -749,6 +749,35 @@ IsSupportedByKeySystem(kWidevine, kAudioMP4MimeType, audio_mp4_codecs())); } +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesWidevineTest, + InvalidKeySystems) { + // Case sensitive. + EXPECT_UNSUPPORTED(IsSupportedByKeySystem( + "com.widevine.WideVine", kVideoWebMMimeType, video_webm_codecs())); + + // TLDs are not allowed. + EXPECT_UNSUPPORTED( + IsSupportedByKeySystem("com.", kVideoWebMMimeType, video_webm_codecs())); + EXPECT_UNSUPPORTED( + IsSupportedByKeySystem("com", kVideoWebMMimeType, video_webm_codecs())); + EXPECT_UNSUPPORTED(IsSupportedByKeySystem("com.widevine.", kVideoWebMMimeType, + video_webm_codecs())); + EXPECT_UNSUPPORTED(IsSupportedByKeySystem("com.widevine", kVideoWebMMimeType, + video_webm_codecs())); + + // Incomplete. + EXPECT_UNSUPPORTED(IsSupportedByKeySystem( + "com.widevine.alp", kVideoWebMMimeType, video_webm_codecs())); + + // Extra character. + EXPECT_UNSUPPORTED(IsSupportedByKeySystem( + "com.widevine.alphab", kVideoWebMMimeType, video_webm_codecs())); + + // There are no child key systems for Widevine. + EXPECT_UNSUPPORTED(IsSupportedByKeySystem( + "com.widevine.alpha.child", kVideoWebMMimeType, video_webm_codecs())); +} + IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesWidevineTest, NoCodecs) { EXPECT_UNSUPPORTED( IsSupportedByKeySystem(kWidevine, kVideoWebMMimeType, no_codecs()));
diff --git a/chrome/browser/metrics/ukm_browsertest.cc b/chrome/browser/metrics/ukm_browsertest.cc index f11b406..3340b5a 100644 --- a/chrome/browser/metrics/ukm_browsertest.cc +++ b/chrome/browser/metrics/ukm_browsertest.cc
@@ -157,7 +157,7 @@ }; // Make sure that UKM is disabled while an incognito window is open. -IN_PROC_BROWSER_TEST_F(UkmBrowserTest, IncognitoCheck) { +IN_PROC_BROWSER_TEST_F(UkmBrowserTest, RegularPlusIncognitoCheck) { // Enable metrics recording and update MetricsServicesManager. bool metrics_enabled = true; ChromeMetricsServiceAccessor::SetMetricsAndCrashReportingForTesting( @@ -197,6 +197,33 @@ ChromeMetricsServiceAccessor::SetMetricsAndCrashReportingForTesting(nullptr); } +// Make sure opening a real window after Incognito doesn't enable UKM. +IN_PROC_BROWSER_TEST_F(UkmBrowserTest, IncognitoPlusRegularCheck) { + // Enable metrics recording and update MetricsServicesManager. + bool metrics_enabled = true; + ChromeMetricsServiceAccessor::SetMetricsAndCrashReportingForTesting( + &metrics_enabled); + g_browser_process->GetMetricsServicesManager()->UpdateUploadPermissions( + false); + + Profile* profile = ProfileManager::GetActiveUserProfile(); + std::unique_ptr<ProfileSyncServiceHarness> harness = + EnableSyncForProfile(profile); + + Browser* incognito_browser = CreateIncognitoBrowser(); + EXPECT_FALSE(ukm_enabled()); + + Browser* sync_browser = CreateBrowser(profile); + EXPECT_FALSE(ukm_enabled()); + + CloseBrowserSynchronously(incognito_browser); + EXPECT_TRUE(ukm_enabled()); + + harness->service()->RequestStop(browser_sync::ProfileSyncService::CLEAR_DATA); + CloseBrowserSynchronously(sync_browser); + ChromeMetricsServiceAccessor::SetMetricsAndCrashReportingForTesting(nullptr); +} + // Make sure that UKM is disabled while an non-sync profile's window is open. IN_PROC_BROWSER_TEST_F(UkmBrowserTest, NonSyncCheck) { // Enable metrics recording and update MetricsServicesManager. @@ -262,6 +289,32 @@ ChromeMetricsServiceAccessor::SetMetricsAndCrashReportingForTesting(nullptr); } +// Make sure that providing consent doesn't enable UKM when sync is disabled. +IN_PROC_BROWSER_TEST_F(UkmBrowserTest, ConsentAddedButNoSyncCheck) { + // Enable metrics recording and update MetricsServicesManager. + bool metrics_enabled = false; + ChromeMetricsServiceAccessor::SetMetricsAndCrashReportingForTesting( + &metrics_enabled); + g_browser_process->GetMetricsServicesManager()->UpdateUploadPermissions(true); + + Profile* profile = ProfileManager::GetActiveUserProfile(); + Browser* browser = CreateBrowser(profile); + EXPECT_FALSE(ukm_enabled()); + + metrics_enabled = true; + g_browser_process->GetMetricsServicesManager()->UpdateUploadPermissions(true); + EXPECT_FALSE(ukm_enabled()); + + std::unique_ptr<ProfileSyncServiceHarness> harness = + EnableSyncForProfile(profile); + g_browser_process->GetMetricsServicesManager()->UpdateUploadPermissions(true); + EXPECT_TRUE(ukm_enabled()); + + harness->service()->RequestStop(browser_sync::ProfileSyncService::CLEAR_DATA); + CloseBrowserSynchronously(browser); + ChromeMetricsServiceAccessor::SetMetricsAndCrashReportingForTesting(nullptr); +} + // Make sure that UKM is disabled when an open sync window disables it. IN_PROC_BROWSER_TEST_F(UkmBrowserTest, DisableSyncCheck) { // Enable metrics recording and update MetricsServicesManager.
diff --git a/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc b/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc index b903860..c270efed 100644 --- a/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc +++ b/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc
@@ -18,6 +18,9 @@ WebFeature::kVibrateWithoutUserGesture, WebFeature::kTouchEventPreventedNoTouchAction, WebFeature::kTouchEventPreventedForcedDocumentPassiveNoTouchAction, + // kDataUriHasOctothorpe may not be recorded correctly for iframes. + // See https://crbug.com/796173 for details. + WebFeature::kDataUriHasOctothorpe, })); return opt_in_features.count(feature); }
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc index f4de288..7a3c03a 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -74,6 +74,8 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_filter.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/web_feature.mojom.h" #include "url/gurl.h" @@ -338,6 +340,8 @@ using WebFeature = blink::mojom::WebFeature; } // namespace +using testing::UnorderedElementsAre; + class PageLoadMetricsBrowserTest : public InProcessBrowserTest { public: PageLoadMetricsBrowserTest() { @@ -1213,6 +1217,9 @@ static_cast<int32_t>(WebFeature::kNavigatorVibrate), 1); histogram_tester_.ExpectBucketCount( internal::kFeaturesHistogramName, + static_cast<int32_t>(WebFeature::kDataUriHasOctothorpe), 1); + histogram_tester_.ExpectBucketCount( + internal::kFeaturesHistogramName, static_cast<int32_t>(WebFeature::kPageVisits), 1); } @@ -1231,11 +1238,19 @@ const auto& entries = test_ukm_recorder_->GetEntriesByName(internal::kUkmUseCounterEventName); - EXPECT_EQ(1u, entries.size()); - test_ukm_recorder_->ExpectEntrySourceHasUrl(entries[0], url); - test_ukm_recorder_->ExpectEntryMetric( - entries[0], internal::kUkmUseCounterFeature, - static_cast<int64_t>(WebFeature::kNavigatorVibrate)); + EXPECT_EQ(2u, entries.size()); + std::vector<int64_t> ukm_features; + for (const auto* entry : entries) { + test_ukm_recorder_->ExpectEntrySourceHasUrl(entry, url); + const auto* metric = + test_ukm_recorder_->FindMetric(entry, internal::kUkmUseCounterFeature); + EXPECT_TRUE(metric); + ukm_features.push_back(metric->value); + } + EXPECT_THAT(ukm_features, + UnorderedElementsAre( + static_cast<int64_t>(WebFeature::kNavigatorVibrate), + static_cast<int64_t>(WebFeature::kDataUriHasOctothorpe))); } // Test UseCounter Features observed in a child frame are recorded, exactly
diff --git a/chrome/browser/policy/policy_network_browsertest.cc b/chrome/browser/policy/policy_network_browsertest.cc index 701502b..c3b5e773 100644 --- a/chrome/browser/policy/policy_network_browsertest.cc +++ b/chrome/browser/policy/policy_network_browsertest.cc
@@ -8,7 +8,9 @@ #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "base/run_loop.h" +#include "base/strings/string_number_conversions.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/policy/profile_policy_connector_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" @@ -17,15 +19,23 @@ #include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" +#include "components/grpc_support/test/quic_test_server.h" #include "components/network_session_configurator/common/network_switches.h" #include "components/policy/core/browser/browser_policy_connector.h" #include "components/policy/core/common/mock_configuration_policy_provider.h" #include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_types.h" #include "components/policy/policy_constants.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/common/content_features.h" #include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "net/cert/test_root_certs.h" +#include "net/dns/mock_host_resolver.h" #include "net/http/http_transaction_factory.h" +#include "net/test/test_data_directory.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" @@ -65,6 +75,21 @@ return is_quic_enabled; } +bool IsQuicEnabled(content::mojom::NetworkContext* network_context) { + GURL url = + GURL(std::string("https://") + grpc_support::kTestServerHost + ":" + + base::NumberToString(grpc_support::GetQuicTestServerPort()) + + grpc_support::kHelloPath); + int rv = content::LoadBasicRequest(network_context, url); + return rv == net::OK; +} + +bool IsQuicEnabled(Profile* profile) { + return IsQuicEnabled( + content::BrowserContext::GetDefaultStoragePartition(profile) + ->GetNetworkContext()); +} + // Short-hand access to global SafeBrowsingService's URLRequestContextGetter for // better readability. scoped_refptr<net::URLRequestContextGetter> @@ -78,6 +103,15 @@ return g_browser_process->system_request_context(); } +bool IsQuicEnabledForSystem() { + if (base::FeatureList::IsEnabled(features::kNetworkService)) { + return IsQuicEnabled( + g_browser_process->system_network_context_manager()->GetContext()); + } + + return IsQuicEnabled(system_request_context()); +} + // Called when an additional profile has been created. // The created profile is stored in *|out_created_profile|. void OnProfileInitialized(Profile** out_created_profile, @@ -94,12 +128,27 @@ namespace policy { +class QuicTestBase : public InProcessBrowserTest { + public: + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitchASCII(switches::kOriginToForceQuicOn, "*"); + } + + void SetUpOnMainThread() override { + net::TestRootCerts* root_certs = net::TestRootCerts::GetInstance(); + root_certs->AddFromFile( + net::GetTestCertsDirectory().AppendASCII("quic-root.pem")); + grpc_support::StartQuicTestServer(); + host_resolver()->AddRule("*", "127.0.0.1"); + } +}; + // The tests are based on the assumption that command line flag kEnableQuic // guarantees that QUIC protocol is enabled which is the case at the moment // when these are being written. -class QuicAllowedPolicyTestBase: public InProcessBrowserTest { +class QuicAllowedPolicyTestBase : public QuicTestBase { public: - QuicAllowedPolicyTestBase() : InProcessBrowserTest() {} + QuicAllowedPolicyTestBase() : QuicTestBase() {} protected: void SetUpInProcessBrowserTestFixture() override { @@ -137,9 +186,9 @@ }; IN_PROC_BROWSER_TEST_F(QuicAllowedPolicyIsFalse, QuicDisallowed) { - EXPECT_FALSE(IsQuicEnabled(system_request_context())); + EXPECT_FALSE(IsQuicEnabledForSystem()); EXPECT_FALSE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_FALSE(IsQuicEnabled(browser()->profile()->GetRequestContext())); + EXPECT_FALSE(IsQuicEnabled(browser()->profile())); } // Policy QuicAllowed set to true. @@ -159,9 +208,9 @@ }; IN_PROC_BROWSER_TEST_F(QuicAllowedPolicyIsTrue, QuicAllowed) { - EXPECT_TRUE(IsQuicEnabled(system_request_context())); + EXPECT_TRUE(IsQuicEnabledForSystem()); EXPECT_TRUE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_TRUE(IsQuicEnabled(browser()->profile()->GetRequestContext())); + EXPECT_TRUE(IsQuicEnabled(browser()->profile())); } // Policy QuicAllowed is not set. @@ -178,17 +227,16 @@ }; IN_PROC_BROWSER_TEST_F(QuicAllowedPolicyIsNotSet, NoQuicRegulations) { - EXPECT_TRUE(IsQuicEnabled(system_request_context())); + EXPECT_TRUE(IsQuicEnabledForSystem()); EXPECT_TRUE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_TRUE(IsQuicEnabled(browser()->profile()->GetRequestContext())); + EXPECT_TRUE(IsQuicEnabled(browser()->profile())); } // Policy QuicAllowed is set dynamically after profile creation. // Supports creation of an additional profile. -class QuicAllowedPolicyDynamicTest : public InProcessBrowserTest { +class QuicAllowedPolicyDynamicTest : public QuicTestBase { public: - QuicAllowedPolicyDynamicTest() - : InProcessBrowserTest(), profile_1_(nullptr), profile_2_(nullptr) {} + QuicAllowedPolicyDynamicTest() : profile_1_(nullptr), profile_2_(nullptr) {} protected: void SetUpCommandLine(base::CommandLine* command_line) override { @@ -198,6 +246,7 @@ #endif // Ensure that QUIC is enabled by default on browser startup. command_line->AppendSwitch(switches::kEnableQuic); + QuicTestBase::SetUpCommandLine(command_line); } void SetUpInProcessBrowserTestFixture() override { @@ -208,7 +257,10 @@ ->PushProviderForTesting(&policy_for_profile_1_); } - void SetUpOnMainThread() override { profile_1_ = browser()->profile(); } + void SetUpOnMainThread() override { + profile_1_ = browser()->profile(); + QuicTestBase::SetUpOnMainThread(); + } // Creates a second Profile for testing. The Profile can then be accessed by // profile_2() and its policy by policy_for_profile_2(). @@ -302,31 +354,31 @@ IN_PROC_BROWSER_TEST_F(QuicAllowedPolicyDynamicTest, QuicAllowedFalseThenTrue) { // After browser start, QuicAllowed=false comes in dynamically SetQuicAllowedPolicy(policy_for_profile_1(), false); - EXPECT_FALSE(IsQuicEnabled(system_request_context())); + EXPECT_FALSE(IsQuicEnabledForSystem()); EXPECT_FALSE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_FALSE(IsQuicEnabled(profile_1()->GetRequestContext())); + EXPECT_FALSE(IsQuicEnabled(profile_1())); // Set the QuicAllowed policy to true again SetQuicAllowedPolicy(policy_for_profile_1(), true); // Effectively, QUIC is still disabled because QUIC re-enabling is not // supported. - EXPECT_FALSE(IsQuicEnabled(system_request_context())); + EXPECT_FALSE(IsQuicEnabledForSystem()); EXPECT_FALSE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_FALSE(IsQuicEnabled(profile_1()->GetRequestContext())); + EXPECT_FALSE(IsQuicEnabled(profile_1())); // Completely remove the QuicAllowed policy RemoveAllPolicies(policy_for_profile_1()); // Effectively, QUIC is still disabled because QUIC re-enabling is not // supported. - EXPECT_FALSE(IsQuicEnabled(system_request_context())); + EXPECT_FALSE(IsQuicEnabledForSystem()); EXPECT_FALSE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_FALSE(IsQuicEnabled(profile_1()->GetRequestContext())); + EXPECT_FALSE(IsQuicEnabled(profile_1())); // QuicAllowed=false is set again SetQuicAllowedPolicy(policy_for_profile_1(), false); - EXPECT_FALSE(IsQuicEnabled(system_request_context())); + EXPECT_FALSE(IsQuicEnabledForSystem()); EXPECT_FALSE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_FALSE(IsQuicEnabled(profile_1()->GetRequestContext())); + EXPECT_FALSE(IsQuicEnabled(profile_1())); } // QUIC is allowed, then disallowed by policy after the profile has been @@ -334,29 +386,27 @@ IN_PROC_BROWSER_TEST_F(QuicAllowedPolicyDynamicTest, QuicAllowedTrueThenFalse) { // After browser start, QuicAllowed=true comes in dynamically SetQuicAllowedPolicy(policy_for_profile_1(), true); - EXPECT_TRUE(IsQuicEnabled(system_request_context())); + EXPECT_TRUE(IsQuicEnabledForSystem()); EXPECT_TRUE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_TRUE(IsQuicEnabled(profile_1()->GetRequestContext())); + EXPECT_TRUE(IsQuicEnabled(profile_1())); // Completely remove the QuicAllowed policy RemoveAllPolicies(policy_for_profile_1()); - EXPECT_TRUE(IsQuicEnabled(system_request_context())); + EXPECT_TRUE(IsQuicEnabledForSystem()); EXPECT_TRUE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_TRUE(IsQuicEnabled(profile_1()->GetRequestContext())); + EXPECT_TRUE(IsQuicEnabled(profile_1())); // Set the QuicAllowed policy to true again SetQuicAllowedPolicy(policy_for_profile_1(), true); - // Effectively, QUIC is still disabled because QUIC re-enabling is not - // supported. - EXPECT_TRUE(IsQuicEnabled(system_request_context())); + EXPECT_TRUE(IsQuicEnabledForSystem()); EXPECT_TRUE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_TRUE(IsQuicEnabled(profile_1()->GetRequestContext())); + EXPECT_TRUE(IsQuicEnabled(profile_1())); // Now set QuicAllowed=false SetQuicAllowedPolicy(policy_for_profile_1(), false); - EXPECT_FALSE(IsQuicEnabled(system_request_context())); + EXPECT_FALSE(IsQuicEnabledForSystem()); EXPECT_FALSE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_FALSE(IsQuicEnabled(profile_1()->GetRequestContext())); + EXPECT_FALSE(IsQuicEnabled(profile_1())); } // A second Profile is created when QuicAllowed=false policy is in effect for @@ -368,17 +418,17 @@ return; SetQuicAllowedPolicy(policy_for_profile_1(), false); - EXPECT_FALSE(IsQuicEnabled(system_request_context())); + EXPECT_FALSE(IsQuicEnabledForSystem()); EXPECT_FALSE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_FALSE(IsQuicEnabled(profile_1()->GetRequestContext())); + EXPECT_FALSE(IsQuicEnabled(profile_1())); CreateSecondProfile(); // QUIC is disabled in both profiles - EXPECT_FALSE(IsQuicEnabled(system_request_context())); + EXPECT_FALSE(IsQuicEnabledForSystem()); EXPECT_FALSE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_FALSE(IsQuicEnabled(profile_1()->GetRequestContext())); - EXPECT_FALSE(IsQuicEnabled(profile_2()->GetRequestContext())); + EXPECT_FALSE(IsQuicEnabled(profile_1())); + EXPECT_FALSE(IsQuicEnabled(profile_2())); } // A second Profile is created when no QuicAllowed policy is in effect for the @@ -393,24 +443,24 @@ CreateSecondProfile(); // QUIC is enabled in both profiles - EXPECT_TRUE(IsQuicEnabled(system_request_context())); + EXPECT_TRUE(IsQuicEnabledForSystem()); EXPECT_TRUE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_TRUE(IsQuicEnabled(profile_1()->GetRequestContext())); - EXPECT_TRUE(IsQuicEnabled(profile_2()->GetRequestContext())); + EXPECT_TRUE(IsQuicEnabled(profile_1())); + EXPECT_TRUE(IsQuicEnabled(profile_2())); // Disable QUIC in first profile SetQuicAllowedPolicy(policy_for_profile_1(), false); - EXPECT_FALSE(IsQuicEnabled(system_request_context())); + EXPECT_FALSE(IsQuicEnabledForSystem()); EXPECT_FALSE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_FALSE(IsQuicEnabled(profile_1()->GetRequestContext())); - EXPECT_FALSE(IsQuicEnabled(profile_2()->GetRequestContext())); + EXPECT_FALSE(IsQuicEnabled(profile_1())); + EXPECT_FALSE(IsQuicEnabled(profile_2())); // Disable QUIC in second profile SetQuicAllowedPolicy(policy_for_profile_2(), false); - EXPECT_FALSE(IsQuicEnabled(system_request_context())); + EXPECT_FALSE(IsQuicEnabledForSystem()); EXPECT_FALSE(IsQuicEnabled(safe_browsing_service_request_context())); - EXPECT_FALSE(IsQuicEnabled(profile_1()->GetRequestContext())); - EXPECT_FALSE(IsQuicEnabled(profile_2()->GetRequestContext())); + EXPECT_FALSE(IsQuicEnabled(profile_1())); + EXPECT_FALSE(IsQuicEnabled(profile_2())); } } // namespace policy
diff --git a/chrome/browser/signin/chrome_signin_helper.cc b/chrome/browser/signin/chrome_signin_helper.cc index 478643c..575a9e8 100644 --- a/chrome/browser/signin/chrome_signin_helper.cc +++ b/chrome/browser/signin/chrome_signin_helper.cc
@@ -119,7 +119,8 @@ if (!IsDicePrepareMigrationEnabled()) return; - if (ShouldBlockReconcilorForRequest(request)) { + if (ShouldBlockReconcilorForRequest(request) && + !request->GetUserData(kDiceURLRequestUserDataKey)) { const content::ResourceRequestInfo* info = content::ResourceRequestInfo::ForRequest(request); request->SetUserData(kDiceURLRequestUserDataKey,
diff --git a/chrome/browser/signin/dice_browsertest.cc b/chrome/browser/signin/dice_browsertest.cc index e7bb129..e6f4175 100644 --- a/chrome/browser/signin/dice_browsertest.cc +++ b/chrome/browser/signin/dice_browsertest.cc
@@ -5,6 +5,7 @@ #include <map> #include <memory> #include <string> +#include <utility> #include "base/base_switches.h" #include "base/bind.h" @@ -28,6 +29,10 @@ #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/profile_chooser_constants.h" +#include "chrome/browser/ui/webui/signin/login_ui_service.h" +#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" +#include "chrome/common/webui_url_constants.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/signin/core/browser/account_reconcilor.h" @@ -38,9 +43,11 @@ #include "components/signin/core/browser/scoped_account_consistency.h" #include "components/signin/core/browser/signin_header_helper.h" #include "components/signin/core/browser/signin_manager.h" +#include "components/signin/core/browser/signin_metrics.h" #include "components/sync/base/sync_prefs.h" #include "components/variations/variations_switches.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/notification_service.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" @@ -75,6 +82,8 @@ const char kAuthorizationCode[] = "authorization_code"; const char kDiceResponseHeader[] = "X-Chrome-ID-Consistency-Response"; +const char kChromeSyncEndpointURL[] = "/signin/chrome/sync"; +const char kEnableSyncURL[] = "/enable_sync"; const char kGoogleSignoutResponseHeader[] = "Google-Accounts-SignOut"; const char kMainEmail[] = "main_email@example.com"; const char kMainGaiaID[] = "main_gaia_id"; @@ -86,6 +95,35 @@ const char kSigninURL[] = "/signin"; const char kSignoutURL[] = "/signout"; +// Test response that does not complete synchronously. It must be unblocked by +// calling the completion closure. +class BlockedHttpResponse : public net::test_server::BasicHttpResponse { + public: + explicit BlockedHttpResponse( + base::OnceCallback<void(base::OnceClosure)> callback) + : callback_(std::move(callback)) {} + + void SendResponse( + const net::test_server::SendBytesCallback& send, + const net::test_server::SendCompleteCallback& done) override { + // Called on the IO thread to unblock the response. + base::OnceClosure unblock_io_thread = + base::BindOnce(send, ToResponseString(), done); + // Unblock the response from any thread by posting a task to the IO thread. + base::OnceClosure unblock_any_thread = + base::BindOnce(base::IgnoreResult(&base::TaskRunner::PostTask), + base::ThreadTaskRunnerHandle::Get(), FROM_HERE, + std::move(unblock_io_thread)); + // Pass |unblock_any_thread| to the caller on the UI thread. + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::BindOnce(std::move(callback_), std::move(unblock_any_thread))); + } + + private: + base::OnceCallback<void(base::OnceClosure)> callback_; +}; + } // namespace namespace FakeGaia { @@ -93,26 +131,55 @@ // Handler for the signin page on the embedded test server. // The response has the content of the Dice request header in its body, and has // the Dice response header. +// Handles both the "Chrome Sync" endpoint and the old endpoint. std::unique_ptr<HttpResponse> HandleSigninURL( - const base::Callback<void(const std::string&)>& callback, + const base::RepeatingCallback<void(const std::string&)>& callback, const HttpRequest& request) { - if (!net::test_server::ShouldHandle(request, kSigninURL)) + if (!net::test_server::ShouldHandle(request, kSigninURL) && + !net::test_server::ShouldHandle(request, kChromeSyncEndpointURL)) return nullptr; + // Extract Dice request header. std::string header_value = kNoDiceRequestHeader; auto it = request.headers.find(signin::kDiceRequestHeader); if (it != request.headers.end()) header_value = it->second; content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, - base::Bind(callback, header_value)); + base::BindRepeating(callback, header_value)); + // Add the SIGNIN dice header. std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); http_response->AddCustomHeader( kDiceResponseHeader, base::StringPrintf( "action=SIGNIN,authuser=1,id=%s,email=%s,authorization_code=%s", kMainGaiaID, kMainEmail, kAuthorizationCode)); + + // When hitting the Chrome Sync endpoint, redirect to kEnableSyncURL, which + // adds the ENABLE_SYNC dice header. + if (net::test_server::ShouldHandle(request, kChromeSyncEndpointURL)) { + http_response->set_code(net::HTTP_FOUND); // 302 redirect. + http_response->AddCustomHeader("location", kEnableSyncURL); + } + + http_response->AddCustomHeader("Cache-Control", "no-store"); + return std::move(http_response); +} + +// Handler for the Gaia endpoint adding the ENABLE_SYNC dice header. +std::unique_ptr<HttpResponse> HandleEnableSyncURL( + const base::RepeatingCallback<void(base::OnceClosure)>& callback, + const HttpRequest& request) { + if (!net::test_server::ShouldHandle(request, kEnableSyncURL)) + return nullptr; + + std::unique_ptr<BlockedHttpResponse> http_response = + std::make_unique<BlockedHttpResponse>(callback); + http_response->AddCustomHeader( + kDiceResponseHeader, + base::StringPrintf("action=ENABLE_SYNC,authuser=1,id=%s,email=%s", + kMainGaiaID, kMainEmail)); http_response->AddCustomHeader("Cache-Control", "no-store"); return std::move(http_response); } @@ -156,7 +223,7 @@ // Checks that the request is well formatted and returns a refresh token in a // JSON dictionary. std::unique_ptr<HttpResponse> HandleOAuth2TokenExchangeURL( - const base::Closure& callback, + const base::RepeatingCallback<void(base::OnceClosure)>& callback, const HttpRequest& request) { if (!net::test_server::ShouldHandle(request, kOAuth2TokenExchangeURL)) return nullptr; @@ -167,10 +234,9 @@ if (request.content.find(kAuthorizationCode) == std::string::npos) return nullptr; - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, - callback); + std::unique_ptr<BlockedHttpResponse> http_response = + std::make_unique<BlockedHttpResponse>(callback); - std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); std::string content = "{" " \"access_token\":\"access_token\"," @@ -186,7 +252,7 @@ // Handler for OAuth2 token revocation. std::unique_ptr<HttpResponse> HandleOAuth2TokenRevokeURL( - const base::Closure& callback, + const base::RepeatingClosure& callback, const HttpRequest& request) { if (!net::test_server::ShouldHandle(request, kOAuth2TokenRevokeURL)) return nullptr; @@ -203,7 +269,7 @@ // Calls the callback with the dice request header, or kNoDiceRequestHeader if // there is no Dice header. std::unique_ptr<HttpResponse> HandleServiceLoginURL( - const base::Callback<void(const std::string&)>& callback, + const base::RepeatingCallback<void(const std::string&)>& callback, const HttpRequest& request) { if (!net::test_server::ShouldHandle(request, "/ServiceLogin")) return nullptr; @@ -212,8 +278,9 @@ auto it = request.headers.find(signin::kDiceRequestHeader); if (it != request.headers.end()) dice_request_header = it->second; - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, - base::Bind(callback, dice_request_header)); + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::BindRepeating(callback, dice_request_header)); std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); http_response->AddCustomHeader("Cache-Control", "no-store"); @@ -224,7 +291,8 @@ class DiceBrowserTestBase : public InProcessBrowserTest, public OAuth2TokenService::Observer, - public AccountReconcilor::Observer { + public AccountReconcilor::Observer, + public SigninManagerBase::Observer { protected: ~DiceBrowserTestBase() override {} @@ -232,6 +300,7 @@ AccountConsistencyMethod account_consistency_method) : scoped_account_consistency_(account_consistency_method), https_server_(net::EmbeddedTestServer::TYPE_HTTPS), + enable_sync_requested_(false), token_requested_(false), refresh_token_available_(false), token_revoked_notification_count_(0), @@ -239,24 +308,28 @@ reconcilor_blocked_count_(0), reconcilor_unblocked_count_(0), reconcilor_started_count_(0) { + https_server_.RegisterDefaultHandler(base::BindRepeating( + &FakeGaia::HandleSigninURL, + base::BindRepeating(&DiceBrowserTestBase::OnSigninRequest, + base::Unretained(this)))); + https_server_.RegisterDefaultHandler(base::BindRepeating( + &FakeGaia::HandleEnableSyncURL, + base::BindRepeating(&DiceBrowserTestBase::OnEnableSyncRequest, + base::Unretained(this)))); https_server_.RegisterDefaultHandler( - base::Bind(&FakeGaia::HandleSigninURL, - base::Bind(&DiceBrowserTestBase::OnSigninRequest, - base::Unretained(this)))); - https_server_.RegisterDefaultHandler( - base::Bind(&FakeGaia::HandleSignoutURL)); - https_server_.RegisterDefaultHandler( - base::Bind(&FakeGaia::HandleOAuth2TokenExchangeURL, - base::Bind(&DiceBrowserTestBase::OnTokenExchangeRequest, - base::Unretained(this)))); - https_server_.RegisterDefaultHandler( - base::Bind(&FakeGaia::HandleOAuth2TokenRevokeURL, - base::Bind(&DiceBrowserTestBase::OnTokenRevocationRequest, - base::Unretained(this)))); - https_server_.RegisterDefaultHandler( - base::Bind(&FakeGaia::HandleServiceLoginURL, - base::Bind(&DiceBrowserTestBase::OnServiceLoginRequest, - base::Unretained(this)))); + base::BindRepeating(&FakeGaia::HandleSignoutURL)); + https_server_.RegisterDefaultHandler(base::BindRepeating( + &FakeGaia::HandleOAuth2TokenExchangeURL, + base::BindRepeating(&DiceBrowserTestBase::OnTokenExchangeRequest, + base::Unretained(this)))); + https_server_.RegisterDefaultHandler(base::BindRepeating( + &FakeGaia::HandleOAuth2TokenRevokeURL, + base::BindRepeating(&DiceBrowserTestBase::OnTokenRevocationRequest, + base::Unretained(this)))); + https_server_.RegisterDefaultHandler(base::BindRepeating( + &FakeGaia::HandleServiceLoginURL, + base::BindRepeating(&DiceBrowserTestBase::OnServiceLoginRequest, + base::Unretained(this)))); signin::SetDiceAccountReconcilorBlockDelayForTesting( kAccountReconcilorDelayMs); @@ -346,6 +419,7 @@ InProcessBrowserTest::SetUpOnMainThread(); https_server_.StartAcceptingConnections(); + GetSigninManager()->AddObserver(this); GetTokenService()->AddObserver(this); // Wait for the token service to be ready. if (!GetTokenService()->AreAllCredentialsLoaded()) @@ -363,6 +437,7 @@ } void TearDownOnMainThread() override { + GetSigninManager()->RemoveObserver(this); GetTokenService()->RemoveObserver(this); AccountReconcilorFactory::GetForProfile(browser()->profile()) ->RemoveObserver(this); @@ -372,7 +447,7 @@ void OnRefreshTokenAvailable(const std::string& account_id) override { if (account_id == GetMainAccountID()) { refresh_token_available_ = true; - RunClosureIfValid(&refresh_token_available_quit_closure_); + RunClosureIfValid(std::move(refresh_token_available_quit_closure_)); } } @@ -381,20 +456,17 @@ } void OnRefreshTokensLoaded() override { - RunClosureIfValid(&tokens_loaded_quit_closure_); + RunClosureIfValid(std::move(tokens_loaded_quit_closure_)); } // Calls |closure| if it is not null and resets it after. - void RunClosureIfValid(base::Closure* closure) { - DCHECK(closure); - if (!closure->is_null()) { - closure->Run(); - closure->Reset(); - } + void RunClosureIfValid(base::OnceClosure closure) { + if (closure) + std::move(closure).Run(); } // Creates and runs a RunLoop until |closure| is called. - void WaitForClosure(base::Closure* closure) { + void WaitForClosure(base::OnceClosure* closure) { base::RunLoop run_loop; *closure = run_loop.QuitClosure(); run_loop.Run(); @@ -408,30 +480,45 @@ void OnServiceLoginRequest(const std::string& dice_request_header) { dice_request_header_ = dice_request_header; - RunClosureIfValid(&service_login_quit_closure_); + RunClosureIfValid(std::move(service_login_quit_closure_)); } - void OnTokenExchangeRequest() { + void OnEnableSyncRequest(base::OnceClosure unblock_response_closure) { + EXPECT_EQ(signin::IsDicePrepareMigrationEnabled(), IsReconcilorBlocked()); + enable_sync_requested_ = true; + RunClosureIfValid(std::move(enable_sync_requested_quit_closure_)); + unblock_enable_sync_response_closure_ = std::move(unblock_response_closure); + } + + void OnTokenExchangeRequest(base::OnceClosure unblock_response_closure) { // The token must be exchanged only once. EXPECT_FALSE(token_requested_); EXPECT_EQ(signin::IsDicePrepareMigrationEnabled(), IsReconcilorBlocked()); token_requested_ = true; - RunClosureIfValid(&token_requested_quit_closure_); + RunClosureIfValid(std::move(token_requested_quit_closure_)); + unblock_token_exchange_response_closure_ = + std::move(unblock_response_closure); } void OnTokenRevocationRequest() { ++token_revoked_count_; - RunClosureIfValid(&token_revoked_quit_closure_); + RunClosureIfValid(std::move(token_revoked_quit_closure_)); } // AccountReconcilor::Observer: void OnBlockReconcile() override { ++reconcilor_blocked_count_; } void OnUnblockReconcile() override { ++reconcilor_unblocked_count_; - RunClosureIfValid(&unblock_count_quit_closure_); + RunClosureIfValid(std::move(unblock_count_quit_closure_)); } void OnStartReconcile() override { ++reconcilor_started_count_; } + // SigninManagerBase::Observer + void GoogleSigninSucceeded(const std::string& account_id, + const std::string& username) override { + RunClosureIfValid(std::move(google_signin_succeeded_quit_closure_)); + } + // Returns true if the account reconcilor is currently blocked. bool IsReconcilorBlocked() { EXPECT_GE(reconcilor_blocked_count_, reconcilor_unblocked_count_); @@ -450,13 +537,34 @@ EXPECT_EQ(count, reconcilor_unblocked_count_); } - // Waits until the token request is sent to the server and the response is - // received. - void WaitForTokenReceived() { + // Waits until the user is authenticated. + void WaitForSigninSucceeded() { + if (GetSigninManager()->GetAuthenticatedAccountId().empty()) + WaitForClosure(&google_signin_succeeded_quit_closure_); + } + + // Waits for the ENABLE_SYNC request to hit the server, and unblocks the + // response. If this is not called, ENABLE_SYNC will not be sent by the + // server. + // Note: this does not wait for the response to reach Chrome. + void SendEnableSyncResponse() { + if (!enable_sync_requested_) + WaitForClosure(&enable_sync_requested_quit_closure_); + DCHECK(unblock_enable_sync_response_closure_); + std::move(unblock_enable_sync_response_closure_).Run(); + } + + // Waits until the token request is sent to the server, the response is + // received and the refresh token is available. If this is not called, the + // refresh token will not be sent by the server. + void SendRefreshTokenResponse() { // Wait for the request hitting the server. if (!token_requested_) WaitForClosure(&token_requested_quit_closure_); EXPECT_TRUE(token_requested_); + // Unblock the server response. + DCHECK(unblock_token_exchange_response_closure_); + std::move(unblock_token_exchange_response_closure_).Run(); // Wait for the response coming back. if (!refresh_token_available_) WaitForClosure(&refresh_token_available_quit_closure_); @@ -473,6 +581,7 @@ base::test::ScopedFeatureList scoped_site_isolation_; signin::ScopedAccountConsistency scoped_account_consistency_; net::EmbeddedTestServer https_server_; + bool enable_sync_requested_; bool token_requested_; bool refresh_token_available_; int token_revoked_notification_count_; @@ -482,13 +591,19 @@ int reconcilor_started_count_; std::string dice_request_header_; + // Unblocks the server responses. + base::OnceClosure unblock_token_exchange_response_closure_; + base::OnceClosure unblock_enable_sync_response_closure_; + // Used for waiting asynchronous events. - base::Closure token_requested_quit_closure_; - base::Closure token_revoked_quit_closure_; - base::Closure refresh_token_available_quit_closure_; - base::Closure service_login_quit_closure_; - base::Closure unblock_count_quit_closure_; - base::Closure tokens_loaded_quit_closure_; + base::OnceClosure enable_sync_requested_quit_closure_; + base::OnceClosure token_requested_quit_closure_; + base::OnceClosure token_revoked_quit_closure_; + base::OnceClosure refresh_token_available_quit_closure_; + base::OnceClosure service_login_quit_closure_; + base::OnceClosure unblock_count_quit_closure_; + base::OnceClosure tokens_loaded_quit_closure_; + base::OnceClosure google_signin_succeeded_quit_closure_; DISALLOW_COPY_AND_ASSIGN(DiceBrowserTestBase); }; @@ -510,6 +625,15 @@ : DiceBrowserTestBase(AccountConsistencyMethod::kDicePrepareMigration) {} }; +class DicePrepareMigrationChromeSynEndpointBrowserTest + : public DiceBrowserTestBase { + public: + DicePrepareMigrationChromeSynEndpointBrowserTest() + : DiceBrowserTestBase( + AccountConsistencyMethod::kDicePrepareMigrationChromeSyncEndpoint) { + } +}; + // Checks that signin on Gaia triggers the fetch for a refresh token. IN_PROC_BROWSER_TEST_F(DiceBrowserTest, Signin) { EXPECT_EQ(0, reconcilor_started_count_); @@ -526,10 +650,11 @@ dice_request_header_); // Check that the token was requested and added to the token service. - WaitForTokenReceived(); + SendRefreshTokenResponse(); EXPECT_TRUE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); // Sync should not be enabled. EXPECT_TRUE(GetSigninManager()->GetAuthenticatedAccountId().empty()); + EXPECT_TRUE(GetSigninManager()->GetAccountIdForAuthInProgress().empty()); EXPECT_EQ(1, reconcilor_blocked_count_); WaitForReconcilorUnblockedCount(1); @@ -556,7 +681,7 @@ dice_request_header_); // Check that the token was requested and added to the token service. - WaitForTokenReceived(); + SendRefreshTokenResponse(); EXPECT_EQ(GetMainAccountID(), GetSigninManager()->GetAuthenticatedAccountId()); // Old token must be revoked silently. @@ -578,6 +703,7 @@ // Check that the user is signed out and all tokens are deleted. EXPECT_TRUE(GetSigninManager()->GetAuthenticatedAccountId().empty()); + EXPECT_TRUE(GetSigninManager()->GetAccountIdForAuthInProgress().empty()); EXPECT_FALSE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); EXPECT_FALSE( GetTokenService()->RefreshTokenIsAvailable(GetSecondaryAccountID())); @@ -619,6 +745,7 @@ // Check that the user is signed out and all tokens are deleted. EXPECT_TRUE(GetSigninManager()->GetAuthenticatedAccountId().empty()); + EXPECT_TRUE(GetSigninManager()->GetAccountIdForAuthInProgress().empty()); EXPECT_FALSE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); EXPECT_FALSE( GetTokenService()->RefreshTokenIsAvailable(GetSecondaryAccountID())); @@ -734,7 +861,7 @@ dice_request_header_); // Check that the token was requested and added to the token service. - WaitForTokenReceived(); + SendRefreshTokenResponse(); EXPECT_EQ(GetMainAccountID(), GetSigninManager()->GetAuthenticatedAccountId()); // Old token must be revoked silently. @@ -780,10 +907,11 @@ dice_request_header_); // Check that the token was requested and added to the token service. - WaitForTokenReceived(); + SendRefreshTokenResponse(); EXPECT_TRUE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); // Sync should not be enabled. EXPECT_TRUE(GetSigninManager()->GetAuthenticatedAccountId().empty()); + EXPECT_TRUE(GetSigninManager()->GetAccountIdForAuthInProgress().empty()); EXPECT_EQ(1, reconcilor_blocked_count_); WaitForReconcilorUnblockedCount(1); @@ -809,3 +937,97 @@ EXPECT_EQ(1, reconcilor_blocked_count_); WaitForReconcilorUnblockedCount(1); } + +// Tests that Sync is enabled if the ENABLE_SYNC response is received after the +// refresh token. +IN_PROC_BROWSER_TEST_F(DicePrepareMigrationChromeSynEndpointBrowserTest, + EnableSyncAfterToken) { + EXPECT_EQ(0, reconcilor_started_count_); + + // Signin using the Chrome Sync endpoint. + browser()->signin_view_controller()->ShowSignin( + profiles::BUBBLE_VIEW_MODE_GAIA_SIGNIN, browser(), + signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS); + + // Receive token. + EXPECT_FALSE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); + SendRefreshTokenResponse(); + EXPECT_TRUE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); + + // Receive ENABLE_SYNC. + SendEnableSyncResponse(); + + // Check that the Dice request header was sent, with no signout confirmation. + std::string client_id = GaiaUrls::GetInstance()->oauth2_chrome_client_id(); + EXPECT_EQ( + base::StringPrintf("version=%s,client_id=%s,signin_mode=all_accounts," + "signout_mode=no_confirmation", + signin::kDiceProtocolVersion, client_id.c_str()), + dice_request_header_); + + WaitForSigninSucceeded(); + EXPECT_EQ(GetMainAccountID(), + GetSigninManager()->GetAuthenticatedAccountId()); + + EXPECT_EQ(1, reconcilor_blocked_count_); + WaitForReconcilorUnblockedCount(1); + EXPECT_EQ(1, reconcilor_started_count_); + + // Check that the tab was navigated to the NTP. + ui_test_utils::UrlLoadObserver ntp_url_observer( + GURL(chrome::kChromeUINewTabURL), + content::NotificationService::AllSources()); + + // Dismiss the OneClickSigninSyncStarter. + LoginUIServiceFactory::GetForProfile(browser()->profile()) + ->SyncConfirmationUIClosed(LoginUIService::SYNC_WITH_DEFAULT_SETTINGS); +} + +// Tests that Sync is enabled if the ENABLE_SYNC response is received before the +// refresh token. +IN_PROC_BROWSER_TEST_F(DicePrepareMigrationChromeSynEndpointBrowserTest, + EnableSyncBeforeToken) { + EXPECT_EQ(0, reconcilor_started_count_); + + // Signin using the Chrome Sync endpoint. + browser()->signin_view_controller()->ShowSignin( + profiles::BUBBLE_VIEW_MODE_GAIA_SIGNIN, browser(), + signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS); + + // Receive ENABLE_SYNC. + SendEnableSyncResponse(); + // Wait for the page to be fully loaded. + ui_test_utils::UrlLoadObserver enable_sync_url_observer( + https_server_.GetURL(kEnableSyncURL), + content::NotificationService::AllSources()); + + // Receive token. + EXPECT_FALSE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); + SendRefreshTokenResponse(); + EXPECT_TRUE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); + + // Check that the Dice request header was sent, with no signout confirmation. + std::string client_id = GaiaUrls::GetInstance()->oauth2_chrome_client_id(); + EXPECT_EQ( + base::StringPrintf("version=%s,client_id=%s,signin_mode=all_accounts," + "signout_mode=no_confirmation", + signin::kDiceProtocolVersion, client_id.c_str()), + dice_request_header_); + + WaitForSigninSucceeded(); + EXPECT_EQ(GetMainAccountID(), + GetSigninManager()->GetAuthenticatedAccountId()); + + EXPECT_EQ(1, reconcilor_blocked_count_); + WaitForReconcilorUnblockedCount(1); + EXPECT_EQ(1, reconcilor_started_count_); + + // Check that the tab was navigated to the NTP. + ui_test_utils::UrlLoadObserver ntp_url_observer( + GURL(chrome::kChromeUINewTabURL), + content::NotificationService::AllSources()); + + // Dismiss the OneClickSigninSyncStarter. + LoginUIServiceFactory::GetForProfile(browser()->profile()) + ->SyncConfirmationUIClosed(LoginUIService::SYNC_WITH_DEFAULT_SETTINGS); +}
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc index 181801a2..08a8a63 100644 --- a/chrome/browser/ssl/ssl_browsertest.cc +++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -2123,10 +2123,18 @@ AuthState::DISPLAYED_FORM_WITH_INSECURE_ACTION); } +// TODO(crbug.com/795820): Fails in Windows official builds. +#if defined(OFFICIAL_BUILD) && defined(OS_WIN) +#define MAYBE_TestBrokenHTTPSReportingCloseTab \ + DISABLED_TestBrokenHTTPSReportingCloseTab +#else +#define MAYBE_TestBrokenHTTPSReportingCloseTab TestBrokenHTTPSReportingCloseTab +#endif + // Test that a report is sent if the user closes the tab on an interstitial // before making a decision to proceed or go back. IN_PROC_BROWSER_TEST_P(SSLUITestWithExtendedReporting, - TestBrokenHTTPSReportingCloseTab) { + MAYBE_TestBrokenHTTPSReportingCloseTab) { ASSERT_TRUE(https_server_expired_.Start()); base::RunLoop run_loop;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index b6c9ad4a..3abb816 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1600,6 +1600,8 @@ "sync/one_click_signin_sync_observer.h", "sync/one_click_signin_sync_starter.cc", "sync/one_click_signin_sync_starter.h", + "views/close_bubble_on_tab_activation_helper.cc", + "views/close_bubble_on_tab_activation_helper.h", "views/external_protocol_dialog.cc", "views/external_protocol_dialog.h", "views/profiles/avatar_button_style.h",
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index 51f8523..cf1bef3 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -11,7 +11,6 @@ #include "base/feature_list.h" #include "base/logging.h" #include "base/memory/ptr_util.h" -#include "build/build_config.h" #include "chrome/browser/autofill/address_normalizer_factory.h" #include "chrome/browser/autofill/personal_data_manager_factory.h" #include "chrome/browser/autofill/risk_util.h" @@ -253,7 +252,7 @@ void ChromeAutofillClient::LoadRiskData( const base::Callback<void(const std::string&)>& callback) { - ::autofill::LoadRiskData(0, web_contents(), callback); + ::autofill::LoadRiskData(0, web_contents(), callback, connector_); } bool ChromeAutofillClient::HasCreditCardScanFeature() {
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h index 21e7894..d552bcc 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.h +++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -14,12 +14,14 @@ #include "base/i18n/rtl.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "build/build_config.h" #include "components/autofill/core/browser/autofill_client.h" #include "components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" #if !defined(OS_ANDROID) +#include "components/autofill/core/browser/ui/save_card_bubble_controller.h" #include "components/zoom/zoom_observer.h" #endif // !defined(OS_ANDROID) @@ -27,6 +29,10 @@ class WebContents; } +namespace service_manager { +class Connector; +} + namespace autofill { class AutofillPopupControllerImpl; @@ -109,9 +115,11 @@ #endif // !defined(OS_ANDROID) private: - explicit ChromeAutofillClient(content::WebContents* web_contents); + friend class SaveCardBubbleViewsBrowserTestBase; friend class content::WebContentsUserData<ChromeAutofillClient>; + explicit ChromeAutofillClient(content::WebContents* web_contents); + void ShowHttpNotSecureExplanation(); base::WeakPtr<AutofillPopupControllerImpl> popup_controller_; @@ -120,6 +128,13 @@ // The identity provider, used for Payments integration. std::unique_ptr<IdentityProvider> identity_provider_; + // An optional connector to expose test services. For example, if set, this + // connector is used when loading risk data. The test class that sets this + // pointer is responsible for the ownership of its object. + // TODO(crbug.com/791155): Necessary for testing due to leaks in the + // geolocation setup code when running browsertests. + service_manager::Connector* connector_ = nullptr; + DISALLOW_COPY_AND_ASSIGN(ChromeAutofillClient); };
diff --git a/chrome/browser/ui/views/autofill/dialog_view_ids.h b/chrome/browser/ui/views/autofill/dialog_view_ids.h new file mode 100644 index 0000000..96f4aa1 --- /dev/null +++ b/chrome/browser/ui/views/autofill/dialog_view_ids.h
@@ -0,0 +1,37 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_DIALOG_VIEW_IDS_H_ +#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_DIALOG_VIEW_IDS_H_ + +#include "components/autofill/core/browser/field_types.h" + +// This defines an enumeration of IDs that can uniquely identify a view within +// the scope of the local and upload credit card save bubbles. + +namespace autofill { + +enum DialogViewId : int { + VIEW_ID_NONE = 0, + + // The following are the important containing views of the bubble. + MAIN_CONTENT_VIEW_LOCAL, // The main content view, for a local save bubble + MAIN_CONTENT_VIEW_UPLOAD, // The main content view, for an upload save bubble + REQUEST_CVC_VIEW, // Secondary main content view for the CVC fix flow + FOOTNOTE_VIEW, // Contains the legal messages for upload save + + // The following are views::LabelButton objects (clickable). + OK_BUTTON, // Can say [Save], [Next], and [Confirm] depend on context + CANCEL_BUTTON, // Typically says [No thanks] + + // The following are views::Link objects (clickable). + LEARN_MORE_LINK, + + // The following are views::Textfield objects. + CVC_TEXTFIELD, // Used for CVC entry +}; + +} // namespace autofill + +#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_DIALOG_VIEW_IDS_H_
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc index 45afff9..e6ecb86 100644 --- a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
@@ -11,6 +11,7 @@ #include "build/build_config.h" #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/views/autofill/dialog_view_ids.h" #include "chrome/browser/ui/views/autofill/view_util.h" #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "components/autofill/core/browser/autofill_experiments.h" @@ -33,6 +34,7 @@ #include "ui/views/controls/styled_label.h" #include "ui/views/controls/textfield/textfield.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/window/dialog_client_view.h" namespace autofill { @@ -68,6 +70,7 @@ void SaveCardBubbleViews::Show(DisplayReason reason) { ShowForReason(reason); + AssignIdsToDialogClientView(); } void SaveCardBubbleViews::Hide() { @@ -84,6 +87,7 @@ learn_more_link_ = new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); learn_more_link_->SetUnderline(false); learn_more_link_->set_listener(this); + learn_more_link_->set_id(DialogViewId::LEARN_MORE_LINK); return learn_more_link_; } @@ -95,6 +99,7 @@ footnote_view_ = new View(); footnote_view_->SetLayoutManager( std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + footnote_view_->set_id(DialogViewId::FOOTNOTE_VIEW); // Add a StyledLabel for each line of the legal message. for (const LegalMessageLine& line : controller_->GetLegalMessageLines()) { @@ -269,6 +274,10 @@ DialogModelChanged(); } +views::View* SaveCardBubbleViews::GetFootnoteViewForTesting() { + return footnote_view_; +} + SaveCardBubbleViews::~SaveCardBubbleViews() {} SaveCardBubbleViews::CurrentFlowStep SaveCardBubbleViews::GetCurrentFlowStep() @@ -293,26 +302,29 @@ view->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); + view->set_id(GetCurrentFlowStep() == LOCAL_SAVE_ONLY_STEP + ? DialogViewId::MAIN_CONTENT_VIEW_LOCAL + : DialogViewId::MAIN_CONTENT_VIEW_UPLOAD); // If applicable, add the upload explanation label. Appears above the card // info. base::string16 explanation = controller_->GetExplanatoryMessage(); if (!explanation.empty()) { - views::Label* explanation_label = new views::Label(explanation); + auto* explanation_label = new views::Label(explanation); explanation_label->SetMultiLine(true); explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); view->AddChildView(explanation_label); } // Add the card type icon, last four digits and expiration date. - views::View* description_view = new views::View(); + auto* description_view = new views::View(); description_view->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::kHorizontal, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL))); view->AddChildView(description_view); const CreditCard& card = controller_->GetCard(); - views::ImageView* card_type_icon = new views::ImageView(); + auto* card_type_icon = new views::ImageView(); card_type_icon->SetImage( ui::ResourceBundle::GetSharedInstance() .GetImageNamed(CreditCard::IconResourceId(card.network())) @@ -339,16 +351,17 @@ provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); request_cvc_view->SetBackground(views::CreateThemedSolidBackground( request_cvc_view.get(), ui::NativeTheme::kColorId_BubbleBackground)); + request_cvc_view->set_id(DialogViewId::REQUEST_CVC_VIEW); const CreditCard& card = controller_->GetCard(); - views::Label* explanation_label = new views::Label(l10n_util::GetStringFUTF16( + auto* explanation_label = new views::Label(l10n_util::GetStringFUTF16( IDS_AUTOFILL_SAVE_CARD_PROMPT_ENTER_CVC_EXPLANATION, card.NetworkAndLastFourDigits())); explanation_label->SetMultiLine(true); explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); request_cvc_view->AddChildView(explanation_label); - views::View* cvc_entry_view = new views::View(); + auto* cvc_entry_view = new views::View(); auto layout = std::make_unique<views::BoxLayout>( views::BoxLayout::kHorizontal, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL)); @@ -359,9 +372,10 @@ DCHECK(!cvc_textfield_); cvc_textfield_ = CreateCvcTextfield(); cvc_textfield_->set_controller(this); + cvc_textfield_->set_id(DialogViewId::CVC_TEXTFIELD); cvc_entry_view->AddChildView(cvc_textfield_); - views::ImageView* cvc_image = new views::ImageView(); + auto* cvc_image = new views::ImageView(); ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); cvc_image->SetImage( rb.GetImageSkiaNamed(controller_->GetCvcImageResourceId())); @@ -371,6 +385,15 @@ return request_cvc_view; } +void SaveCardBubbleViews::AssignIdsToDialogClientView() { + auto* ok_button = GetDialogClientView()->ok_button(); + if (ok_button) + ok_button->set_id(DialogViewId::OK_BUTTON); + auto* cancel_button = GetDialogClientView()->cancel_button(); + if (cancel_button) + cancel_button->set_id(DialogViewId::CANCEL_BUTTON); +} + void SaveCardBubbleViews::Init() { SetLayoutManager( std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical));
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views.h b/chrome/browser/ui/views/autofill/save_card_bubble_views.h index 9b0b920..e245a22 100644 --- a/chrome/browser/ui/views/autofill/save_card_bubble_views.h +++ b/chrome/browser/ui/views/autofill/save_card_bubble_views.h
@@ -77,6 +77,10 @@ void ContentsChanged(views::Textfield* sender, const base::string16& new_contents) override; + // Returns the footnote view, so it can be searched for clickable views. + // Exists for testing (specifically, browsertests). + views::View* GetFootnoteViewForTesting(); + private: // The current step of the save card flow. Accounts for: // 1) Local save vs. Upload save @@ -98,6 +102,9 @@ // Create the dialog's content view asking for the user's CVC. std::unique_ptr<views::View> CreateRequestCvcView(); + // Attributes IDs to the DialogClientView and its buttons. + void AssignIdsToDialogClientView(); + // views::BubbleDialogDelegateView: void Init() override;
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest.cc new file mode 100644 index 0000000..aa2eac6 --- /dev/null +++ b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest.cc
@@ -0,0 +1,663 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <string> + +#include "base/strings/utf_string_conversions.h" +#include "base/test/histogram_tester.h" +#include "chrome/browser/ui/autofill/save_card_bubble_controller_impl.h" +#include "chrome/browser/ui/views/autofill/save_card_bubble_views.h" +#include "chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" +#include "net/url_request/test_url_fetcher_factory.h" +#include "ui/views/controls/button/label_button.h" +#include "ui/views/controls/styled_label.h" +#include "ui/views/controls/textfield/textfield.h" +#include "ui/views/window/dialog_client_view.h" + +using base::Bucket; +using testing::ElementsAre; + +namespace autofill { + +class SaveCardBubbleViewsFullFormBrowserTest + : public SaveCardBubbleViewsBrowserTestBase { + protected: + SaveCardBubbleViewsFullFormBrowserTest() + : SaveCardBubbleViewsBrowserTestBase( + "/credit_card_upload_form_address_and_cc.html") {} + + private: + DISALLOW_COPY_AND_ASSIGN(SaveCardBubbleViewsFullFormBrowserTest); +}; + +class SaveCardBubbleViewsFullFormWithShippingBrowserTest + : public SaveCardBubbleViewsBrowserTestBase { + protected: + SaveCardBubbleViewsFullFormWithShippingBrowserTest() + : SaveCardBubbleViewsBrowserTestBase( + "/credit_card_upload_form_shipping_address.html") {} + + private: + DISALLOW_COPY_AND_ASSIGN(SaveCardBubbleViewsFullFormWithShippingBrowserTest); +}; + +// Tests the local save bubble. Ensures that local save appears if the RPC to +// Google Payments fails unexpectedly. +IN_PROC_BROWSER_TEST_F( + SaveCardBubbleViewsFullFormBrowserTest, + Local_SubmittingFormShowsBubbleIfGetUploadDetailsRpcFails) { + // Set up the Payments RPC. + SetUploadDetailsRpcServerError(); + + // Submitting the form and having the call to Payments fail should show the + // local save bubble. + // (Must wait for response from Payments before accessing the controller.) + ResetEventWaiterForSequence( + {DialogEvent::REQUESTED_UPLOAD_SAVE, + DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE, + DialogEvent::OFFERED_LOCAL_SAVE}); + FillAndSubmitForm(); + WaitForObservedEvent(); + EXPECT_TRUE( + FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_LOCAL)->visible()); +} + +// Tests the local save bubble. Ensures that clicking the [Save] button +// successfully causes the bubble to go away. +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTest, + Local_ClickingSaveClosesBubble) { + // Set up the Payments RPC. + SetUploadDetailsRpcPaymentsDeclines(); + + // Submitting the form and having Payments decline offering to save should + // show the local save bubble. + // (Must wait for response from Payments before accessing the controller.) + ResetEventWaiterForSequence( + {DialogEvent::REQUESTED_UPLOAD_SAVE, + DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE, + DialogEvent::OFFERED_LOCAL_SAVE}); + FillAndSubmitForm(); + WaitForObservedEvent(); + EXPECT_TRUE( + FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_LOCAL)->visible()); + + // Clicking [Save] should accept and close it. + base::HistogramTester histogram_tester; + content::TestNavigationObserver nav_observer(GetActiveWebContents(), 1); + ClickOnDialogViewWithIdAndWait(DialogViewId::OK_BUTTON); + // The bubble should be closed. + // (Must wait for page navigation to complete before checking.) + nav_observer.Wait(); + EXPECT_FALSE(GetSaveCardBubbleViews()); + // UMA should have recorded bubble acceptance. + histogram_tester.ExpectUniqueSample( + "Autofill.SaveCreditCardPrompt.Local.FirstShow", + AutofillMetrics::SAVE_CARD_PROMPT_END_ACCEPTED, 1); +} + +// Tests the local save bubble. Ensures that clicking the [No thanks] button +// successfully causes the bubble to go away. +IN_PROC_BROWSER_TEST_F( + SaveCardBubbleViewsFullFormBrowserTest, + Local_ClickingNoThanksClosesBubbleIfSecondaryUiMdExpOff) { + DisableSecondaryUiMdExperiment(); + + // Set up the Payments RPC. + SetUploadDetailsRpcPaymentsDeclines(); + + // Submitting the form and having Payments decline offering to save should + // show the local save bubble. + // (Must wait for response from Payments before accessing the controller.) + ResetEventWaiterForSequence( + {DialogEvent::REQUESTED_UPLOAD_SAVE, + DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE, + DialogEvent::OFFERED_LOCAL_SAVE}); + FillAndSubmitForm(); + WaitForObservedEvent(); + EXPECT_TRUE( + FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_LOCAL)->visible()); + + // Clicking [No thanks] should cancel and close it. + base::HistogramTester histogram_tester; + content::TestNavigationObserver nav_observer(GetActiveWebContents(), 1); + ClickOnDialogViewWithIdAndWait(DialogViewId::CANCEL_BUTTON); + // The bubble should be closed. + // (Must wait for page navigation to complete before checking.) + nav_observer.Wait(); + EXPECT_FALSE(GetSaveCardBubbleViews()); + // UMA should have recorded bubble rejection. + histogram_tester.ExpectUniqueSample( + "Autofill.SaveCreditCardPrompt.Local.FirstShow", + AutofillMetrics::SAVE_CARD_PROMPT_END_DENIED, 1); +} + +// Tests the local save bubble. Ensures that the Harmony version of the bubble +// does not have a [No thanks] button (it has an [X] Close button instead.) +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTest, + Local_ShouldNotHaveNoThanksButtonIfSecondaryUiMdExpOn) { + EnableSecondaryUiMdExperiment(); + + // Set up the Payments RPC. + SetUploadDetailsRpcPaymentsDeclines(); + + // Submitting the form and having Payments decline offering to save should + // show the local save bubble. + // (Must wait for response from Payments before accessing the controller.) + ResetEventWaiterForSequence( + {DialogEvent::REQUESTED_UPLOAD_SAVE, + DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE, + DialogEvent::OFFERED_LOCAL_SAVE}); + FillAndSubmitForm(); + WaitForObservedEvent(); + EXPECT_TRUE( + FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_LOCAL)->visible()); + + // Assert that the cancel button cannot be found. + EXPECT_FALSE(FindViewInBubbleById(DialogViewId::CANCEL_BUTTON)); +} + +// Tests the local save bubble. Ensures that clicking the [Learn more] link +// causes the bubble to go away and opens the relevant help page. +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTest, + Local_ClickingLearnMoreClosesBubble) { + // Set up the Payments RPC. + SetUploadDetailsRpcPaymentsDeclines(); + + // Submitting the form and having Payments decline offering to save should + // show the local save bubble. + // (Must wait for response from Payments before accessing the controller.) + ResetEventWaiterForSequence( + {DialogEvent::REQUESTED_UPLOAD_SAVE, + DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE, + DialogEvent::OFFERED_LOCAL_SAVE}); + FillAndSubmitForm(); + WaitForObservedEvent(); + EXPECT_TRUE( + FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_LOCAL)->visible()); + + // Click the [Learn more] link. + content::WebContentsAddedObserver web_contents_added_observer; + ClickOnDialogViewWithIdAndWait(DialogViewId::LEARN_MORE_LINK); + + // The bubble should be hidden after clicking the link (not preferred + // behavior, but it's what we've got.) + EXPECT_FALSE(GetSaveCardBubbleViews()); + // A new support page tab should have been spawned. + content::WebContents* new_tab_contents = + web_contents_added_observer.GetWebContents(); + EXPECT_TRUE(new_tab_contents->GetVisibleURL().spec() == + "https://support.google.com/chrome/?p=settings_autofill" || + new_tab_contents->GetVisibleURL().spec() == + "https://support.google.com/chromebook/?p=settings_autofill"); +} + +// Tests the upload save bubble. Ensures that clicking the [Save] button +// successfully causes the bubble to go away and sends an UploadCardRequest RPC +// to Google Payments. +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTest, + Upload_ClickingSaveClosesBubble) { + // Set up the Payments RPC. + SetUploadDetailsRpcPaymentsAccepts(); + + // Submitting the form should show the upload save bubble and legal footer. + // (Must wait for response from Payments before accessing the controller.) + ResetEventWaiterForSequence( + {DialogEvent::REQUESTED_UPLOAD_SAVE, + DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE}); + FillAndSubmitForm(); + WaitForObservedEvent(); + EXPECT_TRUE( + FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_UPLOAD)->visible()); + EXPECT_TRUE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible()); + + // Clicking [Save] should accept and close it, then send an UploadCardRequest + // to Google Payments. + ResetEventWaiterForSequence({DialogEvent::SENT_UPLOAD_CARD_REQUEST}); + base::HistogramTester histogram_tester; + content::TestNavigationObserver nav_observer(GetActiveWebContents(), 1); + ClickOnDialogViewWithIdAndWait(DialogViewId::OK_BUTTON); + // The bubble should be closed. + // (Must wait for page navigation to complete before checking.) + nav_observer.Wait(); + EXPECT_FALSE(GetSaveCardBubbleViews()); + // UMA should have recorded bubble acceptance. + histogram_tester.ExpectUniqueSample( + "Autofill.SaveCreditCardPrompt.Upload.FirstShow", + AutofillMetrics::SAVE_CARD_PROMPT_END_ACCEPTED, 1); +} + +// Tests the upload save bubble. Ensures that clicking the [No thanks] button +// successfully causes the bubble to go away. +IN_PROC_BROWSER_TEST_F( + SaveCardBubbleViewsFullFormBrowserTest, + Upload_ClickingNoThanksClosesBubbleIfSecondaryUiMdExpOff) { + DisableSecondaryUiMdExperiment(); + + // Set up the Payments RPC. + SetUploadDetailsRpcPaymentsAccepts(); + + // Submitting the form should show the upload save bubble and legal footer. + // (Must wait for response from Payments before accessing the controller.) + ResetEventWaiterForSequence( + {DialogEvent::REQUESTED_UPLOAD_SAVE, + DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE}); + FillAndSubmitForm(); + WaitForObservedEvent(); + EXPECT_TRUE( + FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_UPLOAD)->visible()); + EXPECT_TRUE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible()); + + // Clicking [No thanks] should cancel and close it. + base::HistogramTester histogram_tester; + content::TestNavigationObserver nav_observer(GetActiveWebContents(), 1); + ClickOnDialogViewWithIdAndWait(DialogViewId::CANCEL_BUTTON); + // The bubble should be closed. + // (Must wait for page navigation to complete before checking.) + nav_observer.Wait(); + EXPECT_FALSE(GetSaveCardBubbleViews()); + // UMA should have recorded bubble rejection. + histogram_tester.ExpectUniqueSample( + "Autofill.SaveCreditCardPrompt.Upload.FirstShow", + AutofillMetrics::SAVE_CARD_PROMPT_END_DENIED, 1); +} + +// Tests the upload save bubble. Ensures that the Harmony version of the bubble +// does not have a [No thanks] button (it has an [X] Close button instead.) +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTest, + Upload_ShouldNotHaveNoThanksButtonIfSecondaryUiMdExpOn) { + EnableSecondaryUiMdExperiment(); + + // Set up the Payments RPC. + SetUploadDetailsRpcPaymentsAccepts(); + + // Submitting the form should show the upload save bubble and legal footer. + // (Must wait for response from Payments before accessing the controller.) + ResetEventWaiterForSequence( + {DialogEvent::REQUESTED_UPLOAD_SAVE, + DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE}); + FillAndSubmitForm(); + WaitForObservedEvent(); + EXPECT_TRUE( + FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_UPLOAD)->visible()); + EXPECT_TRUE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible()); + + // Assert that the cancel button cannot be found. + EXPECT_FALSE(FindViewInBubbleById(DialogViewId::CANCEL_BUTTON)); +} + +// TODO(crbug.com/791861): There doesn't seem to be a good way of accessing and +// clicking the [X] close button in the top-right corner of the dialog. Calling +// Close() on the bubble doesn't reach WindowClosing(). The closest thing would +// be forcibly destroying the bubble, but at that point the test is already far +// removed from emulating clicking the [X]. When/if that can be worked around, +// create an Upload_ClickingCloseClosesBubbleIfSecondaryUiMdExpOn test. + +// Tests the upload save bubble. Ensures that the updated UI version of the +// bubble (as of M62) does not have a [Learn more] link. +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTest, + Upload_ShouldNotHaveLearnMoreLinkIfNewUiExperimentOn) { + // Set up the Payments RPC. + SetUploadDetailsRpcPaymentsAccepts(); + + // Submitting the form should show the upload save bubble and legal footer. + // (Must wait for response from Payments before accessing the controller.) + ResetEventWaiterForSequence( + {DialogEvent::REQUESTED_UPLOAD_SAVE, + DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE}); + FillAndSubmitForm(); + WaitForObservedEvent(); + EXPECT_TRUE( + FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_UPLOAD)->visible()); + EXPECT_TRUE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible()); + + // Assert that the Learn more link cannot be found. + EXPECT_FALSE(FindViewInBubbleById(DialogViewId::LEARN_MORE_LINK)); +} + +// TODO(jsaul): Only *part* of the legal message StyledLabel is clickable, and +// the NOTREACHED() in SaveCardBubbleViews::StyledLabelLinkClicked +// prevents us from being able to click it unless we know the exact +// gfx::Range of the link. When/if that can be worked around, +// create an Upload_ClickingTosLinkClosesBubble test. + +// Tests the upload save bubble. Ensures that if CVC is invalid when the credit +// card is submitted, the bubble is still shown with the CVC fix flow (starts +// with the footer hidden due to showing it on the second step). +IN_PROC_BROWSER_TEST_F( + SaveCardBubbleViewsFullFormBrowserTest, + Upload_SubmittingFormWithInvalidCvcShowsBubbleIfCvcExpOn) { + EnableRequestCvcIfMissingExperiment(); + + // Set up the Payments RPC. + SetUploadDetailsRpcPaymentsAccepts(); + + // Submitting the form should show the upload save bubble, but should NOT show + // the legal footer on the initial step, and the CVC request view should not + // yet exist. + // (Must wait for response from Payments before accessing the controller.) + ResetEventWaiterForSequence( + {DialogEvent::REQUESTED_UPLOAD_SAVE, + DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE}); + FillAndSubmitFormWithInvalidCvc(); + WaitForObservedEvent(); + EXPECT_TRUE( + FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_UPLOAD)->visible()); + EXPECT_FALSE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible()); + EXPECT_FALSE(FindViewInBubbleById(DialogViewId::REQUEST_CVC_VIEW)); +} + +// Tests the upload save bubble. Ensures that during the CVC fix flow, the final +// [Confirm] button is disabled if CVC has not yet been entered. +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTest, + Upload_ConfirmButtonIsDisabledIfNoCvcAndCvcExpOn) { + EnableRequestCvcIfMissingExperiment(); + + // Set up the Payments RPC. + SetUploadDetailsRpcPaymentsAccepts(); + + // Submitting the form should show the upload save bubble, but should NOT show + // the legal footer on the initial step, and the CVC request view should not + // yet exist. + // (Must wait for response from Payments before accessing the controller.) + ResetEventWaiterForSequence( + {DialogEvent::REQUESTED_UPLOAD_SAVE, + DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE}); + FillAndSubmitFormWithoutCvc(); + WaitForObservedEvent(); + EXPECT_TRUE( + FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_UPLOAD)->visible()); + EXPECT_FALSE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible()); + EXPECT_FALSE(FindViewInBubbleById(DialogViewId::REQUEST_CVC_VIEW)); + + // Clicking [Next] should not close the bubble, but rather advance to the + // request CVC step and show the legal message footer. + ClickOnDialogViewWithIdAndWait(DialogViewId::OK_BUTTON); + EXPECT_TRUE(FindViewInBubbleById(DialogViewId::REQUEST_CVC_VIEW)->visible()); + EXPECT_TRUE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible()); + + // The [Confirm] button should be disabled due to no CVC yet entered. + views::LabelButton* confirm_button = static_cast<views::LabelButton*>( + FindViewInBubbleById(DialogViewId::OK_BUTTON)); + EXPECT_EQ(confirm_button->state(), + views::LabelButton::ButtonState::STATE_DISABLED); +} + +// Tests the upload save bubble. Ensures that during the CVC fix flow, the final +// [Confirm] button is disabled if the entered CVC is invalid. +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTest, + Upload_ConfirmButtonIsDisabledIfInvalidCvcAndCvcExpOn) { + EnableRequestCvcIfMissingExperiment(); + + // Set up the Payments RPC. + SetUploadDetailsRpcPaymentsAccepts(); + + // Submitting the form should show the upload save bubble, but should NOT show + // the legal footer on the initial step, and the CVC request view should not + // yet exist. + // (Must wait for response from Payments before accessing the controller.) + ResetEventWaiterForSequence( + {DialogEvent::REQUESTED_UPLOAD_SAVE, + DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE}); + FillAndSubmitFormWithoutCvc(); + WaitForObservedEvent(); + EXPECT_TRUE( + FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_UPLOAD)->visible()); + EXPECT_FALSE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible()); + EXPECT_FALSE(FindViewInBubbleById(DialogViewId::REQUEST_CVC_VIEW)); + + // Clicking [Next] should not close the bubble, but rather advance to the + // request CVC step and show the legal message footer. + ClickOnDialogViewWithIdAndWait(DialogViewId::OK_BUTTON); + EXPECT_TRUE(FindViewInBubbleById(DialogViewId::REQUEST_CVC_VIEW)->visible()); + EXPECT_TRUE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible()); + + // Enter an invalid length CVC (4-digit CVC for non-AmEx card, for instance). + views::Textfield* cvc_field = static_cast<views::Textfield*>( + FindViewInBubbleById(DialogViewId::CVC_TEXTFIELD)); + cvc_field->InsertOrReplaceText(base::ASCIIToUTF16("1234")); + + // The [Confirm] button should be disabled due to the invalid CVC. + views::LabelButton* confirm_button = static_cast<views::LabelButton*>( + FindViewInBubbleById(DialogViewId::OK_BUTTON)); + EXPECT_EQ(confirm_button->state(), + views::LabelButton::ButtonState::STATE_DISABLED); +} + +// Tests the upload save bubble. Ensures that during the CVC fix flow, if a +// valid 3-digit CVC is entered, the [Confirm] button successfully causes the +// bubble to go away and sends an UploadCardRequest RPC to Google Payments. +IN_PROC_BROWSER_TEST_F( + SaveCardBubbleViewsFullFormBrowserTest, + Upload_Entering3DigitCvcAndClickingConfirmClosesBubbleIfNoCvcAndCvcExpOn) { + EnableRequestCvcIfMissingExperiment(); + + // Set up the Payments RPC. + SetUploadDetailsRpcPaymentsAccepts(); + + // Submitting the form should show the upload save bubble, but should NOT show + // the legal footer on the initial step, and the CVC request view should not + // yet exist. + // (Must wait for response from Payments before accessing the controller.) + ResetEventWaiterForSequence( + {DialogEvent::REQUESTED_UPLOAD_SAVE, + DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE}); + FillAndSubmitFormWithoutCvc(); + WaitForObservedEvent(); + EXPECT_TRUE( + FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_UPLOAD)->visible()); + EXPECT_FALSE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible()); + EXPECT_FALSE(FindViewInBubbleById(DialogViewId::REQUEST_CVC_VIEW)); + + // Clicking [Next] should not close the bubble, but rather advance to the + // request CVC step and show the legal message footer. + ClickOnDialogViewWithIdAndWait(DialogViewId::OK_BUTTON); + EXPECT_TRUE(FindViewInBubbleById(DialogViewId::REQUEST_CVC_VIEW)->visible()); + EXPECT_TRUE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible()); + + // Clicking [Confirm] after entering CVC should accept and close the bubble, + // then send an UploadCardRequest to Google Payments. + ResetEventWaiterForSequence({DialogEvent::SENT_UPLOAD_CARD_REQUEST}); + views::Textfield* cvc_field = static_cast<views::Textfield*>( + FindViewInBubbleById(DialogViewId::CVC_TEXTFIELD)); + cvc_field->InsertOrReplaceText(base::ASCIIToUTF16("123")); + base::HistogramTester histogram_tester; + content::TestNavigationObserver nav_observer(GetActiveWebContents(), 1); + ClickOnDialogViewWithIdAndWait(DialogViewId::OK_BUTTON); + // The bubble should be closed. + // (Must wait for page navigation to complete before checking.) + nav_observer.Wait(); + EXPECT_FALSE(GetSaveCardBubbleViews()); + // UMA should have recorded bubble and CVC fix flow acceptance. + EXPECT_THAT( + histogram_tester.GetAllSamples( + "Autofill.SaveCreditCardPrompt.Upload.FirstShow"), + ElementsAre( + Bucket(AutofillMetrics::SAVE_CARD_PROMPT_END_ACCEPTED, 1), + Bucket(AutofillMetrics::SAVE_CARD_PROMPT_CVC_FIX_FLOW_END_ACCEPTED, + 1))); +} + +// Tests the upload save bubble. Ensures that during the CVC fix flow, if a +// valid 4-digit CVC (for an AmEx card) is entered, the [Confirm] button +// successfully causes the bubble to go away and sends an UploadCardRequest RPC +// to Google Payments. +IN_PROC_BROWSER_TEST_F( + SaveCardBubbleViewsFullFormBrowserTest, + Upload_Entering4DigitCvcAndClickingConfirmClosesBubbleIfNoCvcAndCvcExpOn) { + EnableRequestCvcIfMissingExperiment(); + + // Set up the Payments RPC. + SetUploadDetailsRpcPaymentsAccepts(); + + // Submitting the form should show the upload save bubble, but should NOT show + // the legal footer on the initial step, and the CVC request view should not + // yet exist. + // (Must wait for response from Payments before accessing the controller.) + ResetEventWaiterForSequence( + {DialogEvent::REQUESTED_UPLOAD_SAVE, + DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE}); + FillAndSubmitFormWithAmexWithoutCvc(); + WaitForObservedEvent(); + EXPECT_TRUE( + FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_UPLOAD)->visible()); + EXPECT_FALSE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible()); + EXPECT_FALSE(FindViewInBubbleById(DialogViewId::REQUEST_CVC_VIEW)); + + // Clicking [Next] should not close the bubble, but rather advance to the + // request CVC step and show the legal message footer. + ClickOnDialogViewWithIdAndWait(DialogViewId::OK_BUTTON); + EXPECT_TRUE(FindViewInBubbleById(DialogViewId::REQUEST_CVC_VIEW)->visible()); + EXPECT_TRUE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible()); + + // Clicking [Confirm] after entering CVC should accept and close the bubble, + // then send an UploadCardRequest to Google Payments. + ResetEventWaiterForSequence({DialogEvent::SENT_UPLOAD_CARD_REQUEST}); + views::Textfield* cvc_field = static_cast<views::Textfield*>( + FindViewInBubbleById(DialogViewId::CVC_TEXTFIELD)); + cvc_field->InsertOrReplaceText(base::ASCIIToUTF16("1234")); + base::HistogramTester histogram_tester; + content::TestNavigationObserver nav_observer(GetActiveWebContents(), 1); + ClickOnDialogViewWithIdAndWait(DialogViewId::OK_BUTTON); + // The bubble should be closed. + // (Must wait for page navigation to complete before checking.) + nav_observer.Wait(); + EXPECT_FALSE(GetSaveCardBubbleViews()); + // UMA should have recorded bubble and CVC fix flow acceptance. + EXPECT_THAT( + histogram_tester.GetAllSamples( + "Autofill.SaveCreditCardPrompt.Upload.FirstShow"), + ElementsAre( + Bucket(AutofillMetrics::SAVE_CARD_PROMPT_END_ACCEPTED, 1), + Bucket(AutofillMetrics::SAVE_CARD_PROMPT_CVC_FIX_FLOW_END_ACCEPTED, + 1))); +} + +// Tests the upload save logic. Ensures that credit card upload is offered if +// name, address, and CVC are detected. +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTest, + Logic_ShouldAttemptToOfferToSaveIfEverythingFound) { + DisableSendDetectedValuesExperiment(); + + // Submitting the form should start the flow of asking Payments if Chrome + // should offer to save the card to Google. + ResetEventWaiterForSequence({DialogEvent::REQUESTED_UPLOAD_SAVE}); + FillAndSubmitForm(); + WaitForObservedEvent(); +} + +// Tests the upload save logic. Ensures that credit card upload is offered even +// if street addresses conflict, as long as their postal codes are the same. +IN_PROC_BROWSER_TEST_F( + SaveCardBubbleViewsFullFormWithShippingBrowserTest, + Logic_ShouldAttemptToOfferToSaveIfStreetAddressesConflict) { + DisableSendDetectedValuesExperiment(); + + // Submit first shipping address form with a conflicting street address. + content::TestNavigationObserver shipping_form_nav_observer( + GetActiveWebContents(), 1); + FillAndSubmitFormWithConflictingStreetAddress(); + shipping_form_nav_observer.Wait(); + + // Submitting the second form should start the flow of asking Payments if + // Chrome should offer to save the Google, because conflicting street + // addresses with the same postal code are allowable. + ResetEventWaiterForSequence({DialogEvent::REQUESTED_UPLOAD_SAVE}); + FillAndSubmitForm(); + WaitForObservedEvent(); +} + +// Tests the upload save logic. Ensures that credit card upload is not offered +// if CVC is not detected and the CVC fix flow is not enabled. +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTest, + Logic_ShouldNotOfferToSaveIfCvcNotFoundAndCvcExpOff) { + DisableRequestCvcIfMissingAndSendDetectedValuesExperiments(); + + // Submitting the form should not show the upload save bubble because CVC is + // missing. + ResetEventWaiterForSequence({DialogEvent::DID_NOT_REQUEST_UPLOAD_SAVE}); + FillAndSubmitFormWithoutCvc(); + WaitForObservedEvent(); +} + +// Tests the upload save logic. Ensures that credit card upload is not offered +// if an invalid CVC is detected and the CVC fix flow is not enabled. +IN_PROC_BROWSER_TEST_F( + SaveCardBubbleViewsFullFormBrowserTest, + Logic_ShouldNotOfferToSaveIfInvalidCvcFoundAndCvcExpOff) { + DisableRequestCvcIfMissingAndSendDetectedValuesExperiments(); + + // Submitting the form should not show the upload save bubble because CVC is + // invalid. + ResetEventWaiterForSequence({DialogEvent::DID_NOT_REQUEST_UPLOAD_SAVE}); + FillAndSubmitFormWithInvalidCvc(); + WaitForObservedEvent(); +} + +// Tests the upload save logic. Ensures that credit card upload is not offered +// if address/cardholder name is not detected. +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTest, + Logic_ShouldNotOfferToSaveIfNameNotFound) { + DisableSendDetectedValuesExperiment(); + + // Submitting the form should not show the upload save bubble because name is + // missing. + ResetEventWaiterForSequence({DialogEvent::DID_NOT_REQUEST_UPLOAD_SAVE}); + FillAndSubmitFormWithoutName(); + WaitForObservedEvent(); +} + +// Tests the upload save logic. Ensures that credit card upload is not offered +// if multiple conflicting names are detected. +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormWithShippingBrowserTest, + Logic_ShouldNotOfferToSaveIfNamesConflict) { + DisableSendDetectedValuesExperiment(); + + // Submit first shipping address form with a conflicting name. + content::TestNavigationObserver shipping_form_nav_observer( + GetActiveWebContents(), 1); + FillAndSubmitFormWithConflictingName(); + shipping_form_nav_observer.Wait(); + + // Submitting the second form should not show the upload save bubble because + // the name conflicts with the previous form. + ResetEventWaiterForSequence({DialogEvent::DID_NOT_REQUEST_UPLOAD_SAVE}); + FillAndSubmitForm(); + WaitForObservedEvent(); +} + +// Tests the upload save logic. Ensures that credit card upload is not offered +// if billing address is not detected. +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTest, + Logic_ShouldNotOfferToSaveIfAddressNotFound) { + DisableSendDetectedValuesExperiment(); + + // Submitting the form should not show the upload save bubble because address + // is missing. + ResetEventWaiterForSequence({DialogEvent::DID_NOT_REQUEST_UPLOAD_SAVE}); + FillAndSubmitFormWithoutAddress(); + WaitForObservedEvent(); +} + +// Tests the upload save logic. Ensures that credit card upload is not offered +// if multiple conflicting billing address postal codes are detected. +IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormWithShippingBrowserTest, + Logic_ShouldNotOfferToSaveIfPostalCodesConflict) { + DisableSendDetectedValuesExperiment(); + + // Submit first shipping address form with a conflicting postal code. + content::TestNavigationObserver shipping_form_nav_observer( + GetActiveWebContents(), 1); + FillAndSubmitFormWithConflictingPostalCode(); + shipping_form_nav_observer.Wait(); + + // Submitting the second form should not show the upload save bubble because + // the postal code conflicts with the previous form. + ResetEventWaiterForSequence({DialogEvent::DID_NOT_REQUEST_UPLOAD_SAVE}); + FillAndSubmitForm(); + WaitForObservedEvent(); +} + +} // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.cc new file mode 100644 index 0000000..3793d96 --- /dev/null +++ b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.cc
@@ -0,0 +1,475 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.h" + +#include <list> +#include <memory> +#include <string> + +#include "chrome/browser/ui/autofill/chrome_autofill_client.h" +#include "chrome/browser/ui/autofill/save_card_bubble_controller_impl.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/views/autofill/dialog_event_waiter.h" +#include "chrome/browser/ui/views/autofill/dialog_view_ids.h" +#include "chrome/browser/ui/views/autofill/save_card_bubble_views.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/autofill/content/browser/content_autofill_driver.h" +#include "components/autofill/core/browser/autofill_experiments.h" +#include "components/autofill/core/browser/credit_card_save_manager.h" +#include "components/network_session_configurator/common/network_switches.h" +#include "content/public/test/browser_test_utils.h" +#include "device/geolocation/public/interfaces/geolocation_context.mojom.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "net/dns/mock_host_resolver.h" +#include "net/url_request/test_url_fetcher_factory.h" +#include "services/service_manager/public/cpp/binder_registry.h" +#include "services/service_manager/public/cpp/connector.h" +#include "ui/base/ui_base_features.h" +#include "ui/events/base_event_utils.h" +#include "ui/views/controls/button/button.h" +#include "ui/views/window/dialog_client_view.h" + +namespace autofill { + +namespace { + +const char kURLGetUploadDetailsRequest[] = + "https://payments.google.com/payments/apis/chromepaymentsservice/" + "getdetailsforsavecard"; +const char kResponseGetUploadDetailsSuccess[] = + "{\"legal_message\":{\"line\":[{\"template\":\"Legal message template with " + "link: " + "{0}.\",\"template_parameter\":[{\"display_text\":\"Link\",\"url\":\"https:" + "//www.example.com/\"}]}]},\"context_token\":\"dummy_context_token\"}"; +const char kResponseGetUploadDetailsFailure[] = + "{\"error\":{\"code\":\"FAILED_PRECONDITION\",\"user_error_message\":\"An " + "unexpected error has occurred. Please try again later.\"}}"; + +const double kFakeGeolocationLatitude = -42.0; +const double kFakeGeolocationLongitude = 17.3; +const double kFakeGeolocationAltitude = 123.4; +const double kFakeGeolocationAccuracy = 73.7; +const int kFakeGeolocationTime = 87; + +} // namespace + +// A fake geolocation client; necessary due to leaks in the geolocation setup +// code that causes browsertests to fail when run. +// TODO(crbug.com/791155): Remove this class's implementation once the leak is +// fixed and the original geolocation client can be used in browsertests. +class SaveCardBubbleViewsBrowserTestBase::FakeGeolocation + : public device::mojom::GeolocationContext, + public device::mojom::Geolocation { + public: + explicit FakeGeolocation(device::mojom::Geoposition& position); + ~FakeGeolocation() override; + + void Bind(device::mojom::GeolocationContextRequest request); + + // device::mojom::Geolocation implementation: + void QueryNextPosition(QueryNextPositionCallback callback) override; + void SetHighAccuracy(bool high_accuracy) override; + + // device::mojom::GeolocationContext implementation: + void BindGeolocation(device::mojom::GeolocationRequest request) override; + void SetOverride(device::mojom::GeopositionPtr geoposition) override; + void ClearOverride() override; + + private: + mojo::Binding<device::mojom::GeolocationContext> binding_context_; + mojo::Binding<device::mojom::Geolocation> binding_; + device::mojom::Geoposition position_; +}; + +SaveCardBubbleViewsBrowserTestBase::FakeGeolocation::FakeGeolocation( + device::mojom::Geoposition& position) + : binding_context_(this), binding_(this), position_(position) {} + +SaveCardBubbleViewsBrowserTestBase::FakeGeolocation::~FakeGeolocation() {} + +void SaveCardBubbleViewsBrowserTestBase::FakeGeolocation::Bind( + device::mojom::GeolocationContextRequest request) { + binding_context_.Bind(std::move(request)); +} + +void SaveCardBubbleViewsBrowserTestBase::FakeGeolocation::QueryNextPosition( + QueryNextPositionCallback callback) { + std::move(callback).Run(position_.Clone()); +} + +void SaveCardBubbleViewsBrowserTestBase::FakeGeolocation::SetHighAccuracy( + bool high_accuracy) {} + +void SaveCardBubbleViewsBrowserTestBase::FakeGeolocation::BindGeolocation( + device::mojom::GeolocationRequest request) { + binding_.Bind(std::move(request)); +} + +void SaveCardBubbleViewsBrowserTestBase::FakeGeolocation::SetOverride( + device::mojom::GeopositionPtr geoposition) {} + +void SaveCardBubbleViewsBrowserTestBase::FakeGeolocation::ClearOverride() {} + +SaveCardBubbleViewsBrowserTestBase::SaveCardBubbleViewsBrowserTestBase( + const std::string& test_file_path) + : test_file_path_(test_file_path) {} + +SaveCardBubbleViewsBrowserTestBase::~SaveCardBubbleViewsBrowserTestBase() {} + +void SaveCardBubbleViewsBrowserTestBase::SetUpCommandLine( + base::CommandLine* command_line) { + // HTTPS server only serves a valid cert for localhost, so this is needed to + // load pages from "a.com" without an interstitial. + command_line->AppendSwitch(switches::kIgnoreCertificateErrors); +} + +void SaveCardBubbleViewsBrowserTestBase::SetUpOnMainThread() { + // Set up the HTTPS server (uses the embedded_test_server). + host_resolver()->AddRule("*", "127.0.0.1"); + ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); + embedded_test_server()->ServeFilesFromSourceDirectory( + "components/test/data/autofill"); + embedded_test_server()->StartAcceptingConnections(); + + // Set up the URL fetcher. By providing an Impl, unexpected calls (sync, etc.) + // won't cause the test to crash. + url_fetcher_factory_ = std::make_unique<net::FakeURLFetcherFactory>( + new net::URLFetcherImplFactory()); + + // Set up this class as the ObserverForTest implementation. + CreditCardSaveManager* credit_card_save_manager = + ContentAutofillDriver::GetForRenderFrameHost( + GetActiveWebContents()->GetMainFrame()) + ->autofill_manager() + ->form_data_importer_.get() + ->credit_card_save_manager_.get(); + credit_card_save_manager->SetEventObserverForTesting(this); + + // Set up fake geolocation. Necessary due to leaks in the geolocation setup + // code when loading risk data. + device::mojom::Geoposition position; + position.latitude = kFakeGeolocationLatitude; + position.longitude = kFakeGeolocationLongitude; + position.altitude = kFakeGeolocationAltitude; + position.accuracy = kFakeGeolocationAccuracy; + position.timestamp = base::Time::UnixEpoch() + + base::TimeDelta::FromMilliseconds(kFakeGeolocationTime); + service_manager::mojom::ConnectorRequest connector_request; + connector_ = service_manager::Connector::Create(&connector_request); + fake_geolocation_ = std::make_unique<FakeGeolocation>(position); + registry_.AddInterface<device::mojom::GeolocationContext>(base::BindRepeating( + &FakeGeolocation::Bind, base::Unretained(fake_geolocation_.get()))); + ChromeAutofillClient* chrome_autofill_client = + ChromeAutofillClient::FromWebContents(GetActiveWebContents()); + chrome_autofill_client->connector_ = connector_.get(); + + NavigateTo(test_file_path_); +} + +void SaveCardBubbleViewsBrowserTestBase::NavigateTo( + const std::string& file_path) { + if (file_path.find("data:") == 0U) { + ui_test_utils::NavigateToURL(browser(), GURL(file_path)); + } else { + ui_test_utils::NavigateToURL( + browser(), embedded_test_server()->GetURL("a.com", file_path)); + } +} + +void SaveCardBubbleViewsBrowserTestBase::OnOfferLocalSave() { + if (event_waiter_) + event_waiter_->OnEvent(DialogEvent::OFFERED_LOCAL_SAVE); +} + +void SaveCardBubbleViewsBrowserTestBase::OnDecideToRequestUploadSave() { + if (event_waiter_) + event_waiter_->OnEvent(DialogEvent::REQUESTED_UPLOAD_SAVE); +} + +void SaveCardBubbleViewsBrowserTestBase::OnDecideToNotRequestUploadSave() { + if (event_waiter_) + event_waiter_->OnEvent(DialogEvent::DID_NOT_REQUEST_UPLOAD_SAVE); +} + +void SaveCardBubbleViewsBrowserTestBase::OnReceivedGetUploadDetailsResponse() { + if (event_waiter_) + event_waiter_->OnEvent(DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE); +} + +void SaveCardBubbleViewsBrowserTestBase::OnSentUploadCardRequest() { + if (event_waiter_) + event_waiter_->OnEvent(DialogEvent::SENT_UPLOAD_CARD_REQUEST); +} + +void SaveCardBubbleViewsBrowserTestBase:: + DisableRequestCvcIfMissingAndSendDetectedValuesExperiments() { + scoped_feature_list_.InitWithFeatures( + {}, // Enabled + {kAutofillUpstreamRequestCvcIfMissing, + kAutofillUpstreamSendDetectedValues} // Disabled + ); +} + +void SaveCardBubbleViewsBrowserTestBase::DisableSendDetectedValuesExperiment() { + scoped_feature_list_.InitAndDisableFeature( + kAutofillUpstreamSendDetectedValues); +} + +void SaveCardBubbleViewsBrowserTestBase::DisableSecondaryUiMdExperiment() { + scoped_feature_list_.InitAndDisableFeature(features::kSecondaryUiMd); +} + +void SaveCardBubbleViewsBrowserTestBase::EnableRequestCvcIfMissingExperiment() { + scoped_feature_list_.InitAndEnableFeature( + kAutofillUpstreamRequestCvcIfMissing); +} + +void SaveCardBubbleViewsBrowserTestBase::EnableSecondaryUiMdExperiment() { + scoped_feature_list_.InitAndEnableFeature(features::kSecondaryUiMd); +} + +// Should be called for credit_card_upload_form_address_and_cc.html. +void SaveCardBubbleViewsBrowserTestBase::FillAndSubmitForm() { + content::WebContents* web_contents = GetActiveWebContents(); + const std::string click_fill_button_js = + "(function() { document.getElementById('fill_form').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_fill_button_js)); + + const std::string click_submit_button_js = + "(function() { document.getElementById('submit').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_submit_button_js)); +} + +// Should be called for credit_card_upload_form_address_and_cc.html. +void SaveCardBubbleViewsBrowserTestBase::FillAndSubmitFormWithoutCvc() { + content::WebContents* web_contents = GetActiveWebContents(); + const std::string click_fill_button_js = + "(function() { document.getElementById('fill_form').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_fill_button_js)); + + const std::string click_clear_cvc_button_js = + "(function() { document.getElementById('clear_cvc').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_clear_cvc_button_js)); + + const std::string click_submit_button_js = + "(function() { document.getElementById('submit').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_submit_button_js)); +} + +// Should be called for credit_card_upload_form_address_and_cc.html. +void SaveCardBubbleViewsBrowserTestBase::FillAndSubmitFormWithInvalidCvc() { + content::WebContents* web_contents = GetActiveWebContents(); + const std::string click_fill_button_js = + "(function() { document.getElementById('fill_form').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_fill_button_js)); + + const std::string click_fill_invalid_cvc_button_js = + "(function() { document.getElementById('fill_invalid_cvc').click(); " + "})();"; + ASSERT_TRUE( + content::ExecuteScript(web_contents, click_fill_invalid_cvc_button_js)); + + const std::string click_submit_button_js = + "(function() { document.getElementById('submit').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_submit_button_js)); +} + +// Should be called for credit_card_upload_form_address_and_cc.html. +void SaveCardBubbleViewsBrowserTestBase::FillAndSubmitFormWithAmexWithoutCvc() { + content::WebContents* web_contents = GetActiveWebContents(); + const std::string click_fill_amex_button_js = + "(function() { document.getElementById('fill_form_amex').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_fill_amex_button_js)); + + const std::string click_clear_cvc_button_js = + "(function() { document.getElementById('clear_cvc').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_clear_cvc_button_js)); + + const std::string click_submit_button_js = + "(function() { document.getElementById('submit').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_submit_button_js)); +} + +// Should be called for credit_card_upload_form_address_and_cc.html. +void SaveCardBubbleViewsBrowserTestBase::FillAndSubmitFormWithoutName() { + content::WebContents* web_contents = GetActiveWebContents(); + const std::string click_fill_button_js = + "(function() { document.getElementById('fill_form').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_fill_button_js)); + + const std::string click_clear_name_button_js = + "(function() { document.getElementById('clear_name').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_clear_name_button_js)); + + const std::string click_submit_button_js = + "(function() { document.getElementById('submit').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_submit_button_js)); +} + +// Should be called for credit_card_upload_form_address_and_cc.html. +void SaveCardBubbleViewsBrowserTestBase::FillAndSubmitFormWithoutAddress() { + content::WebContents* web_contents = GetActiveWebContents(); + const std::string click_fill_button_js = + "(function() { document.getElementById('fill_form').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_fill_button_js)); + + const std::string click_clear_name_button_js = + "(function() { document.getElementById('clear_address').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_clear_name_button_js)); + + const std::string click_submit_button_js = + "(function() { document.getElementById('submit').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_submit_button_js)); +} + +// Should be called for credit_card_upload_form_shipping_address.html. +void SaveCardBubbleViewsBrowserTestBase:: + FillAndSubmitFormWithConflictingName() { + content::WebContents* web_contents = GetActiveWebContents(); + const std::string click_fill_button_js = + "(function() { document.getElementById('fill_form').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_fill_button_js)); + + const std::string click_conflicting_name_button_js = + "(function() { document.getElementById('conflicting_name').click(); " + "})();"; + ASSERT_TRUE( + content::ExecuteScript(web_contents, click_conflicting_name_button_js)); + + const std::string click_submit_button_js = + "(function() { document.getElementById('submit').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_submit_button_js)); +} + +// Should be called for credit_card_upload_form_shipping_address.html. +void SaveCardBubbleViewsBrowserTestBase:: + FillAndSubmitFormWithConflictingStreetAddress() { + content::WebContents* web_contents = GetActiveWebContents(); + const std::string click_fill_button_js = + "(function() { document.getElementById('fill_form').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_fill_button_js)); + + const std::string click_conflicting_street_address_button_js = + "(function() { " + "document.getElementById('conflicting_street_address').click(); })();"; + ASSERT_TRUE(content::ExecuteScript( + web_contents, click_conflicting_street_address_button_js)); + + const std::string click_submit_button_js = + "(function() { document.getElementById('submit').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_submit_button_js)); +} + +// Should be called for credit_card_upload_form_shipping_address.html. +void SaveCardBubbleViewsBrowserTestBase:: + FillAndSubmitFormWithConflictingPostalCode() { + content::WebContents* web_contents = GetActiveWebContents(); + const std::string click_fill_button_js = + "(function() { document.getElementById('fill_form').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_fill_button_js)); + + const std::string click_conflicting_postal_code_button_js = + "(function() { " + "document.getElementById('conflicting_postal_code').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, + click_conflicting_postal_code_button_js)); + + const std::string click_submit_button_js = + "(function() { document.getElementById('submit').click(); })();"; + ASSERT_TRUE(content::ExecuteScript(web_contents, click_submit_button_js)); +} + +void SaveCardBubbleViewsBrowserTestBase::SetUploadDetailsRpcPaymentsAccepts() { + url_fetcher_factory_->SetFakeResponse( + GURL(kURLGetUploadDetailsRequest), kResponseGetUploadDetailsSuccess, + net::HTTP_OK, net::URLRequestStatus::SUCCESS); +} + +void SaveCardBubbleViewsBrowserTestBase::SetUploadDetailsRpcPaymentsDeclines() { + url_fetcher_factory_->SetFakeResponse( + GURL(kURLGetUploadDetailsRequest), kResponseGetUploadDetailsFailure, + net::HTTP_OK, net::URLRequestStatus::SUCCESS); +} + +void SaveCardBubbleViewsBrowserTestBase::SetUploadDetailsRpcServerError() { + url_fetcher_factory_->SetFakeResponse( + GURL(kURLGetUploadDetailsRequest), kResponseGetUploadDetailsSuccess, + net::HTTP_INTERNAL_SERVER_ERROR, net::URLRequestStatus::FAILED); +} + +void SaveCardBubbleViewsBrowserTestBase::ClickOnDialogViewWithIdAndWait( + DialogViewId view_id) { + views::View* specified_view = FindViewInBubbleById(view_id); + DCHECK(specified_view); + + ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), + ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, + ui::EF_LEFT_MOUSE_BUTTON); + specified_view->OnMousePressed(pressed); + ui::MouseEvent released_event = ui::MouseEvent( + ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), + ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); + specified_view->OnMouseReleased(released_event); + + WaitForObservedEvent(); +} + +views::View* SaveCardBubbleViewsBrowserTestBase::FindViewInBubbleById( + DialogViewId view_id) { + SaveCardBubbleViews* save_card_bubble_views = GetSaveCardBubbleViews(); + DCHECK(save_card_bubble_views); + + views::View* specified_view = + save_card_bubble_views->GetViewByID(static_cast<int>(view_id)); + if (!specified_view) { + // Many of the save card bubble's inner Views are not child views but rather + // contained by its DialogClientView. If we didn't find what we were looking + // for, check there as well. + specified_view = save_card_bubble_views->GetDialogClientView()->GetViewByID( + static_cast<int>(view_id)); + } + if (!specified_view) { + // Additionally, the save card bubble's footnote view is not part of its + // main bubble, and contains elements such as the legal message links. + // If we didn't find what we were looking for, check there as well. + views::View* footnote_view = + save_card_bubble_views->GetFootnoteViewForTesting(); + if (footnote_view) { + specified_view = footnote_view->GetViewByID(static_cast<int>(view_id)); + } + } + return specified_view; +} + +SaveCardBubbleViews* +SaveCardBubbleViewsBrowserTestBase::GetSaveCardBubbleViews() { + SaveCardBubbleControllerImpl* save_card_bubble_controller_impl = + SaveCardBubbleControllerImpl::FromWebContents(GetActiveWebContents()); + if (!save_card_bubble_controller_impl) + return nullptr; + SaveCardBubbleView* save_card_bubble_view = + save_card_bubble_controller_impl->save_card_bubble_view(); + if (!save_card_bubble_view) + return nullptr; + return static_cast<SaveCardBubbleViews*>(save_card_bubble_view); +} + +content::WebContents* +SaveCardBubbleViewsBrowserTestBase::GetActiveWebContents() { + return browser()->tab_strip_model()->GetActiveWebContents(); +} + +void SaveCardBubbleViewsBrowserTestBase::ResetEventWaiterForSequence( + std::list<DialogEvent> event_sequence) { + event_waiter_ = std::make_unique<DialogEventWaiter<DialogEvent>>( + std::move(event_sequence)); +} + +void SaveCardBubbleViewsBrowserTestBase::WaitForObservedEvent() { + event_waiter_->Wait(); +} + +} // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.h b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.h new file mode 100644 index 0000000..597f7925 --- /dev/null +++ b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.h
@@ -0,0 +1,120 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_SAVE_CARD_BUBBLE_VIEWS_BROWSERTEST_BASE_H_ +#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_SAVE_CARD_BUBBLE_VIEWS_BROWSERTEST_BASE_H_ + +#include <list> +#include <memory> +#include <string> + +#include "base/command_line.h" +#include "base/macros.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/ui/views/autofill/dialog_event_waiter.h" +#include "chrome/browser/ui/views/autofill/dialog_view_ids.h" +#include "chrome/browser/ui/views/autofill/save_card_bubble_views.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "components/autofill/core/browser/credit_card_save_manager.h" +#include "content/public/browser/web_contents_observer.h" +#include "device/geolocation/public/interfaces/geolocation_context.mojom.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/url_request/test_url_fetcher_factory.h" +#include "services/service_manager/public/cpp/binder_registry.h" +#include "services/service_manager/public/cpp/connector.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace autofill { + +// Base class for any interactive SaveCardBubbleViews browser test that will +// need to show and interact with the offer-to-save bubble. +class SaveCardBubbleViewsBrowserTestBase + : public InProcessBrowserTest, + public CreditCardSaveManager::ObserverForTest { + public: + // Various events that can be waited on by the DialogEventWaiter. + enum DialogEvent : int { + OFFERED_LOCAL_SAVE, + REQUESTED_UPLOAD_SAVE, + DID_NOT_REQUEST_UPLOAD_SAVE, + RECEIVED_GET_UPLOAD_DETAILS_RESPONSE, + SENT_UPLOAD_CARD_REQUEST, + }; + + protected: + // Test will open a browser window to |test_file_path| (relative to + // components/test/data/autofill). + explicit SaveCardBubbleViewsBrowserTestBase( + const std::string& test_file_path); + ~SaveCardBubbleViewsBrowserTestBase() override; + + void SetUpCommandLine(base::CommandLine* command_line) override; + void SetUpOnMainThread() override; + + void NavigateTo(const std::string& file_path); + + // CreditCardSaveManager::ObserverForTest: + void OnOfferLocalSave() override; + void OnDecideToRequestUploadSave() override; + void OnDecideToNotRequestUploadSave() override; + void OnReceivedGetUploadDetailsResponse() override; + void OnSentUploadCardRequest() override; + + // Experiments. + void DisableRequestCvcIfMissingAndSendDetectedValuesExperiments(); + void DisableSendDetectedValuesExperiment(); + void DisableSecondaryUiMdExperiment(); + void EnableRequestCvcIfMissingExperiment(); + void EnableSecondaryUiMdExperiment(); + + // Will call JavaScript to fill and submit the form in different ways. + void FillAndSubmitForm(); + void FillAndSubmitFormWithoutCvc(); + void FillAndSubmitFormWithInvalidCvc(); + void FillAndSubmitFormWithAmexWithoutCvc(); + void FillAndSubmitFormWithoutName(); + void FillAndSubmitFormWithConflictingName(); + void FillAndSubmitFormWithoutAddress(); + void FillAndSubmitFormWithConflictingStreetAddress(); + void FillAndSubmitFormWithConflictingPostalCode(); + + // For setting up Payments RPCs. + void SetUploadDetailsRpcPaymentsAccepts(); + void SetUploadDetailsRpcPaymentsDeclines(); + void SetUploadDetailsRpcServerError(); + + // Clicks on a view from within the dialog and waits for a certain event to be + // observed. + void ClickOnDialogViewWithIdAndWait(DialogViewId view_id); + views::View* FindViewInBubbleById(DialogViewId view_id); + + // Gets the views::View* instance of the save credit card bubble. + SaveCardBubbleViews* GetSaveCardBubbleViews(); + + content::WebContents* GetActiveWebContents(); + + // Resets the event waiter for a given |event_sequence|. + void ResetEventWaiterForSequence(std::list<DialogEvent> event_sequence); + // Wait for the event(s) passed to ResetEventWaiter*() to occur. + void WaitForObservedEvent(); + + private: + std::unique_ptr<DialogEventWaiter<DialogEvent>> event_waiter_; + std::unique_ptr<net::FakeURLFetcherFactory> url_fetcher_factory_; + base::test::ScopedFeatureList scoped_feature_list_; + const std::string test_file_path_; + + // FakeGeolocation setup: + class FakeGeolocation; + std::unique_ptr<FakeGeolocation> fake_geolocation_; + std::unique_ptr<service_manager::Connector> connector_; + service_manager::BinderRegistry registry_; + + DISALLOW_COPY_AND_ASSIGN(SaveCardBubbleViewsBrowserTestBase); +}; + +} // namespace autofill + +#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_SAVE_CARD_BUBBLE_VIEWS_BROWSERTEST_BASE_H_
diff --git a/chrome/browser/ui/views/close_bubble_on_tab_activation_helper.cc b/chrome/browser/ui/views/close_bubble_on_tab_activation_helper.cc new file mode 100644 index 0000000..5d545c06 --- /dev/null +++ b/chrome/browser/ui/views/close_bubble_on_tab_activation_helper.cc
@@ -0,0 +1,32 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/close_bubble_on_tab_activation_helper.h" + +#include "chrome/browser/ui/browser.h" +#include "ui/views/bubble/bubble_dialog_delegate.h" +#include "ui/views/widget/widget.h" + +CloseBubbleOnTabActivationHelper::CloseBubbleOnTabActivationHelper( + views::BubbleDialogDelegateView* owner_bubble, + Browser* browser) + : owner_bubble_(owner_bubble), tab_strip_observer_(this) { + DCHECK(owner_bubble_); + tab_strip_observer_.Add(browser->tab_strip_model()); +} + +CloseBubbleOnTabActivationHelper::~CloseBubbleOnTabActivationHelper() = default; + +void CloseBubbleOnTabActivationHelper::ActiveTabChanged( + content::WebContents* old_contents, + content::WebContents* new_contents, + int index, + int reason) { + if (owner_bubble_) { + views::Widget* bubble_widget = owner_bubble_->GetWidget(); + if (bubble_widget) + bubble_widget->Close(); + owner_bubble_ = nullptr; + } +}
diff --git a/chrome/browser/ui/views/close_bubble_on_tab_activation_helper.h b/chrome/browser/ui/views/close_bubble_on_tab_activation_helper.h new file mode 100644 index 0000000..008df33 --- /dev/null +++ b/chrome/browser/ui/views/close_bubble_on_tab_activation_helper.h
@@ -0,0 +1,43 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_CLOSE_BUBBLE_ON_TAB_ACTIVATION_HELPER_H_ +#define CHROME_BROWSER_UI_VIEWS_CLOSE_BUBBLE_ON_TAB_ACTIVATION_HELPER_H_ + +#include "base/scoped_observer.h" +#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" + +class Browser; + +namespace views { +class BubbleDialogDelegateView; +} + +// Helper class that closes the bubble view every time the active tab changes. +// That is required as on macOS, the user may use the keyboard shortcuts to +// add, close or change the active tab. +class CloseBubbleOnTabActivationHelper : public TabStripModelObserver { + public: + // It is the expectation of this class that |bubble| and |browser| should + // outlive it. The recommended usage is for |bubble| to own |this|. + CloseBubbleOnTabActivationHelper( + views::BubbleDialogDelegateView* owner_bubble, + Browser* browser); + ~CloseBubbleOnTabActivationHelper() override; + + // TabStripModelObserver: + void ActiveTabChanged(content::WebContents* old_contents, + content::WebContents* new_contents, + int index, + int reason) override; + + private: + views::BubbleDialogDelegateView* owner_bubble_; // weak, owns me. + ScopedObserver<TabStripModel, CloseBubbleOnTabActivationHelper> + tab_strip_observer_; + + DISALLOW_COPY_AND_ASSIGN(CloseBubbleOnTabActivationHelper); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_CLOSE_BUBBLE_ON_TAB_ACTIVATION_HELPER_H_
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc index b4d83c1..3ab65d0 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -329,6 +329,7 @@ view_mode_(view_mode), gaia_service_type_(service_type), access_point_(access_point), + close_bubble_helper_(this, browser), menu_width_( signin::IsDiceEnabledForProfile(browser->profile()->GetPrefs()) ? kFixedMenuWidthDice
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.h b/chrome/browser/ui/views/profiles/profile_chooser_view.h index 23a1029..ae770a5 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.h +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.h
@@ -17,6 +17,7 @@ #include "chrome/browser/sync/sync_ui_util.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/profile_chooser_constants.h" +#include "chrome/browser/ui/views/close_bubble_on_tab_activation_helper.h" #include "components/signin/core/browser/signin_header_helper.h" #include "content/public/browser/web_contents_delegate.h" #include "google_apis/gaia/oauth2_token_service.h" @@ -225,6 +226,8 @@ // The current access point of sign in. const signin_metrics::AccessPoint access_point_; + CloseBubbleOnTabActivationHelper close_bubble_helper_; + const int menu_width_; DISALLOW_COPY_AND_ASSIGN(ProfileChooserView);
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc index cb201662..e69ae6aa 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc
@@ -14,6 +14,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/histogram_tester.h" #include "base/threading/thread_restrictions.h" +#include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/extension_browsertest.h" @@ -28,7 +29,6 @@ #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/test/test_browser_dialog.h" #include "chrome/browser/ui/user_manager.h" -#include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/profiles/profile_indicator_icon.h" #include "chrome/browser/ui/views/profiles/user_manager_view.h" #include "chrome/common/chrome_paths.h" @@ -44,6 +44,10 @@ #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/webview/webview.h" +#if !defined(OS_MACOSX) || BUILDFLAG(MAC_VIEWS_BROWSER) +#include "chrome/browser/ui/views/frame/browser_view.h" +#endif + namespace { Profile* CreateTestingProfile(const base::FilePath& path) { @@ -180,16 +184,25 @@ protected: void OpenProfileChooserView(Browser* browser) { + ProfileChooserView::close_on_deactivate_for_testing_ = false; +#if defined(OS_MACOSX) && !BUILDFLAG(MAC_VIEWS_BROWSER) + // Show the avatar bubble via API on macOS until |mac_views_browser| is + // enabled. + browser->window()->ShowAvatarBubbleFromAvatarButton( + BrowserWindow::AVATAR_BUBBLE_MODE_DEFAULT, + signin::ManageAccountsParams(), + signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN, true); +#else BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); views::View* button = browser_view->frame()->GetNewAvatarMenuButton(); if (!button) NOTREACHED() << "NewAvatarButton not found."; - ProfileChooserView::close_on_deactivate_for_testing_ = false; - ui::MouseEvent e(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0); button->OnMousePressed(e); +#endif // defined(OS_MACOSX) && !BUILDFLAG(MAC_VIEWS_BROWSER) + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(ProfileChooserView::IsShowing()); @@ -242,8 +255,17 @@ DISALLOW_COPY_AND_ASSIGN(ProfileChooserViewExtensionsTest); }; +#if !defined(OS_MACOSX) || BUILDFLAG(MAC_VIEWS_BROWSER) +#define MAYBE_NoProfileChooserOnOutsideUserDataDirProfiles \ + NoProfileChooserOnOutsideUserDataDirProfiles +#else +// Test fails on macOS as |ProfileImpl::GetSSLConfigService| is not yet +// initialized when creating the browser - see http://crbug.com/795688 . +#define MAYBE_NoProfileChooserOnOutsideUserDataDirProfiles \ + DISABLED_NoProfileChooserOnOutsideUserDataDirProfiles +#endif IN_PROC_BROWSER_TEST_F(ProfileChooserViewExtensionsTest, - NoProfileChooserOnOutsideUserDataDirProfiles) { + MAYBE_NoProfileChooserOnOutsideUserDataDirProfiles) { // Test that the profile chooser view does not show when avatar menu is not // available. This can be repro'ed with a profile path outside user_data_dir. // crbug.com/527505 @@ -387,6 +409,68 @@ UserManager::Hide(); } +// Profile chooser view should close when a tab is added. +// Regression test for http://crbug.com/792845 +IN_PROC_BROWSER_TEST_F(ProfileChooserViewExtensionsTest, + CloseBubbleOnTadAdded) { + TabStripModel* tab_strip = browser()->tab_strip_model(); + ASSERT_EQ(1, tab_strip->count()); + ASSERT_EQ(0, tab_strip->active_index()); + + ASSERT_NO_FATAL_FAILURE(OpenProfileChooserView(browser())); + AddTabAtIndex(1, GURL("https://test_url.com"), + ui::PageTransition::PAGE_TRANSITION_LINK); + EXPECT_EQ(1, tab_strip->active_index()); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(ProfileChooserView::IsShowing()); +} + +// Profile chooser view should close when active tab is changed. +// Regression test for http://crbug.com/792845 +IN_PROC_BROWSER_TEST_F(ProfileChooserViewExtensionsTest, + CloseBubbleOnActiveTabChanged) { + TabStripModel* tab_strip = browser()->tab_strip_model(); + AddTabAtIndex(1, GURL("https://test_url.com"), + ui::PageTransition::PAGE_TRANSITION_LINK); + ASSERT_EQ(2, tab_strip->count()); + ASSERT_EQ(1, tab_strip->active_index()); + + ASSERT_NO_FATAL_FAILURE(OpenProfileChooserView(browser())); + tab_strip->ActivateTabAt(0, false); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(ProfileChooserView::IsShowing()); +} + +// Profile chooser view should close when active tab is closed. +// Regression test for http://crbug.com/792845 +IN_PROC_BROWSER_TEST_F(ProfileChooserViewExtensionsTest, + CloseBubbleOnActiveTabClosed) { + TabStripModel* tab_strip = browser()->tab_strip_model(); + AddTabAtIndex(1, GURL("https://test_url.com"), + ui::PageTransition::PAGE_TRANSITION_LINK); + ASSERT_EQ(2, tab_strip->count()); + ASSERT_EQ(1, tab_strip->active_index()); + + ASSERT_NO_FATAL_FAILURE(OpenProfileChooserView(browser())); + tab_strip->CloseWebContentsAt(1, TabStripModel::CLOSE_NONE); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(ProfileChooserView::IsShowing()); +} + +// Profile chooser view should close when the last tab is closed. +// Regression test for http://crbug.com/792845 +IN_PROC_BROWSER_TEST_F(ProfileChooserViewExtensionsTest, + CloseBubbleOnLastTabClosed) { + TabStripModel* tab_strip = browser()->tab_strip_model(); + ASSERT_EQ(1, tab_strip->count()); + ASSERT_EQ(0, tab_strip->active_index()); + + ASSERT_NO_FATAL_FAILURE(OpenProfileChooserView(browser())); + tab_strip->CloseWebContentsAt(0, TabStripModel::CLOSE_NONE); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(ProfileChooserView::IsShowing()); +} + // Shows a non-signed in profile with no others. IN_PROC_BROWSER_TEST_F(ProfileChooserViewExtensionsTest, InvokeUi_default) { ShowAndVerifyUi();
diff --git a/chrome/renderer/autofill/form_autofill_browsertest.cc b/chrome/renderer/autofill/form_autofill_browsertest.cc index e328c5e..d3b35a2 100644 --- a/chrome/renderer/autofill/form_autofill_browsertest.cc +++ b/chrome/renderer/autofill/form_autofill_browsertest.cc
@@ -1153,10 +1153,9 @@ form.fields[1].is_autofilled = true; form.fields[2].is_autofilled = true; PreviewForm(form, input_element); - // Since the suggestion is previewed as a placeholder, there should be no - // selected text. - EXPECT_EQ(0, input_element.SelectionStart()); - EXPECT_EQ(0, input_element.SelectionEnd()); + // The selection should be set after the second character. + EXPECT_EQ(2, input_element.SelectionStart()); + EXPECT_EQ(2, input_element.SelectionEnd()); // Fill the form. FillForm(form, input_element); @@ -1273,10 +1272,9 @@ form.fields[2].is_autofilled = true; form.fields[3].is_autofilled = true; PreviewForm(form, input_element); - // Since the suggestion is previewed as a placeholder, there should be no - // selected text. - EXPECT_EQ(0, input_element.SelectionStart()); - EXPECT_EQ(0, input_element.SelectionEnd()); + // The selection should be set after the fifth character. + EXPECT_EQ(5, input_element.SelectionStart()); + EXPECT_EQ(5, input_element.SelectionEnd()); // Fill the form. FillForm(form, input_element); @@ -1401,10 +1399,9 @@ form.fields[1].is_autofilled = true; form.fields[2].is_autofilled = true; PreviewForm(form, input_element); - // Since the suggestion is previewed as a placeholder, there should be no - // selected text. - EXPECT_EQ(0, input_element.SelectionStart()); - EXPECT_EQ(0, input_element.SelectionEnd()); + // The selection should be set after the 19th character. + EXPECT_EQ(19, input_element.SelectionStart()); + EXPECT_EQ(19, input_element.SelectionEnd()); // Fill the form. FillForm(form, input_element);
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc index 76f845c7..f42cb81 100644 --- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc +++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -1469,9 +1469,8 @@ EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( selected_element, kAliceUsername, kAlicePassword)); CheckTextFieldsSuggestedState(kAliceUsername, true, kAlicePassword, true); - // Since the suggestion is previewed as a placeholder, there should be no - // selected text. - CheckUsernameSelection(0, 0); + // The selection should be set after the third character. + CheckUsernameSelection(3, 3); } }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 41381b0..03ca287 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -342,6 +342,7 @@ ":test_support", "//base", "//chrome/browser/profiling_host:profiling_browsertests", + "//components/grpc_support/test:quic_test_server", "//components/nacl/common:features", "//components/spellcheck:build_features", "//components/sync:test_support_model", @@ -1335,6 +1336,9 @@ "../browser/ui/views/autofill/card_unmask_prompt_view_tester_views.cc", "../browser/ui/views/autofill/card_unmask_prompt_view_tester_views.h", "../browser/ui/views/autofill/dialog_event_waiter.h", + "../browser/ui/views/autofill/save_card_bubble_views_browsertest.cc", + "../browser/ui/views/autofill/save_card_bubble_views_browsertest_base.cc", + "../browser/ui/views/autofill/save_card_bubble_views_browsertest_base.h", "../browser/ui/views/bookmarks/bookmark_bubble_view_browsertest.cc", "../browser/ui/views/bookmarks/bookmark_editor_view_browsertest.cc", "../browser/ui/views/extensions/extension_message_bubble_view_browsertest.cc", @@ -1373,6 +1377,7 @@ "../browser/ui/views/payments/profile_list_view_controller_browsertest.cc", "../browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc", "../browser/ui/views/payments/shipping_option_view_controller_browsertest.cc", + "../browser/ui/views/profiles/profile_chooser_view_browsertest.cc", "../browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog_browsertest.cc", "../browser/ui/views/select_file_dialog_extension_browsertest.cc", "../browser/ui/views/sync/profile_signin_confirmation_dialog_views_browsertest.cc", @@ -1385,7 +1390,6 @@ if (!is_chromeos && (!is_mac || mac_views_browser)) { sources += [ "../browser/ui/views/profiles/forced_reauthentication_dialog_view_browsertest.cc", - "../browser/ui/views/profiles/profile_chooser_view_browsertest.cc", "../browser/ui/views/toolbar/outdated_upgrade_bubble_view_browsertest.cc", ] } @@ -1631,6 +1635,9 @@ "../browser/profiles/profile_list_desktop_browsertest.cc", "../browser/ui/views/external_protocol_dialog_browsertest.cc", + # chromeos does not use the profile chooser view + "../browser/ui/views/profiles/profile_chooser_view_browsertest.cc", + # inline login UI is disabled on chromeos "../browser/ui/views/sync/profile_signin_confirmation_dialog_views_browsertest.cc", "../browser/ui/webui/profile_helper_browsertest.cc",
diff --git a/chrome/test/data/extensions/api_test/wallpaper_manager/test.js b/chrome/test/data/extensions/api_test/wallpaper_manager/test.js index 8b93425..9af55d2 100644 --- a/chrome/test/data/extensions/api_test/wallpaper_manager/test.js +++ b/chrome/test/data/extensions/api_test/wallpaper_manager/test.js
@@ -57,10 +57,14 @@ true, '123', pass(function(thumbnail) { - chrome.wallpaperPrivate.setCustomWallpaperLayout('CENTER', - pass(function() { - chrome.wallpaperPrivate.setCustomWallpaperLayout('STRETCH', pass()); - })); + // The current wallpaper might have not changed when |thumbnail| data is + // passed back. Allow the async setWallpaper task to finish. + setTimeout(function() { + chrome.wallpaperPrivate.setCustomWallpaperLayout( + 'CENTER', pass(function() { + chrome.wallpaperPrivate.setCustomWallpaperLayout('STRETCH', pass()); + })); + }, 500); })); }, function setCustomPngWallpaper() { @@ -75,11 +79,15 @@ true, '123', pass(function(thumbnail) { - chrome.wallpaperPrivate.setCustomWallpaperLayout('CENTER', - pass(function() { - chrome.wallpaperPrivate.setCustomWallpaperLayout('STRETCH', - pass()); - })); + // The current wallpaper might have not changed when |thumbnail| + // data is passed back. Allow the async setWallpaper task to finish. + setTimeout(function() { + chrome.wallpaperPrivate.setCustomWallpaperLayout( + 'CENTER', pass(function() { + chrome.wallpaperPrivate.setCustomWallpaperLayout( + 'STRETCH', pass()); + })); + }, 500); })); } else { chrome.test.fail('Failed to load test.png from local server.');
diff --git a/chrome/test/data/page_load_metrics/use_counter_features.html b/chrome/test/data/page_load_metrics/use_counter_features.html index a59a2b2c..6d89ab25 100644 --- a/chrome/test/data/page_load_metrics/use_counter_features.html +++ b/chrome/test/data/page_load_metrics/use_counter_features.html
@@ -2,6 +2,7 @@ <head><title>UseCounter Features Test</title></head> <body> <div id="div"></div> + <link href="data:text/css,#foo { color: red; }" rel="stylesheet"> <p id="para">TEST</p> <script type="text/javascript"> for (var i = 0; i < 3; i++) {
diff --git a/chrome/test/data/safe_browsing/dmg/generate_test_data.sh b/chrome/test/data/safe_browsing/dmg/generate_test_data.sh index df85c7b..fceec6f6d 100755 --- a/chrome/test/data/safe_browsing/dmg/generate_test_data.sh +++ b/chrome/test/data/safe_browsing/dmg/generate_test_data.sh
@@ -51,7 +51,7 @@ DMG_NAME="dmg_${DMG_TEMPLATE_FORMAT}_${layout}" hdiutil create -srcfolder "${DMG_SOURCE}" \ -format "${DMG_TEMPLATE_FORMAT}" -layout "${layout}" \ - -volname "${DMG_NAME}" \ + -fs JHFS+ -volname "${DMG_NAME}" \ "${OUT_DIR}/${DMG_NAME}" done @@ -81,7 +81,7 @@ hdiutil create -srcfolder "${DMG_SOURCE}" \ -format UDZO -layout SPUD -volname "Mach-O in DMG" -ov \ - "${OUT_DIR}/mach_o_in_dmg" + -fs JHFS+ "${OUT_DIR}/mach_o_in_dmg" rm -rf "${DMG_SOURCE}"
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index 73fb7581..cddd04a 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc
@@ -526,9 +526,9 @@ // Disables per-user timezone. const char kDisablePerUserTimezone[] = "disable-per-user-timezone"; -// Disables fine grained time zone detection. -const char kDisableFineGrainedTimeZoneDetection[] = - "disable-fine-grained-time-zone-detection"; +// Enables fine grained time zone detection. +const char kEnableFineGrainedTimeZoneDetection[] = + "enable-fine-grained-time-zone-detection"; // Disables client certificate authentication on the sign-in frame on the Chrome // OS sign-in profile.
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index 07884718..fee42cc 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h
@@ -99,7 +99,7 @@ CHROMEOS_EXPORT extern const char kEnableTouchpadThreeFingerClick[]; CHROMEOS_EXPORT extern const char kEnableFileManagerTouchMode[]; CHROMEOS_EXPORT extern const char kDisableFileManagerTouchMode[]; -CHROMEOS_EXPORT extern const char kDisableFineGrainedTimeZoneDetection[]; +CHROMEOS_EXPORT extern const char kEnableFineGrainedTimeZoneDetection[]; CHROMEOS_EXPORT extern const char kDisableSigninFrameClientCerts[]; CHROMEOS_EXPORT extern const char kDisableSigninFrameClientCertUserSelection[]; CHROMEOS_EXPORT extern const char kEnableVideoPlayerChromecastSupport[];
diff --git a/chromeos/dbus/fake_debug_daemon_client.cc b/chromeos/dbus/fake_debug_daemon_client.cc index 717fd9a..4283876 100644 --- a/chromeos/dbus/fake_debug_daemon_client.cc +++ b/chromeos/dbus/fake_debug_daemon_client.cc
@@ -209,7 +209,7 @@ const std::map<pid_t, int32_t>& pid_to_oom_score_adj, const SetOomScoreAdjCallback& callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, false, "")); + FROM_HERE, base::BindOnce(callback, true, "")); } void FakeDebugDaemonClient::SetDebuggingFeaturesStatus(int featues_mask) {
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h index 302908d7..3129f8f 100644 --- a/components/autofill/core/browser/autofill_manager.h +++ b/components/autofill/core/browser/autofill_manager.h
@@ -561,6 +561,7 @@ friend class AutofillManagerTest; friend class FormStructureBrowserTest; + friend class SaveCardBubbleViewsBrowserTestBase; FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, DeterminePossibleFieldTypesForUpload); FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest,
diff --git a/components/autofill/core/browser/credit_card_save_manager.cc b/components/autofill/core/browser/credit_card_save_manager.cc index f9b0251..0ddd6ce 100644 --- a/components/autofill/core/browser/credit_card_save_manager.cc +++ b/components/autofill/core/browser/credit_card_save_manager.cc
@@ -87,6 +87,8 @@ CreditCardSaveManager::~CreditCardSaveManager() {} void CreditCardSaveManager::OfferCardLocalSave(const CreditCard& card) { + if (observer_for_testing_) + observer_for_testing_->OnOfferLocalSave(); client_->ConfirmSaveCreditCardLocally( card, base::Bind(base::IgnoreResult( &PersonalDataManager::SaveImportedCreditCard), @@ -176,6 +178,8 @@ !IsAutofillUpstreamSendDetectedValuesExperimentEnabled()) { LogCardUploadDecisions(upload_decision_metrics_); pending_upload_request_origin_ = url::Origin(); + if (observer_for_testing_) + observer_for_testing_->OnDecideToNotRequestUploadSave(); return; } @@ -190,6 +194,8 @@ } // All required data is available, start the upload process. + if (observer_for_testing_) + observer_for_testing_->OnDecideToRequestUploadSave(); payments_client_->GetUploadDetails( upload_request_.profiles, GetDetectedValues(), base::UTF16ToASCII(CreditCard::StripSeparators(card.number())) @@ -198,9 +204,12 @@ } bool CreditCardSaveManager::IsCreditCardUploadEnabled() { - return ::autofill::IsCreditCardUploadEnabled( - client_->GetPrefs(), client_->GetSyncService(), - client_->GetIdentityProvider()->GetActiveUsername()); + // If observer_for_testing_ is set, assume we are in a browsertest and + // credit card upload should be enabled by default. + return observer_for_testing_ || + ::autofill::IsCreditCardUploadEnabled( + client_->GetPrefs(), client_->GetSyncService(), + client_->GetIdentityProvider()->GetActiveUsername()); } void CreditCardSaveManager::OnDidUploadCard( @@ -224,6 +233,8 @@ AutofillClient::PaymentsRpcResult result, const base::string16& context_token, std::unique_ptr<base::DictionaryValue> legal_message) { + if (observer_for_testing_) + observer_for_testing_->OnReceivedGetUploadDetailsResponse(); if (result == AutofillClient::SUCCESS) { // Do *not* call payments_client_->Prepare() here. We shouldn't send // credentials until the user has explicitly accepted a prompt to upload. @@ -271,6 +282,8 @@ detected_values & DetectedValue::CVC; if (!IsAutofillUpstreamSendDetectedValuesExperimentEnabled() || found_name_and_postal_code_and_cvc) { + if (observer_for_testing_) + observer_for_testing_->OnOfferLocalSave(); client_->ConfirmSaveCreditCardLocally( upload_request_.card, base::BindRepeating( @@ -495,6 +508,8 @@ } void CreditCardSaveManager::SendUploadCardRequest() { + if (observer_for_testing_) + observer_for_testing_->OnSentUploadCardRequest(); upload_request_.app_locale = app_locale_; // If the upload request does not have card CVC and the CVC fix flow is // enabled, populate it with the value provided by the user. If the CVC fix
diff --git a/components/autofill/core/browser/credit_card_save_manager.h b/components/autofill/core/browser/credit_card_save_manager.h index 973a687f..fc0897b 100644 --- a/components/autofill/core/browser/credit_card_save_manager.h +++ b/components/autofill/core/browser/credit_card_save_manager.h
@@ -56,6 +56,17 @@ HAS_GOOGLE_PAYMENTS_ACCOUNT = 1 << 8, }; + // An observer class used by browsertests that gets notified whenever + // particular actions occur. + class ObserverForTest { + public: + virtual void OnOfferLocalSave() = 0; + virtual void OnDecideToRequestUploadSave() = 0; + virtual void OnDecideToNotRequestUploadSave() = 0; + virtual void OnReceivedGetUploadDetailsResponse() = 0; + virtual void OnSentUploadCardRequest() = 0; + }; + // The parameters should outlive the CreditCardSaveManager. CreditCardSaveManager(AutofillClient* client, payments::PaymentsClient* payments_client, @@ -85,6 +96,8 @@ const std::string& server_id) override; private: + friend class SaveCardBubbleViewsBrowserTestBase; + // payments::PaymentsClientSaveDelegate: void OnDidGetUploadDetails( AutofillClient::PaymentsRpcResult result, @@ -129,6 +142,11 @@ // |AutofillMetrics::CardUploadDecisionMetric|. void LogCardUploadDecisions(int upload_decision_metrics); + // For testing. + void SetEventObserverForTesting(ObserverForTest* observer) { + observer_for_testing_ = observer; + } + AutofillClient* const client_; // Handles Payments service requests. @@ -171,6 +189,9 @@ // The origin of the top level frame from which a form is uploaded. url::Origin pending_upload_request_origin_; + // May be null. + ObserverForTest* observer_for_testing_ = nullptr; + base::WeakPtrFactory<CreditCardSaveManager> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(CreditCardSaveManager);
diff --git a/components/autofill/core/browser/form_data_importer.h b/components/autofill/core/browser/form_data_importer.h index e79e951..68cb8bd8 100644 --- a/components/autofill/core/browser/form_data_importer.h +++ b/components/autofill/core/browser/form_data_importer.h
@@ -118,6 +118,7 @@ friend class AutofillMergeTest; friend class FormDataImporterTest; friend class FormDataImporterTestBase; + friend class SaveCardBubbleViewsBrowserTestBase; FRIEND_TEST_ALL_PREFIXES(AutofillMergeTest, MergeProfiles); FRIEND_TEST_ALL_PREFIXES(FormDataImporterTest, AllowDuplicateMaskedServerCardIfFlagEnabled);
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/NQETest.java b/components/cronet/android/test/javatests/src/org/chromium/net/NQETest.java index 0918c8c..007a89fa 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/NQETest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/NQETest.java
@@ -23,6 +23,7 @@ import org.chromium.base.Log; import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.MetricsUtils.HistogramDelta; import org.chromium.net.CronetTestRule.OnlyRunNativeCronet; @@ -163,6 +164,7 @@ @SmallTest @Feature({"Cronet"}) @OnlyRunNativeCronet + @DisabledTest(message = "crbug.com/796260") public void testQuicDisabled() throws Exception { ExperimentalCronetEngine.Builder cronetEngineBuilder = new ExperimentalCronetEngine.Builder(getContext()); @@ -353,6 +355,7 @@ @SmallTest @Feature({"Cronet"}) @OnlyRunNativeCronet + @DisabledTest(message = "crbug.com/796260") public void testQuicDisabledWithParams() throws Exception { ExperimentalCronetEngine.Builder cronetEngineBuilder = new ExperimentalCronetEngine.Builder(getContext());
diff --git a/components/grpc_support/test/quic_test_server.cc b/components/grpc_support/test/quic_test_server.cc index 1d2ad5b..ef1ffce 100644 --- a/components/grpc_support/test/quic_test_server.cc +++ b/components/grpc_support/test/quic_test_server.cc
@@ -83,10 +83,9 @@ directory = test_files_root; std::unique_ptr<net::ProofSourceChromium> proof_source( new net::ProofSourceChromium()); - CHECK(proof_source->Initialize( - directory.AppendASCII("quic_test.example.com.crt"), - directory.AppendASCII("quic_test.example.com.key.pkcs8"), - directory.AppendASCII("quic_test.example.com.key.sct"))); + CHECK(proof_source->Initialize(directory.AppendASCII("quic-chain.pem"), + directory.AppendASCII("quic-cert.key"), + base::FilePath())); SetupQuicHttpResponseCache(); g_quic_server = new net::QuicSimpleServer(
diff --git a/components/grpc_support/test/quic_test_server.h b/components/grpc_support/test/quic_test_server.h index 46ac331..81e0306 100644 --- a/components/grpc_support/test/quic_test_server.h +++ b/components/grpc_support/test/quic_test_server.h
@@ -21,6 +21,7 @@ extern const char kStatusHeader[]; +extern const char kHelloPath[]; extern const char kHelloBodyValue[]; extern const char kHelloStatus[];
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 02e1afe..ca8b008 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -8653,7 +8653,7 @@ 'id': 361, 'caption': '''Maximum SSL version enabled''', 'tags': ['system-security'], - 'desc': '''Warning: The max TLS version policy will be entirely removed from <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> around version 66 (around February 2018). + 'desc': '''Warning: The max TLS version policy will be entirely removed from <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> around version 72 (around January 2019). If this policy is not configured then <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> uses the default maximum version.
diff --git a/components/search_engines/prepopulated_engines.json b/components/search_engines/prepopulated_engines.json index 002b6c0..5127a1a1 100644 --- a/components/search_engines/prepopulated_engines.json +++ b/components/search_engines/prepopulated_engines.json
@@ -32,7 +32,7 @@ // Increment this if you change the data in ways that mean users with // existing data should get a new version. - "kCurrentDataVersion": 99 + "kCurrentDataVersion": 100 }, // The following engines are included in country lists and are added to the @@ -48,11 +48,13 @@ "id": 35 }, + // Ask and Ask UK have suggestion URLs reachable over HTTPS, but they + // throw a certificate error, so those will remain as HTTP for now. "ask": { "name": "Ask", "keyword": "ask.com", - "favicon_url": "http://sp.ask.com/sh/i/a16/favicon/favicon.ico", - "search_url": "http://www.ask.com/web?q={searchTerms}", + "favicon_url": "https://sp.ask.com/sh/i/a16/favicon/favicon.ico", + "search_url": "https://www.ask.com/web?q={searchTerms}", "suggest_url": "http://ss.ask.com/query?q={searchTerms}&li=ff", "type": "SEARCH_ENGINE_ASK", "id": 4 @@ -61,8 +63,8 @@ "ask_br": { "name": "Ask Brasil", "keyword": "br.ask.com", - "favicon_url": "http://sp.br.ask.com/sh/i/a14/favicon/favicon.ico", - "search_url": "http://br.ask.com/web?q={searchTerms}", + "favicon_url": "https://sp.br.ask.com/sh/i/a14/favicon/favicon.ico", + "search_url": "https://br.ask.com/web?q={searchTerms}", "type": "SEARCH_ENGINE_ASK", "id": 4 }, @@ -70,13 +72,15 @@ "ask_uk": { "name": "Ask Jeeves", "keyword": "uk.ask.com", - "favicon_url": "http://sp.uk.ask.com/sh/i/a16/favicon/favicon.ico", - "search_url": "http://uk.ask.com/web?q={searchTerms}", + "favicon_url": "https://sp.uk.ask.com/sh/i/a16/favicon/favicon.ico", + "search_url": "https://uk.ask.com/web?q={searchTerms}", "suggest_url": "http://ss.uk.ask.com/query?q={searchTerms}&li=ff", "type": "SEARCH_ENGINE_ASK", "id": 4 }, + // Baidu's suggestion URL is not reachable over HTTPS, so it remains as + // HTTP for now. "baidu": { "name": "\u767e\u5ea6", "keyword": "baidu.com", @@ -103,9 +107,9 @@ "daum": { "name": "Daum", "keyword": "daum.net", - "favicon_url": "http://search.daum.net/favicon.ico", - "search_url": "http://search.daum.net/search?ie={inputEncoding}&q={searchTerms}", - "suggest_url": "http://sug.search.daum.net/search_nsuggest?mod=fxjson&ie={inputEncoding}&code=utf_in_out&q={searchTerms}", + "favicon_url": "https://search.daum.net/favicon.ico", + "search_url": "https://search.daum.net/search?ie={inputEncoding}&q={searchTerms}", + "suggest_url": "https://sug.search.daum.net/search_nsuggest?mod=fxjson&ie={inputEncoding}&code=utf_in_out&q={searchTerms}", "type": "SEARCH_ENGINE_DAUM", "id": 68 }, @@ -173,8 +177,8 @@ "onet": { "name": "Onet.pl", "keyword": "onet.pl", - "favicon_url": "http://szukaj.onet.pl/favicon.ico", - "search_url": "http://szukaj.onet.pl/wyniki.html?qt={searchTerms}", + "favicon_url": "https://szukaj.onet.pl/favicon.ico", + "search_url": "https://szukaj.onet.pl/wyniki.html?qt={searchTerms}", "type": "SEARCH_ENGINE_ONET", "id": 75 }, @@ -665,8 +669,11 @@ "atlas_cz": { "name": "Atlas.cz", "keyword": "atlas.cz", - "favicon_url": "http://searchatlas.centrum.cz/favicon.ico", - "search_url": "http://searchatlas.centrum.cz/?q={searchTerms}", + "favicon_url": "https://searchatlas.centrum.cz/favicon.ico", + "search_url": "https://searchatlas.centrum.cz/?q={searchTerms}", + "alternate_urls": [ + "http://searchatlas.centrum.cz/?q={searchTerms}" + ], "suggest_url": "http://radce.centrum.cz/?q={searchTerms}&of=1", "type": "SEARCH_ENGINE_ATLAS", "id": 27 @@ -676,7 +683,10 @@ "name": "ATLAS.SK", "keyword": "atlas.sk", "favicon_url": "http://static.mediacentrum.sk/katalog/atlas.sk/images/favicon.ico", - "search_url": "http://hladaj.atlas.sk/fulltext/?phrase={searchTerms}", + "search_url": "https://hladaj.atlas.sk/fulltext/?phrase={searchTerms}", + "alternate_urls": [ + "http://hladaj.atlas.sk/fulltext/?phrase={searchTerms}" + ], "id": 27 }, @@ -722,8 +732,11 @@ "delfi_lt": { "name": "DELFI", "keyword": "delfi.lt", - "favicon_url": "http://www.delfi.lt/favicon.ico", - "search_url": "http://www.delfi.lt/paieska/?q={searchTerms}", + "favicon_url": "https://www.delfi.lt/favicon.ico", + "search_url": "https://www.delfi.lt/paieska/?q={searchTerms}", + "alternate_urls": [ + "http://www.delfi.lt/paieska/?q={searchTerms}" + ], "type": "SEARCH_ENGINE_DELFI", "id": 45 }, @@ -1039,8 +1052,11 @@ "zoznam": { "name": "Zoznam", "keyword": "zoznam.sk", - "favicon_url": "http://www.zoznam.sk/favicon.ico", - "search_url": "http://www.zoznam.sk/hladaj.fcgi?s={searchTerms}", + "favicon_url": "https://www.zoznam.sk/favicon.ico", + "search_url": "https://www.zoznam.sk/hladaj.fcgi?s={searchTerms}", + "alternate_urls": [ + "http://www.zoznam.sk/hladaj.fcgi?s={searchTerms}" + ], "encoding": "windows-1250", "type": "SEARCH_ENGINE_ZOZNAM", "id": 85
diff --git a/components/test/data/autofill/credit_card_upload_done.html b/components/test/data/autofill/credit_card_upload_done.html new file mode 100644 index 0000000..499b45f --- /dev/null +++ b/components/test/data/autofill/credit_card_upload_done.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> +<!-- +Copyright 2017 The Chromium Authors. All rights reserved. +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> +<html> +<head> +<title>Credit Card Upload Test - Form submission landing page</title> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> +</head> +<body> + Done! +</body> +</html>
diff --git a/components/test/data/autofill/credit_card_upload_form_address_and_cc.html b/components/test/data/autofill/credit_card_upload_form_address_and_cc.html new file mode 100644 index 0000000..8c988d3 --- /dev/null +++ b/components/test/data/autofill/credit_card_upload_form_address_and_cc.html
@@ -0,0 +1,94 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> +<!-- +Copyright 2017 The Chromium Authors. All rights reserved. +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> +<html> +<head> +<title>Credit Card Upload Test - Form with address and credit card</title> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> +</head> +<body> + <form id="checkout" name="checkout" action="/credit_card_upload_done.html" method="post"> + <div>Name: <input type="text" name="name_address" autocomplete="name"></div> + <div>Address: <input type="text" name="address" autocomplete="address-line1"></div> + <div>City: <input type="text" name="city" autocomplete="address-level2"></div> + <div>State: <input type="text" name="state" autocomplete="address-level1"></div> + <div>Zip: <input type="text" name="zip" autocomplete="postal-code"></div> + <div>Country: <input type="text" name="country" autocomplete="country-name"></div> + <hr> + <div>Name on card: <input type="text" name="name_cc" autocomplete="cc-name"></div> + <div>Credit card number: <input type="text" name="cc_number" autocomplete="cc-number"></div> + <div>Expiry Date: + <input type="text" name="cc_month_exp" placeholder="MM" autocomplete="cc-exp-month"> + / + <input type="text" name="cc_year_exp" placeholder="YYYY" autocomplete="cc-exp-year"></div> + <div>CVC: <input name="cc_cvc" autocomplete="cc-csc"></div> + <hr> + <button id="fill_form" type="button">Fill entire form with default (MasterCard) values</button> + <button id="fill_form_amex" type="button">Fill entire form, but with AMEX CC values</button> + <button id="fill_invalid_cvc" type="button">Fill the CVC field with an invalid value</button> + <button id="clear_cvc" type="button">Clear the CVC field</button> + <button id="clear_name" type="button">Clear the name fields</button> + <button id="clear_address" type="button">Clear the address fields</button> + <button id="submit" type="submit">Submit</button> + </form> +<script type="text/javascript"> + document.getElementById("fill_form").addEventListener( + "click", + function() { + document.getElementsByName("name_address")[0].value = "John Smith"; + document.getElementsByName("address")[0].value = "123 Testing St."; + document.getElementsByName("city")[0].value = "Mountain View"; + document.getElementsByName("state")[0].value = "California"; + document.getElementsByName("zip")[0].value = "94043"; + document.getElementsByName("country")[0].value = "US"; + document.getElementsByName("name_cc")[0].value = "John Smith"; + document.getElementsByName("cc_number")[0].value = "5454545454545454"; + document.getElementsByName("cc_month_exp")[0].value = "12"; + document.getElementsByName("cc_year_exp")[0].value = "2023"; + document.getElementsByName("cc_cvc")[0].value = "123"; + }); + + document.getElementById("fill_form_amex").addEventListener( + "click", + function() { + document.getElementById("fill_form").click(); + document.getElementsByName("cc_number")[0].value = "378282246310005"; + document.getElementsByName("cc_cvc")[0].value = "1234"; + }); + + document.getElementById("fill_invalid_cvc").addEventListener( + "click", + function() { + document.getElementsByName("cc_cvc")[0].value = "12345"; + }); + + document.getElementById("clear_cvc").addEventListener( + "click", + function() { + document.getElementsByName("cc_cvc")[0].value = ""; + }); + + document.getElementById("clear_name").addEventListener( + "click", + function() { + document.getElementsByName("name_address")[0].value = ""; + document.getElementsByName("name_cc")[0].value = ""; + }); + + document.getElementById("clear_address").addEventListener( + "click", + function() { + document.getElementsByName("name_address")[0].value = ""; + document.getElementsByName("address")[0].value = ""; + document.getElementsByName("city")[0].value = ""; + document.getElementsByName("state")[0].value = ""; + document.getElementsByName("zip")[0].value = ""; + document.getElementsByName("country")[0].value = ""; + }); +</script> +</body> +</html>
diff --git a/components/test/data/autofill/credit_card_upload_form_shipping_address.html b/components/test/data/autofill/credit_card_upload_form_shipping_address.html new file mode 100644 index 0000000..c1b6598 --- /dev/null +++ b/components/test/data/autofill/credit_card_upload_form_shipping_address.html
@@ -0,0 +1,61 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> +<!-- +Copyright 2017 The Chromium Authors. All rights reserved. +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> +<html> +<head> +<title>Credit Card Upload Test - Form with shipping address, leads to credit card form</title> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> +</head> +<body> + <form id="checkout" name="checkout" action="/credit_card_upload_form_address_and_cc.html" method="post"> + <div>Name: <input type="text" name="name_address" autocomplete="name"></div> + <div>Address: <input type="text" name="address" autocomplete="address-line1"></div> + <div>City: <input type="text" name="city" autocomplete="address-level2"></div> + <div>State: <input type="text" name="state" autocomplete="address-level1"></div> + <div>Zip: <input type="text" name="zip" autocomplete="postal-code"></div> + <div>Country: <input type="text" name="country" autocomplete="country-name"></div> + <hr> + <button id="fill_form" type="button">Fill entire form with default values</button> + <button id="conflicting_name" type="button">Fill a different name than the next form</button> + <button id="conflicting_street_address" type="button">Fill a different street address than the next form</button> + <button id="conflicting_postal_code" type="button">Fill a different postal code than the next form</button> + <button id="submit" type="submit">Submit</button> + </form> +<script type="text/javascript"> + document.getElementById("fill_form").addEventListener( + "click", + function() { + document.getElementsByName("name_address")[0].value = "John Smith"; + document.getElementsByName("address")[0].value = "123 Testing St."; + document.getElementsByName("city")[0].value = "Mountain View"; + document.getElementsByName("state")[0].value = "California"; + document.getElementsByName("zip")[0].value = "94043"; + document.getElementsByName("country")[0].value = "US"; + }); + + document.getElementById("conflicting_name").addEventListener( + "click", + function() { + document.getElementsByName("name_address")[0].value = "Chrome Guy"; + }); + + document.getElementById("conflicting_street_address").addEventListener( + "click", + function() { + document.getElementsByName("address")[0].value = "456 Chromium Ave."; + }); + + document.getElementById("conflicting_postal_code").addEventListener( + "click", + function() { + document.getElementsByName("address")[0].value = "456 Chromium Ave."; + document.getElementsByName("city")[0].value = "San Francisco"; + document.getElementsByName("zip")[0].value = "94105"; + }); +</script> +</body> +</html>
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn index 3451065..e92cc15a 100644 --- a/components/viz/common/BUILD.gn +++ b/components/viz/common/BUILD.gn
@@ -155,6 +155,7 @@ "//gpu", "//gpu/command_buffer/client:gles2_implementation", "//gpu/command_buffer/client:gles2_interface", + "//gpu/command_buffer/common:gles2_utils", "//gpu/command_buffer/service", "//gpu/ipc:gl_in_process_context", "//gpu/skia_bindings:skia_bindings",
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index 2505020..1e632db 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -1135,9 +1135,9 @@ GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon"); return base::MakeRefCounted<ui::ContextProviderCommandBuffer>( - std::move(gpu_channel_host), stream_id, stream_priority, surface_handle, - url, automatic_flushes, support_locking, gpu::SharedMemoryLimits(), - attributes, shared_context_provider, type); + std::move(gpu_channel_host), GetGpuMemoryBufferManager(), stream_id, + stream_priority, surface_handle, url, automatic_flushes, support_locking, + gpu::SharedMemoryLimits(), attributes, shared_context_provider, type); } } // namespace content
diff --git a/content/browser/compositor/software_browser_compositor_output_surface.cc b/content/browser/compositor/software_browser_compositor_output_surface.cc index b805b8b..d402e04ae 100644 --- a/content/browser/compositor/software_browser_compositor_output_surface.cc +++ b/content/browser/compositor/software_browser_compositor_output_surface.cc
@@ -132,7 +132,7 @@ return false; } -GLenum +uint32_t SoftwareBrowserCompositorOutputSurface::GetFramebufferCopyTextureFormat() { // Not used for software surfaces. NOTREACHED();
diff --git a/content/browser/compositor/viz_process_transport_factory.cc b/content/browser/compositor/viz_process_transport_factory.cc index ebfa9e5..8bfdd5a 100644 --- a/content/browser/compositor/viz_process_transport_factory.cc +++ b/content/browser/compositor/viz_process_transport_factory.cc
@@ -43,6 +43,7 @@ scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextProviderImpl( scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, bool support_locking, bool support_gles2_interface, bool support_raster_interface, @@ -64,10 +65,10 @@ GURL url("chrome://gpu/VizProcessTransportFactory::CreateContextProvider"); return base::MakeRefCounted<ui::ContextProviderCommandBuffer>( - std::move(gpu_channel_host), kGpuStreamIdDefault, kGpuStreamPriorityUI, - gpu::kNullSurfaceHandle, std::move(url), kAutomaticFlushes, - support_locking, gpu::SharedMemoryLimits(), attributes, - shared_context_provider, type); + std::move(gpu_channel_host), gpu_memory_buffer_manager, + kGpuStreamIdDefault, kGpuStreamPriorityUI, gpu::kNullSurfaceHandle, + std::move(url), kAutomaticFlushes, support_locking, + gpu::SharedMemoryLimits(), attributes, shared_context_provider, type); } bool CheckContextLost(viz::ContextProvider* context_provider) { @@ -496,9 +497,10 @@ if (!shared_worker_context_provider_) { shared_worker_context_provider_ = CreateContextProviderImpl( - gpu_channel_host, kSharedWorkerContextSupportsLocking, - kSharedWorkerContextSupportsGLES2, kSharedWorkerContextSupportsRaster, - nullptr, ui::command_buffer_metrics::BROWSER_WORKER_CONTEXT); + gpu_channel_host, GetGpuMemoryBufferManager(), + kSharedWorkerContextSupportsLocking, kSharedWorkerContextSupportsGLES2, + kSharedWorkerContextSupportsRaster, nullptr, + ui::command_buffer_metrics::BROWSER_WORKER_CONTEXT); auto result = shared_worker_context_provider_->BindToCurrentThread(); if (result != gpu::ContextResult::kSuccess) { @@ -509,9 +511,9 @@ if (!compositor_context_provider_) { compositor_context_provider_ = CreateContextProviderImpl( - std::move(gpu_channel_host), kCompositorContextSupportsLocking, - kCompositorContextSupportsGLES2, kCompositorContextSupportsRaster, - shared_worker_context_provider_.get(), + std::move(gpu_channel_host), GetGpuMemoryBufferManager(), + kCompositorContextSupportsLocking, kCompositorContextSupportsGLES2, + kCompositorContextSupportsRaster, shared_worker_context_provider_.get(), ui::command_buffer_metrics::UI_COMPOSITOR_CONTEXT); compositor_context_provider_->SetDefaultTaskRunner(resize_task_runner_);
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc index 27d51327..e76727b 100644 --- a/content/browser/gpu/browser_gpu_channel_host_factory.cc +++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -46,10 +46,8 @@ class BrowserGpuChannelHostFactory::EstablishRequest : public base::RefCountedThreadSafe<EstablishRequest> { public: - static scoped_refptr<EstablishRequest> Create( - int gpu_client_id, - uint64_t gpu_client_tracing_id, - BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager); + static scoped_refptr<EstablishRequest> Create(int gpu_client_id, + uint64_t gpu_client_tracing_id); void Wait(); void Cancel(); @@ -59,9 +57,7 @@ private: friend class base::RefCountedThreadSafe<EstablishRequest>; - EstablishRequest(int gpu_client_id, - uint64_t gpu_client_tracing_id, - BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager); + EstablishRequest(int gpu_client_id, uint64_t gpu_client_tracing_id); ~EstablishRequest() {} void RestartTimeout(); void EstablishOnIO(); @@ -75,7 +71,6 @@ base::WaitableEvent event_; const int gpu_client_id_; const uint64_t gpu_client_tracing_id_; - BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager_; scoped_refptr<gpu::GpuChannelHost> gpu_channel_; bool finished_; scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; @@ -84,10 +79,9 @@ scoped_refptr<BrowserGpuChannelHostFactory::EstablishRequest> BrowserGpuChannelHostFactory::EstablishRequest::Create( int gpu_client_id, - uint64_t gpu_client_tracing_id, - BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager) { - scoped_refptr<EstablishRequest> establish_request = new EstablishRequest( - gpu_client_id, gpu_client_tracing_id, gpu_memory_buffer_manager); + uint64_t gpu_client_tracing_id) { + scoped_refptr<EstablishRequest> establish_request = + new EstablishRequest(gpu_client_id, gpu_client_tracing_id); // PostTask outside the constructor to ensure at least one reference exists. BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, @@ -99,13 +93,11 @@ BrowserGpuChannelHostFactory::EstablishRequest::EstablishRequest( int gpu_client_id, - uint64_t gpu_client_tracing_id, - BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager) + uint64_t gpu_client_tracing_id) : event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED), gpu_client_id_(gpu_client_id), gpu_client_tracing_id_(gpu_client_tracing_id), - gpu_memory_buffer_manager_(gpu_memory_buffer_manager), finished_(false), main_task_runner_(base::ThreadTaskRunnerHandle::Get()) {} @@ -156,16 +148,8 @@ } if (channel_handle.is_valid()) { - // Note: We may get here after the BrowserGpuChannelHostFactory is destroyed - // on the UI thread, in which case gpu_memory_buffer_manager_ could be - // stale. However GpuChannelHost doesn't dereference it, and it only gets - // used by CommandBufferProxyImpl after we returned the GpuChannelHost on - // the UI thread, which we won't if indeed BrowserGpuChannelHostFactory was - // destroyed. - // TODO(piman): clean this. gpu_channel_ = base::MakeRefCounted<gpu::GpuChannelHost>( - gpu_client_id_, gpu_info, gpu_feature_info, std::move(channel_handle), - gpu_memory_buffer_manager_); + gpu_client_id_, gpu_info, gpu_feature_info, std::move(channel_handle)); } FinishOnIO(); } @@ -277,8 +261,7 @@ if (!gpu_channel_.get() && !pending_request_.get()) { // We should only get here if the context was lost. pending_request_ = - EstablishRequest::Create(gpu_client_id_, gpu_client_tracing_id_, - gpu_memory_buffer_manager_.get()); + EstablishRequest::Create(gpu_client_id_, gpu_client_tracing_id_); RestartTimeout(); }
diff --git a/content/browser/gpu/gpu_ipc_browsertests.cc b/content/browser/gpu/gpu_ipc_browsertests.cc index 485dd27..c25e2426 100644 --- a/content/browser/gpu/gpu_ipc_browsertests.cc +++ b/content/browser/gpu/gpu_ipc_browsertests.cc
@@ -29,6 +29,8 @@ scoped_refptr<ui::ContextProviderCommandBuffer> CreateContext( scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) { + gpu::GpuChannelEstablishFactory* factory = + content::BrowserMainLoop::GetInstance()->gpu_channel_establish_factory(); // This is for an offscreen context, so the default framebuffer doesn't need // any alpha, depth, stencil, antialiasing. gpu::gles2::ContextCreationAttribHelper attributes; @@ -41,10 +43,11 @@ constexpr bool automatic_flushes = false; constexpr bool support_locking = false; return base::MakeRefCounted<ui::ContextProviderCommandBuffer>( - std::move(gpu_channel_host), content::kGpuStreamIdDefault, - content::kGpuStreamPriorityDefault, gpu::kNullSurfaceHandle, GURL(), - automatic_flushes, support_locking, gpu::SharedMemoryLimits(), attributes, - nullptr, ui::command_buffer_metrics::OFFSCREEN_CONTEXT_FOR_TESTING); + std::move(gpu_channel_host), factory->GetGpuMemoryBufferManager(), + content::kGpuStreamIdDefault, content::kGpuStreamPriorityDefault, + gpu::kNullSurfaceHandle, GURL(), automatic_flushes, support_locking, + gpu::SharedMemoryLimits(), attributes, nullptr, + ui::command_buffer_metrics::OFFSCREEN_CONTEXT_FOR_TESTING); } void OnEstablishedGpuChannel( @@ -326,8 +329,8 @@ attributes.bind_generates_resource = false; auto impl = std::make_unique<gpu::CommandBufferProxyImpl>( - GetGpuChannel(), content::kGpuStreamIdDefault, - base::ThreadTaskRunnerHandle::Get()); + GetGpuChannel(), GetFactory()->GetGpuMemoryBufferManager(), + content::kGpuStreamIdDefault, base::ThreadTaskRunnerHandle::Get()); ASSERT_EQ( impl->Initialize(gpu::kNullSurfaceHandle, nullptr, content::kGpuStreamPriorityDefault, attributes, GURL()),
diff --git a/content/browser/media/media_interface_proxy.cc b/content/browser/media/media_interface_proxy.cc index 3513a992..0584b24 100644 --- a/content/browser/media/media_interface_proxy.cc +++ b/content/browser/media/media_interface_proxy.cc
@@ -172,6 +172,11 @@ factory->CreateCdm(key_system, std::move(request)); } +void MediaInterfaceProxy::CreateCdmProxy( + media::mojom::CdmProxyRequest request) { + NOTREACHED() << "The CdmProxy should only be created by a CDM."; +} + service_manager::mojom::InterfaceProviderPtr MediaInterfaceProxy::GetFrameServices(const std::string& cdm_file_system_id) { // Register frame services. @@ -188,13 +193,19 @@ BrowserContext::GetDefaultStoragePartition( render_frame_host_->GetProcess()->GetBrowserContext()) ->GetURLRequestContext(); - provider->registry()->AddInterface(base::Bind( + provider->registry()->AddInterface(base::BindRepeating( &ProvisionFetcherImpl::Create, base::RetainedRef(context_getter))); #if BUILDFLAG(ENABLE_LIBRARY_CDMS) - DCHECK(!cdm_file_system_id.empty()); - provider->registry()->AddInterface(base::Bind( - &CdmStorageImpl::Create, render_frame_host_, cdm_file_system_id)); + // Only provide CdmStorageImpl when we have a valid |cdm_file_system_id|, + // which is currently only set for the CdmService (not the MediaService). + if (!cdm_file_system_id.empty()) { + provider->registry()->AddInterface(base::BindRepeating( + &CdmStorageImpl::Create, render_frame_host_, cdm_file_system_id)); + } + + provider->registry()->AddInterface(base::BindRepeating( + &MediaInterfaceProxy::CreateCdmProxyInternal, base::Unretained(this))); #endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) #endif // BUILDFLAG(ENABLE_MOJO_CDM) @@ -353,7 +364,18 @@ DCHECK(cdm_interface_factory_map_.count(cdm_guid)); cdm_interface_factory_map_.erase(cdm_guid); } - #endif // BUILDFLAG(ENABLE_STANDALONE_CDM_SERVICE) +#if BUILDFLAG(ENABLE_LIBRARY_CDMS) +void MediaInterfaceProxy::CreateCdmProxyInternal( + media::mojom::CdmProxyRequest request) { + DVLOG(1) << __func__; + DCHECK(thread_checker_.CalledOnValidThread()); + + InterfaceFactory* factory = GetMediaInterfaceFactory(); + if (factory) + factory->CreateCdmProxy(std::move(request)); +} +#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) + } // namespace content
diff --git a/content/browser/media/media_interface_proxy.h b/content/browser/media/media_interface_proxy.h index b26c760..3ee6e43 100644 --- a/content/browser/media/media_interface_proxy.h +++ b/content/browser/media/media_interface_proxy.h
@@ -48,6 +48,7 @@ media::mojom::RendererRequest request) final; void CreateCdm(const std::string& key_system, media::mojom::ContentDecryptionModuleRequest request) final; + void CreateCdmProxy(media::mojom::CdmProxyRequest request) final; private: using InterfaceFactoryPtr = media::mojom::InterfaceFactoryPtr; @@ -87,6 +88,13 @@ void OnCdmServiceConnectionError(const std::string& cdm_guid); #endif // BUILDFLAG(ENABLE_STANDALONE_CDM_SERVICE) +#if BUILDFLAG(ENABLE_LIBRARY_CDMS) + // Creates a CdmProxy for the CDM in CdmService. Not implemented in + // CreateCdmProxy() because we don't want any client to be able to create + // a CdmProxy. + void CreateCdmProxyInternal(media::mojom::CdmProxyRequest request); +#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) + // Safe to hold a raw pointer since |this| is owned by RenderFrameHostImpl. RenderFrameHost* const render_frame_host_;
diff --git a/content/browser/payments/payment_app_database.cc b/content/browser/payments/payment_app_database.cc index abc3d6c..efa443d 100644 --- a/content/browser/payments/payment_app_database.cc +++ b/content/browser/payments/payment_app_database.cc
@@ -249,8 +249,7 @@ FetchAndWritePaymentAppInfoCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - payment_app_info_fetcher_ = new PaymentAppInfoFetcher(); - payment_app_info_fetcher_->Start( + PaymentAppInfoFetcher::Start( context, service_worker_context_, base::BindOnce(&PaymentAppDatabase::FetchPaymentAppInfoCallback, weak_ptr_factory_.GetWeakPtr(), scope, user_hint, @@ -264,8 +263,6 @@ std::unique_ptr<PaymentAppInfoFetcher::PaymentAppInfo> app_info) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - payment_app_info_fetcher_ = nullptr; - service_worker_context_->FindReadyRegistrationForPattern( scope, base::Bind(&PaymentAppDatabase::DidFindRegistrationToWritePaymentAppInfo,
diff --git a/content/browser/payments/payment_app_database.h b/content/browser/payments/payment_app_database.h index 06152a9e..d70d1c3 100644 --- a/content/browser/payments/payment_app_database.h +++ b/content/browser/payments/payment_app_database.h
@@ -193,7 +193,6 @@ ServiceWorkerStatusCode status); void DidSetPaymentAppUserHint(ServiceWorkerStatusCode status); - scoped_refptr<PaymentAppInfoFetcher> payment_app_info_fetcher_; scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_; base::WeakPtrFactory<PaymentAppDatabase> weak_ptr_factory_;
diff --git a/content/browser/payments/payment_app_info_fetcher.cc b/content/browser/payments/payment_app_info_fetcher.cc index b57e83b..70b57b1 100644 --- a/content/browser/payments/payment_app_info_fetcher.cc +++ b/content/browser/payments/payment_app_info_fetcher.cc
@@ -17,9 +17,6 @@ namespace content { -PaymentAppInfoFetcher::PaymentAppInfoFetcher() - : fetched_payment_app_info_(std::make_unique<PaymentAppInfo>()) {} - PaymentAppInfoFetcher::PaymentAppInfo::PaymentAppInfo() {} PaymentAppInfoFetcher::PaymentAppInfo::~PaymentAppInfo() {} @@ -30,32 +27,53 @@ PaymentAppInfoFetchCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - context_url_ = context_url; - callback_ = std::move(callback); - std::unique_ptr<std::vector<std::pair<int, int>>> provider_hosts = service_worker_context->GetProviderHostIds(context_url.GetOrigin()); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::BindOnce(&PaymentAppInfoFetcher::StartFromUIThread, this, - std::move(provider_hosts))); + base::BindOnce(&PaymentAppInfoFetcher::StartOnUI, context_url, + std::move(provider_hosts), std::move(callback))); +} + +void PaymentAppInfoFetcher::StartOnUI( + const GURL& context_url, + const std::unique_ptr<std::vector<std::pair<int, int>>>& provider_hosts, + PaymentAppInfoFetchCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + SelfDeleteFetcher* fetcher = new SelfDeleteFetcher(std::move(callback)); + fetcher->Start(context_url, std::move(provider_hosts)); } PaymentAppInfoFetcher::WebContentsHelper::WebContentsHelper( WebContents* web_contents) - : WebContentsObserver(web_contents) {} + : WebContentsObserver(web_contents) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); +} -PaymentAppInfoFetcher::WebContentsHelper::~WebContentsHelper() {} +PaymentAppInfoFetcher::WebContentsHelper::~WebContentsHelper() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); +} -PaymentAppInfoFetcher::~PaymentAppInfoFetcher() {} +PaymentAppInfoFetcher::SelfDeleteFetcher::SelfDeleteFetcher( + PaymentAppInfoFetchCallback callback) + : fetched_payment_app_info_(std::make_unique<PaymentAppInfo>()), + callback_(std::move(callback)) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); +} -void PaymentAppInfoFetcher::StartFromUIThread( +PaymentAppInfoFetcher::SelfDeleteFetcher::~SelfDeleteFetcher() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); +} + +void PaymentAppInfoFetcher::SelfDeleteFetcher::Start( + const GURL& context_url, const std::unique_ptr<std::vector<std::pair<int, int>>>& provider_hosts) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (provider_hosts->size() == 0U) { - PostPaymentAppInfoFetchResultToIOThread(); + RunCallbackAndDestroy(); return; } @@ -68,22 +86,33 @@ WebContentsImpl* web_content = static_cast<WebContentsImpl*>( WebContents::FromRenderFrameHost(render_frame_host)); if (!web_content || web_content->IsHidden() || - context_url_.spec().compare( - web_content->GetLastCommittedURL().spec()) != 0) { + context_url.spec().compare(web_content->GetLastCommittedURL().spec()) != + 0) { continue; } web_contents_helper_ = std::make_unique<WebContentsHelper>(web_content); - web_content->GetManifest(base::Bind( - &PaymentAppInfoFetcher::FetchPaymentAppManifestCallback, this)); + web_content->GetManifest( + base::Bind(&PaymentAppInfoFetcher::SelfDeleteFetcher:: + FetchPaymentAppManifestCallback, + base::Unretained(this))); return; } - PostPaymentAppInfoFetchResultToIOThread(); + RunCallbackAndDestroy(); } -void PaymentAppInfoFetcher::FetchPaymentAppManifestCallback( +void PaymentAppInfoFetcher::SelfDeleteFetcher::RunCallbackAndDestroy() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::BindOnce(std::move(callback_), + std::move(fetched_payment_app_info_))); + delete this; +} + +void PaymentAppInfoFetcher::SelfDeleteFetcher::FetchPaymentAppManifestCallback( const GURL& url, const Manifest& manifest) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -96,7 +125,7 @@ "href=\"some-file-name-here\">. This manifest defines the payment " "handler's name and icon. User may not recognize this payment handler " "in UI, because it will be labeled only by its origin."); - PostPaymentAppInfoFetchResultToIOThread(); + RunCallbackAndDestroy(); return; } @@ -108,7 +137,7 @@ "manifest defines the payment handler's name and icon. User may not " "recognize this payment handler in UI, because it will be labeled only " "by its origin."); - PostPaymentAppInfoFetchResultToIOThread(); + RunCallbackAndDestroy(); return; } @@ -163,7 +192,7 @@ manifest_url_.spec() + "\" does not contain an \"icons\" field with a valid URL in \"src\" " "sub-field. User may not recognize this payment handler in UI."); - PostPaymentAppInfoFetchResultToIOThread(); + RunCallbackAndDestroy(); return; } @@ -177,7 +206,7 @@ manifest_url_.spec() + "\". This is most likely due to unsupported MIME types in the " "\"icons\" field. User may not recognize this payment handler in UI."); - PostPaymentAppInfoFetchResultToIOThread(); + RunCallbackAndDestroy(); return; } @@ -187,14 +216,15 @@ "or navigated away during installation. User may not " "recognize this payment handler in UI, because it will be " "labeled only by its name and origin."; - PostPaymentAppInfoFetchResultToIOThread(); + RunCallbackAndDestroy(); return; } bool can_download = content::ManifestIconDownloader::Download( web_contents_helper_->web_contents(), icon_url_, kPaymentAppIdealIconSize, kPaymentAppMinimumIconSize, - base::Bind(&PaymentAppInfoFetcher::OnIconFetched, this)); + base::Bind(&PaymentAppInfoFetcher::SelfDeleteFetcher::OnIconFetched, + base::Unretained(this))); // |can_download| is false only if web contents are null or the icon URL is // not valid. Both of these conditions are manually checked above, so // |can_download| should never be false. The manual checks above are necessary @@ -202,7 +232,8 @@ DCHECK(can_download); } -void PaymentAppInfoFetcher::OnIconFetched(const SkBitmap& icon) { +void PaymentAppInfoFetcher::SelfDeleteFetcher::OnIconFetched( + const SkBitmap& icon) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (icon.drawsNothing()) { @@ -211,7 +242,7 @@ "\", which is defined in the web app manifest \"" + manifest_url_.spec() + "\". User may not recognize this payment handler in UI."); - PostPaymentAppInfoFetchResultToIOThread(); + RunCallbackAndDestroy(); return; } @@ -220,18 +251,11 @@ base::Base64Encode( base::StringPiece(raw_data->front_as<char>(), raw_data->size()), &(fetched_payment_app_info_->icon)); - PostPaymentAppInfoFetchResultToIOThread(); + RunCallbackAndDestroy(); } -void PaymentAppInfoFetcher::PostPaymentAppInfoFetchResultToIOThread() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::BindOnce(std::move(callback_), - std::move(fetched_payment_app_info_))); -} - -void PaymentAppInfoFetcher::WarnIfPossible(const std::string& message) { +void PaymentAppInfoFetcher::SelfDeleteFetcher::WarnIfPossible( + const std::string& message) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(web_contents_helper_);
diff --git a/content/browser/payments/payment_app_info_fetcher.h b/content/browser/payments/payment_app_info_fetcher.h index ebb7aac1..4100d1d7 100644 --- a/content/browser/payments/payment_app_info_fetcher.h +++ b/content/browser/payments/payment_app_info_fetcher.h
@@ -9,7 +9,6 @@ #include <string> #include "base/macros.h" -#include "base/memory/ref_counted.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/public/browser/stored_payment_app.h" #include "content/public/browser/web_contents_observer.h" @@ -18,11 +17,8 @@ namespace content { -class PaymentAppInfoFetcher - : public base::RefCountedThreadSafe<PaymentAppInfoFetcher> { +class PaymentAppInfoFetcher { public: - PaymentAppInfoFetcher(); - struct PaymentAppInfo { PaymentAppInfo(); ~PaymentAppInfo(); @@ -34,46 +30,62 @@ }; using PaymentAppInfoFetchCallback = base::OnceCallback<void(std::unique_ptr<PaymentAppInfo> app_info)>; - void Start(const GURL& context_url, - scoped_refptr<ServiceWorkerContextWrapper> service_worker_context, - PaymentAppInfoFetchCallback callback); + + // Only accessed on the IO thread. + static void Start( + const GURL& context_url, + scoped_refptr<ServiceWorkerContextWrapper> service_worker_context, + PaymentAppInfoFetchCallback callback); private: - friend class base::RefCountedThreadSafe<PaymentAppInfoFetcher>; + // Only accessed on the UI thread. + static void StartOnUI( + const GURL& context_url, + const std::unique_ptr<std::vector<std::pair<int, int>>>& provider_hosts, + PaymentAppInfoFetchCallback callback); // Keeps track of the web contents. + // Only accessed on the UI thread. class WebContentsHelper : public WebContentsObserver { public: explicit WebContentsHelper(WebContents* web_contents); ~WebContentsHelper() override; }; - ~PaymentAppInfoFetcher(); + // Only accessed on the UI thread. + class SelfDeleteFetcher { + public: + explicit SelfDeleteFetcher(PaymentAppInfoFetchCallback callback); + ~SelfDeleteFetcher(); - void StartFromUIThread( - const std::unique_ptr<std::vector<std::pair<int, int>>>& provider_hosts); + void Start(const GURL& context_url, + const std::unique_ptr<std::vector<std::pair<int, int>>>& + provider_hosts); - // The WebContents::GetManifestCallback. - void FetchPaymentAppManifestCallback(const GURL& url, - const Manifest& manifest); + private: + void RunCallbackAndDestroy(); - // The ManifestIconDownloader::IconFetchCallback. - void OnIconFetched(const SkBitmap& icon); - void PostPaymentAppInfoFetchResultToIOThread(); + // The WebContents::GetManifestCallback. + void FetchPaymentAppManifestCallback(const GURL& url, + const Manifest& manifest); - // Prints the warning |message| in the DevTools console, if possible. - // Otherwise logs the warning on command line. - void WarnIfPossible(const std::string& message); + // The ManifestIconDownloader::IconFetchCallback. + void OnIconFetched(const SkBitmap& icon); - GURL context_url_; - PaymentAppInfoFetchCallback callback_; + // Prints the warning |message| in the DevTools console, if possible. + // Otherwise logs the warning on command line. + void WarnIfPossible(const std::string& message); - std::unique_ptr<WebContentsHelper> web_contents_helper_; - std::unique_ptr<PaymentAppInfo> fetched_payment_app_info_; - GURL manifest_url_; - GURL icon_url_; + GURL manifest_url_; + GURL icon_url_; + std::unique_ptr<WebContentsHelper> web_contents_helper_; + std::unique_ptr<PaymentAppInfo> fetched_payment_app_info_; + PaymentAppInfoFetchCallback callback_; - DISALLOW_COPY_AND_ASSIGN(PaymentAppInfoFetcher); + DISALLOW_COPY_AND_ASSIGN(SelfDeleteFetcher); + }; + + DISALLOW_IMPLICIT_CONSTRUCTORS(PaymentAppInfoFetcher); }; } // namespace content
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 0f770ae1..66547bf 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -234,6 +234,9 @@ if (!gpu_channel_host) callback.Run(nullptr); + gpu::GpuChannelEstablishFactory* factory = + BrowserMainLoop::GetInstance()->gpu_channel_establish_factory(); + int32_t stream_id = kGpuStreamIdDefault; gpu::SchedulingPriority stream_priority = kGpuStreamPriorityUI; @@ -242,7 +245,8 @@ auto context_provider = base::MakeRefCounted<ui::ContextProviderCommandBuffer>( - std::move(gpu_channel_host), stream_id, stream_priority, handle, + std::move(gpu_channel_host), factory->GetGpuMemoryBufferManager(), + stream_id, stream_priority, handle, GURL(std::string("chrome://gpu/Compositor::CreateContextProvider")), automatic_flushes, support_locking, shared_memory_limits, attributes, nullptr /* shared_context */, @@ -755,6 +759,9 @@ DCHECK(window_); DCHECK_NE(surface_handle_, gpu::kNullSurfaceHandle); + gpu::GpuChannelEstablishFactory* factory = + BrowserMainLoop::GetInstance()->gpu_channel_establish_factory(); + int32_t stream_id = kGpuStreamIdDefault; gpu::SchedulingPriority stream_priority = kGpuStreamPriorityUI; @@ -767,8 +774,8 @@ ui::ContextProviderCommandBuffer* shared_context = nullptr; auto context_provider = base::MakeRefCounted<ui::ContextProviderCommandBuffer>( - std::move(gpu_channel_host), stream_id, stream_priority, - surface_handle_, + std::move(gpu_channel_host), factory->GetGpuMemoryBufferManager(), + stream_id, stream_priority, surface_handle_, GURL(std::string("chrome://gpu/CompositorImpl::") + std::string("CompositorContextProvider")), automatic_flushes, support_locking,
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 0edc633..b53c2285 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -226,9 +226,9 @@ const GURL url("chrome://gpu/RenderWidgetHostViewAndroid"); provider_ = new ui::ContextProviderCommandBuffer( - std::move(gpu_channel_host), stream_id, stream_priority, - gpu::kNullSurfaceHandle, url, automatic_flushes, support_locking, limits, - attributes, nullptr, + std::move(gpu_channel_host), factory->GetGpuMemoryBufferManager(), + stream_id, stream_priority, gpu::kNullSurfaceHandle, url, + automatic_flushes, support_locking, limits, attributes, nullptr, ui::command_buffer_metrics::BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT); auto result = provider_->BindToCurrentThread(); if (result != gpu::ContextResult::kSuccess)
diff --git a/content/public/test/network_service_test_helper.cc b/content/public/test/network_service_test_helper.cc index 4aaba75d..24186ff 100644 --- a/content/public/test/network_service_test_helper.cc +++ b/content/public/test/network_service_test_helper.cc
@@ -15,8 +15,10 @@ #include "content/public/common/content_features.h" #include "content/public/test/test_host_resolver.h" #include "mojo/public/cpp/bindings/binding_set.h" +#include "net/cert/test_root_certs.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/test_data_directory.h" #include "services/network/public/interfaces/network_change_manager.mojom.h" #include "services/service_manager/sandbox/sandbox_type.h" @@ -86,6 +88,11 @@ // Register the EmbeddedTestServer's certs, so that any SSL connections to // it succeed. Only do this when file I/O is allowed in the current process. net::EmbeddedTestServer::RegisterTestCerts(); + + // Also add the QUIC test certificate. + net::TestRootCerts* root_certs = net::TestRootCerts::GetInstance(); + root_certs->AddFromFile( + net::GetTestCertsDirectory().AppendASCII("quic-root.pem")); } }
diff --git a/content/renderer/indexed_db/webidbdatabase_impl.h b/content/renderer/indexed_db/webidbdatabase_impl.h index d5ebc00..38c14a9c 100644 --- a/content/renderer/indexed_db/webidbdatabase_impl.h +++ b/content/renderer/indexed_db/webidbdatabase_impl.h
@@ -36,7 +36,7 @@ void CreateObjectStore(long long transaction_id, long long objectstore_id, const blink::WebString& name, - const blink::WebIDBKeyPath& key_path, + const blink::WebIDBKeyPath&, bool auto_increment) override; void DeleteObjectStore(long long transaction_id, long long object_store_id) override; @@ -60,69 +60,69 @@ void RemoveObservers( const blink::WebVector<int32_t>& observer_ids_to_remove) override; - void Get(long long transactionId, - long long objectStoreId, - long long indexId, + void Get(long long transaction_id, + long long object_store_id, + long long index_id, const blink::WebIDBKeyRange&, - bool keyOnly, + bool key_only, blink::WebIDBCallbacks*) override; - void GetAll(long long transactionId, - long long objectStoreId, - long long indexId, + void GetAll(long long transaction_id, + long long object_store_id, + long long index_id, const blink::WebIDBKeyRange&, - long long maxCount, - bool keyOnly, + long long max_count, + bool key_only, blink::WebIDBCallbacks*) override; - void Put(long long transactionId, - long long objectStoreId, + void Put(long long transaction_id, + long long object_store_id, const blink::WebData& value, - const blink::WebVector<blink::WebBlobInfo>& webBlobInfo, + const blink::WebVector<blink::WebBlobInfo>&, const blink::WebIDBKey&, blink::WebIDBPutMode, blink::WebIDBCallbacks*, - const blink::WebVector<long long>& indexIds, + const blink::WebVector<long long>& index_ids, const blink::WebVector<WebIndexKeys>&) override; - void SetIndexKeys(long long transactionId, - long long objectStoreId, + void SetIndexKeys(long long transaction_id, + long long object_store_id, const blink::WebIDBKey&, - const blink::WebVector<long long>& indexIds, + const blink::WebVector<long long>& index_ids, const blink::WebVector<WebIndexKeys>&) override; - void SetIndexesReady(long long transactionId, - long long objectStoreId, - const blink::WebVector<long long>& indexIds) override; - void OpenCursor(long long transactionId, - long long objectStoreId, - long long indexId, + void SetIndexesReady(long long transaction_id, + long long object_store_id, + const blink::WebVector<long long>& index_ids) override; + void OpenCursor(long long transaction_id, + long long object_store_id, + long long index_id, const blink::WebIDBKeyRange&, blink::WebIDBCursorDirection direction, - bool keyOnly, + bool key_only, blink::WebIDBTaskType, blink::WebIDBCallbacks*) override; - void Count(long long transactionId, - long long objectStoreId, - long long indexId, + void Count(long long transaction_id, + long long object_store_id, + long long index_id, const blink::WebIDBKeyRange&, blink::WebIDBCallbacks*) override; - void DeleteRange(long long transactionId, - long long objectStoreId, + void DeleteRange(long long transaction_id, + long long object_store_id, const blink::WebIDBKeyRange&, blink::WebIDBCallbacks*) override; - void Clear(long long transactionId, - long long objectStoreId, + void Clear(long long transaction_id, + long long object_store_id, blink::WebIDBCallbacks*) override; - void CreateIndex(long long transactionId, - long long objectStoreId, - long long indexId, + void CreateIndex(long long transaction_id, + long long object_store_id, + long long index_id, const blink::WebString& name, const blink::WebIDBKeyPath&, bool unique, - bool multiEntry) override; - void DeleteIndex(long long transactionId, - long long objectStoreId, - long long indexId) override; - void RenameIndex(long long transactionId, - long long objectStoreId, - long long indexId, + bool multi_entry) override; + void DeleteIndex(long long transaction_id, + long long object_store_id, + long long index_id) override; + void RenameIndex(long long transaction_id, + long long object_store_id, + long long index_id, const blink::WebString& new_name) override; void Abort(long long transaction_id) override; void Commit(long long transaction_id) override;
diff --git a/content/renderer/media/media_interface_factory.cc b/content/renderer/media/media_interface_factory.cc index d7568b3..74e3f73 100644 --- a/content/renderer/media/media_interface_factory.cc +++ b/content/renderer/media/media_interface_factory.cc
@@ -81,6 +81,11 @@ GetMediaInterfaceFactory()->CreateCdm(key_system, std::move(request)); } +void MediaInterfaceFactory::CreateCdmProxy( + media::mojom::CdmProxyRequest request) { + NOTREACHED() << "CdmProxy should only be connected from a library CDM"; +} + media::mojom::InterfaceFactory* MediaInterfaceFactory::GetMediaInterfaceFactory() { DVLOG(1) << __func__;
diff --git a/content/renderer/media/media_interface_factory.h b/content/renderer/media/media_interface_factory.h index c39dd7d..f127eefe 100644 --- a/content/renderer/media/media_interface_factory.h +++ b/content/renderer/media/media_interface_factory.h
@@ -36,6 +36,7 @@ media::mojom::RendererRequest request) final; void CreateCdm(const std::string& key_system, media::mojom::ContentDecryptionModuleRequest request) final; + void CreateCdmProxy(media::mojom::CdmProxyRequest request) final; private: media::mojom::InterfaceFactory* GetMediaInterfaceFactory();
diff --git a/content/renderer/pepper/pepper_video_encoder_host.cc b/content/renderer/pepper/pepper_video_encoder_host.cc index c2783eb..9b4e44ac 100644 --- a/content/renderer/pepper/pepper_video_encoder_host.cc +++ b/content/renderer/pepper/pepper_video_encoder_host.cc
@@ -531,8 +531,9 @@ return false; command_buffer_ = std::make_unique<gpu::CommandBufferProxyImpl>( - std::move(channel), kGpuStreamIdDefault, - base::ThreadTaskRunnerHandle::Get()); + std::move(channel), + RenderThreadImpl::current()->GetGpuMemoryBufferManager(), + kGpuStreamIdDefault, base::ThreadTaskRunnerHandle::Get()); auto result = command_buffer_->Initialize( gpu::kNullSurfaceHandle, nullptr, kGpuStreamPriorityDefault, gpu::gles2::ContextCreationAttribHelper(), GURL::EmptyGURL());
diff --git a/content/renderer/pepper/ppb_graphics_3d_impl.cc b/content/renderer/pepper/ppb_graphics_3d_impl.cc index f59d980..997d388 100644 --- a/content/renderer/pepper/ppb_graphics_3d_impl.cc +++ b/content/renderer/pepper/ppb_graphics_3d_impl.cc
@@ -269,8 +269,8 @@ } command_buffer_ = std::make_unique<gpu::CommandBufferProxyImpl>( - std::move(channel), kGpuStreamIdDefault, - base::ThreadTaskRunnerHandle::Get()); + std::move(channel), render_thread->GetGpuMemoryBufferManager(), + kGpuStreamIdDefault, base::ThreadTaskRunnerHandle::Get()); auto result = command_buffer_->Initialize( gpu::kNullSurfaceHandle, share_buffer, kGpuStreamPriorityDefault, attrib_helper, GURL::EmptyGURL());
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index dec83a6..4190abe 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -372,6 +372,7 @@ scoped_refptr<ui::ContextProviderCommandBuffer> CreateOffscreenContext( scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const gpu::SharedMemoryLimits& limits, bool support_locking, bool support_gles2_interface, @@ -401,8 +402,8 @@ const bool automatic_flushes = false; return base::MakeRefCounted<ui::ContextProviderCommandBuffer>( - std::move(gpu_channel_host), stream_id, stream_priority, - gpu::kNullSurfaceHandle, + std::move(gpu_channel_host), gpu_memory_buffer_manager, stream_id, + stream_priority, gpu::kNullSurfaceHandle, GURL("chrome://gpu/RenderThreadImpl::CreateOffscreenContext/" + ui::command_buffer_metrics::ContextTypeToString(type)), automatic_flushes, support_locking, limits, attributes, nullptr, type); @@ -1500,11 +1501,11 @@ bool support_raster_interface = false; bool support_oop_rasterization = false; scoped_refptr<ui::ContextProviderCommandBuffer> media_context_provider = - CreateOffscreenContext(gpu_channel_host, limits, support_locking, - support_gles2_interface, support_raster_interface, - support_oop_rasterization, - ui::command_buffer_metrics::MEDIA_CONTEXT, - kGpuStreamIdDefault, kGpuStreamPriorityDefault); + CreateOffscreenContext( + gpu_channel_host, GetGpuMemoryBufferManager(), limits, + support_locking, support_gles2_interface, support_raster_interface, + support_oop_rasterization, ui::command_buffer_metrics::MEDIA_CONTEXT, + kGpuStreamIdDefault, kGpuStreamPriorityDefault); auto result = media_context_provider->BindToCurrentThread(); if (result != gpu::ContextResult::kSuccess) return nullptr; @@ -1559,9 +1560,9 @@ bool support_raster_interface = false; bool support_oop_rasterization = false; shared_main_thread_contexts_ = CreateOffscreenContext( - std::move(gpu_channel_host), gpu::SharedMemoryLimits(), support_locking, - support_gles2_interface, support_raster_interface, - support_oop_rasterization, + std::move(gpu_channel_host), GetGpuMemoryBufferManager(), + gpu::SharedMemoryLimits(), support_locking, support_gles2_interface, + support_raster_interface, support_oop_rasterization, ui::command_buffer_metrics::RENDERER_MAINTHREAD_CONTEXT, kGpuStreamIdDefault, kGpuStreamPriorityDefault); auto result = shared_main_thread_contexts_->BindToCurrentThread(); @@ -2140,9 +2141,9 @@ scoped_refptr<ui::ContextProviderCommandBuffer> context_provider( new ui::ContextProviderCommandBuffer( - gpu_channel_host, kGpuStreamIdDefault, kGpuStreamPriorityDefault, - gpu::kNullSurfaceHandle, url, automatic_flushes, support_locking, - limits, attributes, share_context, + gpu_channel_host, GetGpuMemoryBufferManager(), kGpuStreamIdDefault, + kGpuStreamPriorityDefault, gpu::kNullSurfaceHandle, url, + automatic_flushes, support_locking, limits, attributes, share_context, ui::command_buffer_metrics::RENDER_COMPOSITOR_CONTEXT)); if (layout_test_deps_) { @@ -2461,9 +2462,9 @@ bool support_gles2_interface = !support_oop_rasterization; bool support_raster_interface = true; shared_worker_context_provider_ = CreateOffscreenContext( - std::move(gpu_channel_host), gpu::SharedMemoryLimits(), support_locking, - support_gles2_interface, support_raster_interface, - support_oop_rasterization, + std::move(gpu_channel_host), GetGpuMemoryBufferManager(), + gpu::SharedMemoryLimits(), support_locking, support_gles2_interface, + support_raster_interface, support_oop_rasterization, ui::command_buffer_metrics::RENDER_WORKER_CONTEXT, stream_id, stream_priority); auto result = shared_worker_context_provider_->BindToCurrentThread();
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index bf78db3da..0500572 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -1151,10 +1151,12 @@ scoped_refptr<ui::ContextProviderCommandBuffer> provider( new ui::ContextProviderCommandBuffer( - std::move(gpu_channel_host), kGpuStreamIdDefault, - kGpuStreamPriorityDefault, gpu::kNullSurfaceHandle, - GURL(top_document_web_url), automatic_flushes, support_locking, - gpu::SharedMemoryLimits(), attributes, share_context, + std::move(gpu_channel_host), + RenderThreadImpl::current()->GetGpuMemoryBufferManager(), + kGpuStreamIdDefault, kGpuStreamPriorityDefault, + gpu::kNullSurfaceHandle, GURL(top_document_web_url), + automatic_flushes, support_locking, gpu::SharedMemoryLimits(), + attributes, share_context, ui::command_buffer_metrics::OFFSCREEN_CONTEXT_FOR_WEBGL)); return std::make_unique<WebGraphicsContext3DProviderImpl>( std::move(provider), is_software_rendering);
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc index cebbe9d..3b6ac86 100644 --- a/content/test/layouttest_support.cc +++ b/content/test/layouttest_support.cc
@@ -319,6 +319,7 @@ // previously being created but in that case the old GpuChannel would be // lost as would the LayerTreeFrameSink. gpu_channel_ = gpu_channel; + gpu_memory_buffer_manager_ = gpu_memory_buffer_manager; auto* task_runner = deps->GetCompositorImplThreadTaskRunner().get(); bool synchronous_composite = !task_runner; @@ -378,8 +379,8 @@ auto context_provider = base::MakeRefCounted<ui::ContextProviderCommandBuffer>( - gpu_channel_, kGpuStreamIdDefault, kGpuStreamPriorityDefault, - gpu::kNullSurfaceHandle, + gpu_channel_, gpu_memory_buffer_manager_, kGpuStreamIdDefault, + kGpuStreamPriorityDefault, gpu::kNullSurfaceHandle, GURL("chrome://gpu/" "LayoutTestDependenciesImpl::CreateOutputSurface"), automatic_flushes, support_locking, gpu::SharedMemoryLimits(), @@ -413,6 +414,7 @@ std::unordered_map<int32_t, viz::TestLayerTreeFrameSink*> layer_tree_frame_sinks_; scoped_refptr<gpu::GpuChannelHost> gpu_channel_; + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_ = nullptr; }; void EnableRendererLayoutTestMode() {
diff --git a/device/u2f/u2f_hid_discovery.cc b/device/u2f/u2f_hid_discovery.cc index 0695778..6c4e711 100644 --- a/device/u2f/u2f_hid_discovery.cc +++ b/device/u2f/u2f_hid_discovery.cc
@@ -55,9 +55,8 @@ void U2fHidDiscovery::OnGetDevices( std::vector<device::mojom::HidDeviceInfoPtr> device_infos) { - std::for_each( - device_infos.begin(), device_infos.end(), - [this](auto& device_info) { DeviceAdded(std::move(device_info)); }); + for (auto& device_info : device_infos) + DeviceAdded(std::move(device_info)); NotifyDiscoveryStarted(true); }
diff --git a/extensions/renderer/resources/platform_app.js b/extensions/renderer/resources/platform_app.js index 278d781..862abf7 100644 --- a/extensions/renderer/resources/platform_app.js +++ b/extensions/renderer/resources/platform_app.js
@@ -208,10 +208,8 @@ // Deprecated document properties from // https://developer.mozilla.org/en/DOM/document. - // To deprecate document.all, simply changing its getter and setter would - // activate its cache mechanism, and degrade the performance. Here we assign - // it first to 'undefined' to avoid this. - document.all = undefined; + // Disable document.all so that platform apps can not access. + delete Document.prototype.all disableGetters(document, 'document', ['alinkColor', 'all', 'bgColor', 'fgColor', 'linkColor', 'vlinkColor'], null, true);
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index 12a7d43..bacacf935 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn
@@ -20,6 +20,8 @@ "//gpu/command_buffer/client:client_sources", "//gpu/command_buffer/client:gles2_cmd_helper_sources", "//gpu/command_buffer/common:common_sources", + "//gpu/command_buffer/common:gles2_sources", + "//gpu/command_buffer/service:gles2_sources", "//gpu/command_buffer/service:service_sources", "//gpu/config:config_sources", "//gpu/ipc:command_buffer_sources", @@ -133,6 +135,7 @@ "//gpu/command_buffer/client:gles2_interface", ] deps = [ + "//gpu/command_buffer/common:gles2_utils", "//testing/gmock", "//testing/gtest", "//ui/gl:gl_unittest_utils", @@ -466,6 +469,7 @@ "//base", "//base/test:test_support", "//gpu/command_buffer/client:gles2_implementation", + "//gpu/command_buffer/common:gles2_utils", "//testing/gtest", "//testing/perf", "//ui/gfx/geometry",
diff --git a/gpu/command_buffer/client/BUILD.gn b/gpu/command_buffer/client/BUILD.gn index 2392c44d1..2bc585f 100644 --- a/gpu/command_buffer/client/BUILD.gn +++ b/gpu/command_buffer/client/BUILD.gn
@@ -15,13 +15,6 @@ ":client_sources", ] } - - if (!is_nacl) { - deps = [ - "//cc/paint", - "//skia", - ] - } } group("gles2_cmd_helper") { @@ -67,10 +60,8 @@ public_deps = [ "//base", - "//gpu/command_buffer/common:gles2_utils", ] deps = [ - ":gles2_interface", "//gpu/command_buffer/common:common_sources", "//gpu/ipc/common:surface_handle_type", "//ui/gfx:memory_buffer", @@ -96,6 +87,7 @@ ":client_sources", "//base", "//gpu/command_buffer/common:common_sources", + "//gpu/command_buffer/common:gles2_sources", ] } @@ -169,11 +161,12 @@ all_dependent_configs = [ "//third_party/khronos:khronos_headers" ] deps = [ + ":client", ":gles2_cmd_helper", ":gles2_interface", "//base", - "//gpu/command_buffer/client", "//gpu/command_buffer/common", + "//gpu/command_buffer/common:gles2", "//gpu/command_buffer/common:gles2_utils", "//ui/gfx/geometry", ] @@ -209,6 +202,7 @@ ":gles2_interface", "//base", "//gpu/command_buffer/common", + "//gpu/command_buffer/common:gles2", "//gpu/command_buffer/common:gles2_utils", "//ui/gfx", "//ui/gfx/geometry", @@ -228,7 +222,6 @@ defines = [ "GLES2_C_LIB_IMPLEMENTATION" ] deps = [ - ":client", ":gles2_interface", "//base", "//base/third_party/dynamic_annotations", @@ -246,8 +239,6 @@ "GLES2_CONFORMANCE_TESTS=1", ] deps = [ - ":client", - ":gles2_implementation_no_check", ":gles2_interface", "//base", "//base/third_party/dynamic_annotations",
diff --git a/gpu/command_buffer/client/transfer_buffer.h b/gpu/command_buffer/client/transfer_buffer.h index 565b0fd..cb94510 100644 --- a/gpu/command_buffer/client/transfer_buffer.h +++ b/gpu/command_buffer/client/transfer_buffer.h
@@ -14,7 +14,6 @@ #include "base/macros.h" #include "gpu/command_buffer/client/ring_buffer.h" #include "gpu/command_buffer/common/buffer.h" -#include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/gpu_export.h" namespace base {
diff --git a/gpu/command_buffer/common/BUILD.gn b/gpu/command_buffer/common/BUILD.gn index bc4f2c2..9c6ce10 100644 --- a/gpu/command_buffer/common/BUILD.gn +++ b/gpu/command_buffer/common/BUILD.gn
@@ -19,6 +19,18 @@ } } +group("gles2") { + if (is_component_build) { + public_deps = [ + "//gpu", + ] + } else { + public_deps = [ + ":gles2_sources", + ] + } +} + source_set("common_sources") { visibility = [ "//gpu/*" ] @@ -36,16 +48,8 @@ "command_buffer_id.h", "constants.h", "context_result.h", - "debug_marker_manager.cc", - "debug_marker_manager.h", "discardable_handle.cc", "discardable_handle.h", - "gl2_types.h", - "gles2_cmd_format.cc", - "gles2_cmd_format.h", - "gles2_cmd_format_autogen.h", - "gles2_cmd_ids.h", - "gles2_cmd_ids_autogen.h", "gpu_memory_buffer_support.cc", "gpu_memory_buffer_support.h", "id_allocator.cc", @@ -75,9 +79,37 @@ ] deps = [ + "//base", + ] + + # TODO(piman): needed for gpu_memory_buffer_support.cc. Split common vs gles2 + # specifics. + configs += [ "//third_party/khronos:khronos_headers" ] +} + +source_set("gles2_sources") { + visibility = [ "//gpu/*" ] + + sources = [ + "debug_marker_manager.cc", + "debug_marker_manager.h", + "gl2_types.h", + "gles2_cmd_format.cc", + "gles2_cmd_format.h", + "gles2_cmd_format_autogen.h", + "gles2_cmd_ids.h", + "gles2_cmd_ids_autogen.h", + ] + + configs += [ "//gpu:gpu_implementation" ] + + deps = [ ":gles2_utils", "//base", ] + public_deps = [ + ":common_sources", + ] } component("gles2_utils") {
diff --git a/gpu/command_buffer/common/mailbox_holder.h b/gpu/command_buffer/common/mailbox_holder.h index bc0d88d..b1cc3df 100644 --- a/gpu/command_buffer/common/mailbox_holder.h +++ b/gpu/command_buffer/common/mailbox_holder.h
@@ -8,7 +8,6 @@ #include <stdint.h> #include <string.h> -#include "gpu/command_buffer/common/gl2_types.h" #include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/common/sync_token.h" #include "gpu/gpu_export.h" @@ -30,7 +29,7 @@ gpu::Mailbox mailbox; gpu::SyncToken sync_token; - GLenum texture_target; + uint32_t texture_target; }; } // namespace gpu
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn index 05e9b46..770f24a 100644 --- a/gpu/command_buffer/service/BUILD.gn +++ b/gpu/command_buffer/service/BUILD.gn
@@ -17,6 +17,18 @@ } } +group("gles2") { + if (is_component_build) { + public_deps = [ + "//gpu", + ] + } else { + public_deps = [ + ":gles2_sources", + ] + } +} + if (is_component_build) { link_target_type = "source_set" } else { @@ -29,15 +41,70 @@ sources = [ "async_api_interface.h", + "command_buffer_service.cc", + "command_buffer_service.h", + "common_decoder.cc", + "common_decoder.h", + "gpu_preferences.cc", + "gpu_preferences.h", + "gpu_switches.cc", + "gpu_switches.h", + "image_factory.cc", + "image_factory.h", + "image_manager.cc", + "image_manager.h", + "memory_tracking.h", + "scheduler.cc", + "scheduler.h", + "sequence_id.h", + "sync_point_manager.cc", + "sync_point_manager.h", + "transfer_buffer_manager.cc", + "transfer_buffer_manager.h", + ] + + configs += [ + # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. + "//build/config/compiler:no_size_t_to_int_warning", + "//build/config:precompiled_headers", + "//gpu:gpu_implementation", + "//third_party/khronos:khronos_headers", + ] + + public_deps = [ + "//gpu/command_buffer/common:common_sources", + ] + deps = [ + "//base", + "//base/third_party/dynamic_annotations", + "//gpu/command_buffer/client:client_sources", + "//gpu/config:config_sources", + "//gpu/ipc/common:surface_handle_type", + "//media:media_features", + "//ui/gfx", + "//ui/gfx/geometry", + "//ui/gl", + ] + + if (is_android && !is_debug) { + # On Android optimize more since this component can be a bottleneck. + configs -= [ "//build/config/compiler:default_optimization" ] + configs += [ "//build/config/compiler:optimize_max" ] + } +} + +target(link_target_type, "gles2_sources") { + # External code should depend on this via //gpu/command_buffer/service:gles2 + # above rather than depending on this directly or the component build will + # break. + visibility = [ "//gpu/*" ] + + sources = [ "buffer_manager.cc", "buffer_manager.h", "client_service_map.h", "command_buffer_direct.cc", "command_buffer_direct.h", - "command_buffer_service.cc", - "command_buffer_service.h", - "common_decoder.cc", - "common_decoder.h", "context_group.cc", "context_group.h", "context_state.cc", @@ -83,20 +150,12 @@ "gles2_cmd_validation_implementation_autogen.h", "gpu_fence_manager.cc", "gpu_fence_manager.h", - "gpu_preferences.cc", - "gpu_preferences.h", "gpu_state_tracer.cc", "gpu_state_tracer.h", - "gpu_switches.cc", - "gpu_switches.h", "gpu_tracer.cc", "gpu_tracer.h", "id_manager.cc", "id_manager.h", - "image_factory.cc", - "image_factory.h", - "image_manager.cc", - "image_manager.h", "indexed_buffer_binding_host.cc", "indexed_buffer_binding_host.h", "logger.cc", @@ -125,9 +184,6 @@ "renderbuffer_manager.h", "sampler_manager.cc", "sampler_manager.h", - "scheduler.cc", - "scheduler.h", - "sequence_id.h", "service_discardable_manager.cc", "service_discardable_manager.h", "service_transfer_cache.cc", @@ -140,14 +196,10 @@ "shader_translator.h", "shader_translator_cache.cc", "shader_translator_cache.h", - "sync_point_manager.cc", - "sync_point_manager.h", "texture_definition.cc", "texture_definition.h", "texture_manager.cc", "texture_manager.h", - "transfer_buffer_manager.cc", - "transfer_buffer_manager.h", "transform_feedback_manager.cc", "transform_feedback_manager.h", "vertex_array_manager.cc", @@ -167,18 +219,18 @@ public_deps = [ "//gpu/command_buffer/common:common_sources", + "//gpu/command_buffer/common:gles2_sources", ] deps = [ ":disk_cache_proto", + ":service_sources", "//base", "//base/third_party/dynamic_annotations", "//cc/paint", - "//crypto", "//gpu/command_buffer/client:client_sources", "//gpu/command_buffer/common:gles2_utils", "//gpu/config:config_sources", "//gpu/ipc/common:surface_handle_type", - "//media:media_features", "//third_party/angle:angle_image_util", "//third_party/angle:commit_id", "//third_party/angle:translator",
diff --git a/gpu/command_buffer/service/transfer_buffer_manager.cc b/gpu/command_buffer/service/transfer_buffer_manager.cc index 29359bd4..3a89439 100644 --- a/gpu/command_buffer/service/transfer_buffer_manager.cc +++ b/gpu/command_buffer/service/transfer_buffer_manager.cc
@@ -18,7 +18,6 @@ #include "base/trace_event/process_memory_dump.h" #include "base/trace_event/trace_event.h" #include "gpu/command_buffer/common/cmd_buffer_common.h" -#include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/service/memory_tracking.h" using ::base::SharedMemory;
diff --git a/gpu/command_buffer/tests/gl_ext_window_rectangles_unittest.cc b/gpu/command_buffer/tests/gl_ext_window_rectangles_unittest.cc index c953a3d..7ef2cea 100644 --- a/gpu/command_buffer/tests/gl_ext_window_rectangles_unittest.cc +++ b/gpu/command_buffer/tests/gl_ext_window_rectangles_unittest.cc
@@ -25,11 +25,11 @@ void TearDown() override { gl_.Destroy(); } bool IsApplicable() const { - // If a driver isn't capable of supporting ES3 context, creating - // ContextGroup will fail. - bool have_es3 = gl_.decoder() && gl_.decoder()->GetContextGroup(); + // Not applicable for devices not supporting OpenGLES3. + if (!gl_.IsInitialized()) + return false; bool have_ext = GLTestHelper::HasExtension("GL_EXT_window_rectangles"); - return have_es3 && have_ext; + return have_ext; } GLuint SetupFramebuffer() {
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json index b5fc4eb..32e3883c 100644 --- a/gpu/config/gpu_driver_bug_list.json +++ b/gpu/config/gpu_driver_bug_list.json
@@ -1982,7 +1982,11 @@ "description": "Emulate GLSL function isnan() on Intel Mac", "cr_bugs": [650547], "os": { - "type": "macosx" + "type": "macosx", + "version": { + "op": "<", + "value": "10.13.2" + } }, "vendor_id": "0x8086", "device_id" : [
diff --git a/gpu/ipc/BUILD.gn b/gpu/ipc/BUILD.gn index 7774238..6c99b960 100644 --- a/gpu/ipc/BUILD.gn +++ b/gpu/ipc/BUILD.gn
@@ -37,6 +37,7 @@ "//base", "//gpu/command_buffer/client:client_sources", "//gpu/command_buffer/common:common_sources", + "//gpu/command_buffer/service:gles2_sources", "//gpu/command_buffer/service:service_sources", "//gpu/config:config_sources", "//gpu/config:crash_keys",
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.cc b/gpu/ipc/client/command_buffer_proxy_impl.cc index 6f8385a..cabfd25 100644 --- a/gpu/ipc/client/command_buffer_proxy_impl.cc +++ b/gpu/ipc/client/command_buffer_proxy_impl.cc
@@ -52,9 +52,11 @@ CommandBufferProxyImpl::CommandBufferProxyImpl( scoped_refptr<GpuChannelHost> channel, + GpuMemoryBufferManager* gpu_memory_buffer_manager, int32_t stream_id, scoped_refptr<base::SingleThreadTaskRunner> task_runner) : channel_(std::move(channel)), + gpu_memory_buffer_manager_(gpu_memory_buffer_manager), channel_id_(channel_->channel_id()), route_id_(channel_->GenerateRouteID()), stream_id_(stream_id), @@ -458,8 +460,6 @@ int32_t new_id = channel_->ReserveImageId(); - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager = - channel_->gpu_memory_buffer_manager(); gfx::GpuMemoryBuffer* gpu_memory_buffer = reinterpret_cast<gfx::GpuMemoryBuffer*>(buffer); DCHECK(gpu_memory_buffer); @@ -504,8 +504,8 @@ EnsureWorkVisible(); sync_token.SetVerifyFlush(); - gpu_memory_buffer_manager->SetDestructionSyncToken(gpu_memory_buffer, - sync_token); + gpu_memory_buffer_manager_->SetDestructionSyncToken(gpu_memory_buffer, + sync_token); } return new_id;
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.h b/gpu/ipc/client/command_buffer_proxy_impl.h index 664e9b31b..bd7b870 100644 --- a/gpu/ipc/client/command_buffer_proxy_impl.h +++ b/gpu/ipc/client/command_buffer_proxy_impl.h
@@ -60,6 +60,7 @@ namespace gpu { class GpuChannelHost; +class GpuMemoryBufferManager; // Client side proxy that forwards messages synchronously to a // CommandBufferStub. @@ -81,6 +82,7 @@ CommandBufferProxyImpl( scoped_refptr<GpuChannelHost> channel, + GpuMemoryBufferManager* gpu_memory_buffer_manager, int32_t stream_id, scoped_refptr<base::SingleThreadTaskRunner> task_runner); ~CommandBufferProxyImpl() override; @@ -264,6 +266,7 @@ base::ObserverList<DeletionObserver> deletion_observers_; scoped_refptr<GpuChannelHost> channel_; + GpuMemoryBufferManager* gpu_memory_buffer_manager_; bool disconnected_ = false; const int channel_id_; const int32_t route_id_;
diff --git a/gpu/ipc/client/gpu_channel_host.cc b/gpu/ipc/client/gpu_channel_host.cc index 6d0b00fd..9edd1c0 100644 --- a/gpu/ipc/client/gpu_channel_host.cc +++ b/gpu/ipc/client/gpu_channel_host.cc
@@ -30,19 +30,16 @@ } // namespace -GpuChannelHost::GpuChannelHost( - int channel_id, - const gpu::GPUInfo& gpu_info, - const gpu::GpuFeatureInfo& gpu_feature_info, - mojo::ScopedMessagePipeHandle handle, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) +GpuChannelHost::GpuChannelHost(int channel_id, + const gpu::GPUInfo& gpu_info, + const gpu::GpuFeatureInfo& gpu_feature_info, + mojo::ScopedMessagePipeHandle handle) : io_thread_(base::ThreadTaskRunnerHandle::Get()), channel_id_(channel_id), gpu_info_(gpu_info), gpu_feature_info_(gpu_feature_info), listener_(new Listener(std::move(handle), io_thread_), - base::OnTaskRunnerDeleter(io_thread_)), - gpu_memory_buffer_manager_(gpu_memory_buffer_manager) { + base::OnTaskRunnerDeleter(io_thread_)) { next_image_id_.GetNext(); next_route_id_.GetNext(); }
diff --git a/gpu/ipc/client/gpu_channel_host.h b/gpu/ipc/client/gpu_channel_host.h index 5fb3c29..21b6d54 100644 --- a/gpu/ipc/client/gpu_channel_host.h +++ b/gpu/ipc/client/gpu_channel_host.h
@@ -35,12 +35,10 @@ } namespace gpu { -class GpuMemoryBufferManager; -} - -namespace gpu { struct SyncToken; class GpuChannelHost; +class GpuMemoryBufferManager; + using GpuChannelEstablishedCallback = base::OnceCallback<void(scoped_refptr<GpuChannelHost>)>; @@ -64,8 +62,7 @@ GpuChannelHost(int channel_id, const gpu::GPUInfo& gpu_info, const gpu::GpuFeatureInfo& gpu_feature_info, - mojo::ScopedMessagePipeHandle handle, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager); + mojo::ScopedMessagePipeHandle handle); bool IsLost() const { DCHECK(listener_.get()); @@ -116,10 +113,6 @@ // Remove the message route associated with |route_id|. void RemoveRoute(int route_id); - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager() const { - return gpu_memory_buffer_manager_; - } - // Returns a handle to the shared memory that can be sent via IPC to the // GPU process. The caller is responsible for ensuring it is closed. Returns // an invalid handle on failure. @@ -216,8 +209,6 @@ // with base::Unretained(listener_). std::unique_ptr<Listener, base::OnTaskRunnerDeleter> listener_; - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_; - // Image IDs are allocated in sequence. base::AtomicSequenceNumber next_image_id_;
diff --git a/gpu/ipc/common/BUILD.gn b/gpu/ipc/common/BUILD.gn index 25b9d4cc..901586d 100644 --- a/gpu/ipc/common/BUILD.gn +++ b/gpu/ipc/common/BUILD.gn
@@ -99,7 +99,6 @@ public_deps = [ ":command_buffer_traits_sources", ":surface_handle_type", - "//gpu/command_buffer/common:gles2_utils", "//ipc", ]
diff --git a/gpu/ipc/service/BUILD.gn b/gpu/ipc/service/BUILD.gn index b35d65f..6f2b3d5 100644 --- a/gpu/ipc/service/BUILD.gn +++ b/gpu/ipc/service/BUILD.gn
@@ -74,6 +74,7 @@ deps = [ "//base/third_party/dynamic_annotations", "//gpu/command_buffer/common:common_sources", + "//gpu/command_buffer/service:gles2_sources", "//gpu/command_buffer/service:service_sources", "//gpu/config:config_sources", "//gpu/config:crash_keys",
diff --git a/gpu/ipc/service/gpu_channel_manager_unittest.cc b/gpu/ipc/service/gpu_channel_manager_unittest.cc index c4443930..821529c 100644 --- a/gpu/ipc/service/gpu_channel_manager_unittest.cc +++ b/gpu/ipc/service/gpu_channel_manager_unittest.cc
@@ -5,7 +5,6 @@ #include <stddef.h> #include <stdint.h> -#include "gpu/command_buffer/service/gl_utils.h" #include "gpu/ipc/common/gpu_messages.h" #include "gpu/ipc/service/gpu_channel.h" #include "gpu/ipc/service/gpu_channel_manager.h"
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 3f1249cd..636f572 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -811,6 +811,8 @@ // FeatureEngagementTracker). If neither is eligible, neither bubble is // presented. This method requires that |self.browserState| is not NULL. - (void)presentBubblesIfEligible; +// Returns whether |tab| is scrolled to the top. +- (BOOL)isTabScrolledToTop:(Tab*)tab; // Update find bar with model data. If |shouldFocus| is set to YES, the text // field will become first responder. @@ -2309,10 +2311,9 @@ return; if (currentTab.webState->GetVisibleURL() == kChromeUINewTabURL) return; - // Do not present the bubble if the tab is scrolled. - if (!CGPointEqualToPoint( - currentTab.webState->GetWebViewProxy().scrollViewProxy.contentOffset, - CGPointZero)) + + // Do not present the bubble if the tab is not scrolled to the top. + if (![self isTabScrolledToTop:currentTab]) return; NSString* text = @@ -2378,10 +2379,9 @@ Tab* currentTab = [self.tabModel currentTab]; if (!currentTab) return; - // Do not present the bubble if the tab is scrolled. - if (!CGPointEqualToPoint( - currentTab.webState->GetWebViewProxy().scrollViewProxy.contentOffset, - CGPointZero)) + + // Do not present the bubble if the tab is not scrolled to the top. + if (![self isTabScrolledToTop:currentTab]) return; NSString* text = l10n_util::GetNSStringWithFixup( @@ -2410,6 +2410,19 @@ [_toolbarCoordinator triggerToolsMenuButtonAnimation]; } +- (BOOL)isTabScrolledToTop:(Tab*)tab { + CGPoint scrollOffset = + tab.webState->GetWebViewProxy().scrollViewProxy.contentOffset; + + // If there is a native controller, use the native controller's scroll offset. + id nativeController = [self nativeControllerForTab:tab]; + if ([nativeController conformsToProtocol:@protocol(CRWNativeContent)] && + [nativeController respondsToSelector:@selector(scrollOffset)]) { + scrollOffset = [nativeController scrollOffset]; + } + return CGPointEqualToPoint(scrollOffset, CGPointZero); +} + #pragma mark - Tap handling - (void)setLastTapPoint:(OpenNewTabCommand*)command {
diff --git a/ios/chrome/test/app/tab_test_util.mm b/ios/chrome/test/app/tab_test_util.mm index bd72660..a6fc5fd 100644 --- a/ios/chrome/test/app/tab_test_util.mm +++ b/ios/chrome/test/app/tab_test_util.mm
@@ -13,7 +13,6 @@ #import "ios/chrome/browser/metrics/tab_usage_recorder.h" #import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model.h" -#import "ios/chrome/browser/tabs/tab_private.h" #import "ios/chrome/browser/ui/browser_view_controller.h" #import "ios/chrome/browser/ui/commands/browser_commands.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
diff --git a/ios/web/public/test/fakes/test_web_state.h b/ios/web/public/test/fakes/test_web_state.h index b6c7253..76a99c1 100644 --- a/ios/web/public/test/fakes/test_web_state.h +++ b/ios/web/public/test/fakes/test_web_state.h
@@ -85,7 +85,6 @@ bool CanTakeSnapshot() const override; void TakeSnapshot(const SnapshotCallback& callback, CGSize target_size) const override; - base::WeakPtr<WebState> AsWeakPtr() override; // Setters for test data. void SetBrowserState(BrowserState* browser_state);
diff --git a/ios/web/public/test/fakes/test_web_state.mm b/ios/web/public/test/fakes/test_web_state.mm index f212f82..587bbb8bf 100644 --- a/ios/web/public/test/fakes/test_web_state.mm +++ b/ios/web/public/test/fakes/test_web_state.mm
@@ -321,9 +321,4 @@ callback.Run(gfx::Image([[UIImage alloc] init])); } -base::WeakPtr<WebState> TestWebState::AsWeakPtr() { - NOTREACHED(); - return base::WeakPtr<WebState>(); -} - } // namespace web
diff --git a/ios/web/public/web_state/web_state.h b/ios/web/public/web_state/web_state.h index a2859a25..47b72e75 100644 --- a/ios/web/public/web_state/web_state.h +++ b/ios/web/public/web_state/web_state.h
@@ -53,7 +53,6 @@ class WebStateInterfaceProvider; class WebStateObserver; class WebStatePolicyDecider; -class WebStateWeakPtrFactory; // Core interface for interaction with the web. class WebState : public base::SupportsUserData { @@ -326,13 +325,6 @@ WebState() {} private: - friend class WebStateWeakPtrFactory; // For AsWeakPtr. - - // Returns a WeakPtr<WebState> to the current WebState. Must remain private - // and only call must be in WebStateWeakPtrFactory. Please consult that class - // for more details. Remove as part of http://crbug.com/556736. - virtual base::WeakPtr<WebState> AsWeakPtr() = 0; - DISALLOW_COPY_AND_ASSIGN(WebState); };
diff --git a/ios/web/web_state/BUILD.gn b/ios/web/web_state/BUILD.gn index 642f0a07..b3d9c8e 100644 --- a/ios/web/web_state/BUILD.gn +++ b/ios/web/web_state/BUILD.gn
@@ -33,8 +33,6 @@ "web_state_observer.mm", "web_state_observer_bridge.mm", "web_state_policy_decider.mm", - "web_state_weak_ptr_factory.h", - "web_state_weak_ptr_factory.mm", ] libs = [ "WebKit.framework" ]
diff --git a/ios/web/web_state/js/resources/common.js b/ios/web/web_state/js/resources/common.js index 97329ee..0b41262 100644 --- a/ios/web/web_state/js/resources/common.js +++ b/ios/web/web_state/js/resources/common.js
@@ -247,12 +247,13 @@ if (!input || !window['angular']) { return; } - var angular_element = window['angular'].element(input); + var angular_element = window['angular'].element && + window['angular'].element(input); if (!angular_element) { return; } angular_element.val(value); - var angular_model = angular_element.data('ngModel'); + var angular_model = angular_element.data && angular_element.data('ngModel'); if (!angular_model) { return; }
diff --git a/ios/web/web_state/web_state_impl.h b/ios/web/web_state/web_state_impl.h index dd4f877..84aca54 100644 --- a/ios/web/web_state/web_state_impl.h +++ b/ios/web/web_state/web_state_impl.h
@@ -232,7 +232,6 @@ bool CanTakeSnapshot() const override; void TakeSnapshot(const SnapshotCallback& callback, CGSize target_size) const override; - base::WeakPtr<WebState> AsWeakPtr() override; void AddObserver(WebStateObserver* observer) override; void RemoveObserver(WebStateObserver* observer) override; @@ -370,11 +369,6 @@ // WebState::CreateParams::created_with_opener_ for more details. bool created_with_opener_; - // Member variables should appear before the WeakPtrFactory<> to ensure that - // any WeakPtrs to WebStateImpl are invalidated before its member variable's - // destructors are executed, rendering them invalid. - base::WeakPtrFactory<WebState> weak_factory_; - // Mojo interface registry for this WebState. std::unique_ptr<WebStateInterfaceProvider> web_state_interface_provider_;
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm index 0e8f669..9c3fe90 100644 --- a/ios/web/web_state/web_state_impl.mm +++ b/ios/web/web_state/web_state_impl.mm
@@ -78,8 +78,7 @@ is_being_destroyed_(false), web_controller_(nil), interstitial_(nullptr), - created_with_opener_(params.created_with_opener), - weak_factory_(this) { + created_with_opener_(params.created_with_opener) { if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) { navigation_manager_ = base::MakeUnique<WKBasedNavigationManagerImpl>(); } else { @@ -536,10 +535,6 @@ } } -base::WeakPtr<WebState> WebStateImpl::AsWeakPtr() { - return weak_factory_.GetWeakPtr(); -} - #pragma mark - WebState implementation bool WebStateImpl::IsWebUsageEnabled() const {
diff --git a/ios/web/web_state/web_state_weak_ptr_factory.h b/ios/web/web_state/web_state_weak_ptr_factory.h deleted file mode 100644 index 137db85..0000000 --- a/ios/web/web_state/web_state_weak_ptr_factory.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_WEB_WEB_STATE_WEB_STATE_WEAK_PTR_FACTORY_H_ -#define IOS_WEB_WEB_STATE_WEB_STATE_WEAK_PTR_FACTORY_H_ - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" - -namespace web { - -class WebState; - -// Usage of this factory is disallowed for new code. It is there to support -// migrating src/chrome code that used GetWebContentsByID, and will eventually -// go away (cleanup will happen as part of http://crbug.com/556736). -class WebStateWeakPtrFactory { - public: - // Returns a WeakPtr<> to |web_state| if possible. May returns a null - // WeakPtr<> during testing. - static base::WeakPtr<WebState> CreateWeakPtr(WebState* web_state); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(WebStateWeakPtrFactory); -}; - -} // namespace web - -#endif // IOS_WEB_WEB_STATE_WEB_STATE_WEAK_PTR_FACTORY_H_
diff --git a/ios/web/web_state/web_state_weak_ptr_factory.mm b/ios/web/web_state/web_state_weak_ptr_factory.mm deleted file mode 100644 index 2b94ef4..0000000 --- a/ios/web/web_state/web_state_weak_ptr_factory.mm +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ios/web/web_state/web_state_weak_ptr_factory.h" - -#import "ios/web/public/web_state/web_state.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace web { - -// static -base::WeakPtr<WebState> WebStateWeakPtrFactory::CreateWeakPtr( - WebState* web_state) { - if (!web_state) - return base::WeakPtr<WebState>(); - return web_state->AsWeakPtr(); -} - -} // namespace web
diff --git a/media/base/ipc/media_param_traits_macros.h b/media/base/ipc/media_param_traits_macros.h index 33efc65..2ddca2cb 100644 --- a/media/base/ipc/media_param_traits_macros.h +++ b/media/base/ipc/media_param_traits_macros.h
@@ -31,13 +31,12 @@ #include "media/base/video_rotation.h" #include "media/base/video_types.h" #include "media/base/watch_time_keys.h" +// TODO(crbug.com/676224): When EnabledIf attribute is supported in mojom files, +// move CdmProxy related code into #if BUILDFLAG(ENABLE_LIBRARY_CDMS). +#include "media/cdm/cdm_proxy.h" #include "media/media_features.h" #include "ui/gfx/ipc/color/gfx_param_traits_macros.h" -#if BUILDFLAG(ENABLE_LIBRARY_CDMS) -#include "media/cdm/cdm_proxy.h" // nogncheck -#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) - // Enum traits. IPC_ENUM_TRAITS_MAX_VALUE(media::AudioCodec, media::AudioCodec::kAudioCodecMax) @@ -60,7 +59,6 @@ IPC_ENUM_TRAITS_MAX_VALUE(media::CdmPromise::Exception, media::CdmPromise::Exception::EXCEPTION_MAX) -#if BUILDFLAG(ENABLE_LIBRARY_CDMS) IPC_ENUM_TRAITS_MAX_VALUE(media::CdmProxy::Function, media::CdmProxy::Function::kMax) @@ -69,7 +67,6 @@ IPC_ENUM_TRAITS_MAX_VALUE(media::CdmProxy::Status, media::CdmProxy::Status::kMax) -#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) IPC_ENUM_TRAITS_MAX_VALUE(media::CdmSessionType, media::CdmSessionType::SESSION_TYPE_MAX)
diff --git a/media/cdm/BUILD.gn b/media/cdm/BUILD.gn index ddb8b07c..2d0a927 100644 --- a/media/cdm/BUILD.gn +++ b/media/cdm/BUILD.gn
@@ -28,6 +28,10 @@ sources = [ "aes_decryptor.cc", "aes_decryptor.h", + + # TODO(crbug.com/676224): Move this to |enable_library_cdms| block below + # when EnabledIf attribute is supported in mojom. + "cdm_proxy.h", "cenc_utils.cc", "cenc_utils.h", "default_cdm_factory.cc", @@ -72,7 +76,6 @@ "cdm_helpers.h", "cdm_module.cc", "cdm_module.h", - "cdm_proxy.h", "cdm_wrapper.h", "output_protection.h", "platform_verification.h",
diff --git a/media/cdm/cdm_adapter.cc b/media/cdm/cdm_adapter.cc index 5a802a0d..e76c2a79 100644 --- a/media/cdm/cdm_adapter.cc +++ b/media/cdm/cdm_adapter.cc
@@ -1156,6 +1156,8 @@ cdm::FileIO* CdmAdapter::CreateFileIO(cdm::FileIOClient* client) { DCHECK(task_runner_->BelongsToCurrentThread()); + DVLOG(3) << __func__; + return helper_->CreateCdmFileIO(client); } @@ -1171,9 +1173,10 @@ } cdm::CdmProxy* CdmAdapter::CreateCdmProxy() { - // TODO(xhwang): Implement this! - NOTIMPLEMENTED(); - return nullptr; + DCHECK(task_runner_->BelongsToCurrentThread()); + DVLOG(3) << __func__; + + return helper_->CreateCdmProxy(); } void CdmAdapter::OnStorageIdObtained(uint32_t version,
diff --git a/media/cdm/cdm_auxiliary_helper.cc b/media/cdm/cdm_auxiliary_helper.cc index 7950eac7..bd65b64 100644 --- a/media/cdm/cdm_auxiliary_helper.cc +++ b/media/cdm/cdm_auxiliary_helper.cc
@@ -17,6 +17,10 @@ return nullptr; } +cdm::CdmProxy* CdmAuxiliaryHelper::CreateCdmProxy() { + return nullptr; +} + cdm::Buffer* CdmAuxiliaryHelper::CreateCdmBuffer(size_t capacity) { return nullptr; }
diff --git a/media/cdm/cdm_auxiliary_helper.h b/media/cdm/cdm_auxiliary_helper.h index 3233538..60f304b 100644 --- a/media/cdm/cdm_auxiliary_helper.h +++ b/media/cdm/cdm_auxiliary_helper.h
@@ -20,6 +20,7 @@ namespace cdm { class FileIO; class FileIOClient; +class CdmProxy; } // namespace cdm namespace media { @@ -45,6 +46,12 @@ // needed anymore. virtual cdm::FileIO* CreateCdmFileIO(cdm::FileIOClient* client); + // Creates a cdm::CdmProxy object and returns it. + // The caller does not own the returned object and should not delete it + // directly. Instead, it should call cdm::CdmProxy::Destroy() after it's not + // needed anymore. + virtual cdm::CdmProxy* CreateCdmProxy(); + // CdmAllocator implementation. cdm::Buffer* CreateCdmBuffer(size_t capacity) override; std::unique_ptr<VideoFrameImpl> CreateCdmVideoFrame() override;
diff --git a/media/cdm/cdm_proxy.h b/media/cdm/cdm_proxy.h index 2cf4e67f..47094db 100644 --- a/media/cdm/cdm_proxy.h +++ b/media/cdm/cdm_proxy.h
@@ -15,7 +15,8 @@ namespace media { -// A proxy for the CDM. +// A class that proxies part of ContentDecryptionModule (CDM) functionalities to +// a different entity, e.g. hardware CDM modules. // In general, the interpretation of the method and callback parameters are // protocol dependent. For enum parameters, values outside the enum range may // not work. @@ -81,7 +82,7 @@ ProcessCB process_cb) = 0; // Callback for CreateMediaCryptoSession(). - // On suceess: + // On success: // |crypto_session_id| is the ID for the created crypto session. // |output_data| is extra value, if any. using CreateMediaCryptoSessionCB = base::OnceCallback< @@ -116,4 +117,4 @@ } // namespace media -#endif // MEDIA_CDM_CDM_PROXY_H_ \ No newline at end of file +#endif // MEDIA_CDM_CDM_PROXY_H_
diff --git a/media/gpu/android/android_video_decode_accelerator.cc b/media/gpu/android/android_video_decode_accelerator.cc index 3312b14..8160e75f 100644 --- a/media/gpu/android/android_video_decode_accelerator.cc +++ b/media/gpu/android/android_video_decode_accelerator.cc
@@ -232,13 +232,13 @@ AVDACodecAllocator* codec_allocator, std::unique_ptr<AndroidVideoSurfaceChooser> surface_chooser, const MakeGLContextCurrentCallback& make_context_current_cb, - const GetGLES2DecoderCallback& get_gles2_decoder_cb, + const GetContextGroupCallback& get_context_group_cb, const AndroidOverlayMojoFactoryCB& overlay_factory_cb, DeviceInfo* device_info) : client_(nullptr), codec_allocator_(codec_allocator), make_context_current_cb_(make_context_current_cb), - get_gles2_decoder_cb_(get_gles2_decoder_cb), + get_context_group_cb_(get_context_group_cb), state_(BEFORE_OVERLAY_INIT), picturebuffers_requested_(false), picture_buffer_manager_(this), @@ -286,7 +286,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); base::AutoReset<bool> scoper(&during_initialize_, true); - if (make_context_current_cb_.is_null() || get_gles2_decoder_cb_.is_null()) { + if (make_context_current_cb_.is_null() || get_context_group_cb_.is_null()) { DLOG(ERROR) << "GL callbacks are required for this VDA"; return false; } @@ -334,9 +334,9 @@ return false; } - auto gles_decoder = get_gles2_decoder_cb_.Run(); - if (!gles_decoder) { - DLOG(ERROR) << "Failed to get gles2 decoder instance."; + auto* context_group = get_context_group_cb_.Run(); + if (!context_group) { + DLOG(ERROR) << "Failed to get context group."; return false; } @@ -1357,9 +1357,9 @@ return size_; } -base::WeakPtr<gpu::gles2::GLES2Decoder> -AndroidVideoDecodeAccelerator::GetGlDecoder() const { - return get_gles2_decoder_cb_.Run(); +gpu::gles2::ContextGroup* AndroidVideoDecodeAccelerator::GetContextGroup() + const { + return get_context_group_cb_.Run(); } void AndroidVideoDecodeAccelerator::OnStopUsingOverlayImmediately(
diff --git a/media/gpu/android/android_video_decode_accelerator.h b/media/gpu/android/android_video_decode_accelerator.h index 5cbb6a30..ea3be48 100644 --- a/media/gpu/android/android_video_decode_accelerator.h +++ b/media/gpu/android/android_video_decode_accelerator.h
@@ -54,7 +54,7 @@ AVDACodecAllocator* codec_allocator, std::unique_ptr<AndroidVideoSurfaceChooser> surface_chooser, const MakeGLContextCurrentCallback& make_context_current_cb, - const GetGLES2DecoderCallback& get_gles2_decoder_cb, + const GetContextGroupCallback& get_context_group_cb, const AndroidOverlayMojoFactoryCB& overlay_factory_cb, DeviceInfo* device_info); @@ -76,7 +76,7 @@ // AVDAStateProvider implementation: const gfx::Size& GetSize() const override; - base::WeakPtr<gpu::gles2::GLES2Decoder> GetGlDecoder() const override; + gpu::gles2::ContextGroup* GetContextGroup() const override; // Notifies the client about the error and sets |state_| to |ERROR|. If we're // in the middle of Initialize, we guarantee that Initialize will return // failure. If deferred init is pending, then we'll fail deferred init. @@ -272,8 +272,8 @@ // Callback to set the correct gl context. MakeGLContextCurrentCallback make_context_current_cb_; - // Callback to get the GLES2Decoder instance. - GetGLES2DecoderCallback get_gles2_decoder_cb_; + // Callback to get the ContextGroup*. + GetContextGroupCallback get_context_group_cb_; // The current state of this class. For now, this is used only for setting // error state.
diff --git a/media/gpu/android/android_video_decode_accelerator_unittest.cc b/media/gpu/android/android_video_decode_accelerator_unittest.cc index cd8a84f..c5f0968 100644 --- a/media/gpu/android/android_video_decode_accelerator_unittest.cc +++ b/media/gpu/android/android_video_decode_accelerator_unittest.cc
@@ -18,8 +18,11 @@ #include "base/test/scoped_task_environment.h" #include "base/threading/sequenced_task_runner_handle.h" #include "gpu/command_buffer/client/client_test_helper.h" -#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" +#include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/gpu_tracer.h" +#include "gpu/command_buffer/service/image_manager.h" +#include "gpu/command_buffer/service/mailbox_manager_impl.h" +#include "gpu/command_buffer/service/service_discardable_manager.h" #include "media/base/android/media_codec_util.h" #include "media/base/android/mock_android_overlay.h" #include "media/base/android/mock_media_codec_bridge.h" @@ -56,9 +59,9 @@ return true; } -base::WeakPtr<gpu::gles2::GLES2Decoder> GetGLES2Decoder( - const base::WeakPtr<gpu::gles2::GLES2Decoder>& decoder) { - return decoder; +gpu::gles2::ContextGroup* GetContextGroup( + scoped_refptr<gpu::gles2::ContextGroup> context_group) { + return context_group.get(); } class MockVDAClient : public VideoDecodeAccelerator::Client { @@ -85,9 +88,7 @@ class AndroidVideoDecodeAcceleratorTest : public testing::Test { public: // Default to baseline H264 because it's always supported. - AndroidVideoDecodeAcceleratorTest() - : gl_decoder_(&command_buffer_service_, &outputter_), - config_(H264PROFILE_BASELINE) {} + AndroidVideoDecodeAcceleratorTest() : config_(H264PROFILE_BASELINE) {} void SetUp() override { ASSERT_TRUE(gl::init::InitializeGLOneOff()); @@ -104,6 +105,12 @@ base::MakeUnique<NiceMock<MockAndroidVideoSurfaceChooser>>(); chooser_ = chooser_that_is_usually_null_.get(); + feature_info_ = new gpu::gles2::FeatureInfo(); + context_group_ = new gpu::gles2::ContextGroup( + gpu_preferences_, false, &mailbox_manager_, nullptr, nullptr, nullptr, + feature_info_, false, &image_manager_, nullptr, nullptr, + gpu::GpuFeatureInfo(), &discardable_manager_); + // By default, allow deferred init. config_.is_deferred_initialization_allowed = true; } @@ -115,6 +122,9 @@ codec_allocator_ = nullptr; context_ = nullptr; surface_ = nullptr; + feature_info_ = nullptr; + context_group_ = nullptr; + gl::init::ShutdownGL(false); } @@ -123,8 +133,8 @@ // Because VDA has a custom deleter, we must assign it to |vda_| carefully. AndroidVideoDecodeAccelerator* avda = new AndroidVideoDecodeAccelerator( codec_allocator_.get(), std::move(chooser_that_is_usually_null_), - base::Bind(&MakeContextCurrent), - base::Bind(&GetGLES2Decoder, gl_decoder_.AsWeakPtr()), + base::BindRepeating(&MakeContextCurrent), + base::BindRepeating(&GetContextGroup, context_group_), AndroidOverlayMojoFactoryCB(), device_info_.get()); vda_.reset(avda); avda->force_defer_surface_creation_for_testing_ = @@ -199,12 +209,16 @@ scoped_refptr<gl::GLSurface> surface_; scoped_refptr<gl::GLContext> context_; - gpu::FakeCommandBufferServiceBase command_buffer_service_; - gpu::gles2::TraceOutputter outputter_; - NiceMock<gpu::gles2::MockGLES2Decoder> gl_decoder_; NiceMock<MockVDAClient> client_; std::unique_ptr<FakeCodecAllocator> codec_allocator_; + scoped_refptr<gpu::gles2::ContextGroup> context_group_; + scoped_refptr<gpu::gles2::FeatureInfo> feature_info_; + gpu::GpuPreferences gpu_preferences_; + gpu::gles2::MailboxManagerImpl mailbox_manager_; + gpu::gles2::ImageManager image_manager_; + gpu::ServiceDiscardableManager discardable_manager_; + // Only set until InitializeAVDA() is called. std::unique_ptr<MockAndroidVideoSurfaceChooser> chooser_that_is_usually_null_; MockAndroidVideoSurfaceChooser* chooser_;
diff --git a/media/gpu/android/avda_picture_buffer_manager.cc b/media/gpu/android/avda_picture_buffer_manager.cc index 8efc505f..fde92b9 100644 --- a/media/gpu/android/avda_picture_buffer_manager.cc +++ b/media/gpu/android/avda_picture_buffer_manager.cc
@@ -84,9 +84,7 @@ void AVDAPictureBufferManager::SetImageForPicture( const PictureBuffer& picture_buffer, gpu::gles2::GLStreamTextureImage* image) { - auto gles_decoder = state_provider_->GetGlDecoder(); - RETURN_IF_NULL(gles_decoder); - auto* context_group = gles_decoder->GetContextGroup(); + auto* context_group = state_provider_->GetContextGroup(); RETURN_IF_NULL(context_group); auto* texture_manager = context_group->texture_manager(); RETURN_IF_NULL(texture_manager);
diff --git a/media/gpu/android/avda_state_provider.h b/media/gpu/android/avda_state_provider.h index 86af2c41..93d5ef78 100644 --- a/media/gpu/android/avda_state_provider.h +++ b/media/gpu/android/avda_state_provider.h
@@ -13,7 +13,7 @@ namespace gpu { namespace gles2 { -class GLES2Decoder; +class ContextGroup; } } // namespace gpu @@ -25,7 +25,7 @@ public: // Various handy getters. virtual const gfx::Size& GetSize() const = 0; - virtual base::WeakPtr<gpu::gles2::GLES2Decoder> GetGlDecoder() const = 0; + virtual gpu::gles2::ContextGroup* GetContextGroup() const = 0; // Report a fatal error. This will post NotifyError(), and transition to the // error state.
diff --git a/media/gpu/gpu_video_decode_accelerator_factory.cc b/media/gpu/gpu_video_decode_accelerator_factory.cc index 667424f8..2e72cb5 100644 --- a/media/gpu/gpu_video_decode_accelerator_factory.cc +++ b/media/gpu/gpu_video_decode_accelerator_factory.cc
@@ -47,7 +47,7 @@ const BindGLImageCallback& bind_image_cb) { return base::WrapUnique(new GpuVideoDecodeAcceleratorFactory( get_gl_context_cb, make_context_current_cb, bind_image_cb, - GetGLES2DecoderCallback(), AndroidOverlayMojoFactoryCB())); + GetContextGroupCallback(), AndroidOverlayMojoFactoryCB())); } // static @@ -56,11 +56,11 @@ const GetGLContextCallback& get_gl_context_cb, const MakeGLContextCurrentCallback& make_context_current_cb, const BindGLImageCallback& bind_image_cb, - const GetGLES2DecoderCallback& get_gles2_decoder_cb, + const GetContextGroupCallback& get_context_group_cb, const AndroidOverlayMojoFactoryCB& overlay_factory_cb) { return base::WrapUnique(new GpuVideoDecodeAcceleratorFactory( get_gl_context_cb, make_context_current_cb, bind_image_cb, - get_gles2_decoder_cb, overlay_factory_cb)); + get_context_group_cb, overlay_factory_cb)); } // static @@ -242,7 +242,7 @@ AVDACodecAllocator::GetInstance(base::ThreadTaskRunnerHandle::Get()), base::MakeUnique<AndroidVideoSurfaceChooserImpl>( DeviceInfo::GetInstance()->IsSetOutputSurfaceSupported()), - make_context_current_cb_, get_gles2_decoder_cb_, overlay_factory_cb_, + make_context_current_cb_, get_context_group_cb_, overlay_factory_cb_, DeviceInfo::GetInstance())); return decoder; } @@ -252,12 +252,12 @@ const GetGLContextCallback& get_gl_context_cb, const MakeGLContextCurrentCallback& make_context_current_cb, const BindGLImageCallback& bind_image_cb, - const GetGLES2DecoderCallback& get_gles2_decoder_cb, + const GetContextGroupCallback& get_context_group_cb, const AndroidOverlayMojoFactoryCB& overlay_factory_cb) : get_gl_context_cb_(get_gl_context_cb), make_context_current_cb_(make_context_current_cb), bind_image_cb_(bind_image_cb), - get_gles2_decoder_cb_(get_gles2_decoder_cb), + get_context_group_cb_(get_context_group_cb), overlay_factory_cb_(overlay_factory_cb) {} GpuVideoDecodeAcceleratorFactory::~GpuVideoDecodeAcceleratorFactory() = default;
diff --git a/media/gpu/gpu_video_decode_accelerator_factory.h b/media/gpu/gpu_video_decode_accelerator_factory.h index b089f6a..56a0d7f 100644 --- a/media/gpu/gpu_video_decode_accelerator_factory.h +++ b/media/gpu/gpu_video_decode_accelerator_factory.h
@@ -26,7 +26,7 @@ struct GpuPreferences; namespace gles2 { -class GLES2Decoder; +class ContextGroup; } } @@ -37,25 +37,25 @@ ~GpuVideoDecodeAcceleratorFactory(); // Return current GLContext. - using GetGLContextCallback = base::Callback<gl::GLContext*(void)>; + using GetGLContextCallback = base::RepeatingCallback<gl::GLContext*(void)>; // Make the applicable GL context current. To be called by VDAs before // executing any GL calls. Return true on success, false otherwise. - using MakeGLContextCurrentCallback = base::Callback<bool(void)>; + using MakeGLContextCurrentCallback = base::RepeatingCallback<bool(void)>; // Bind |image| to |client_texture_id| given |texture_target|. If // |can_bind_to_sampler| is true, then the image may be used as a sampler // directly, otherwise a copy to a staging buffer is required. // Return true on success, false otherwise. using BindGLImageCallback = - base::Callback<bool(uint32_t client_texture_id, - uint32_t texture_target, - const scoped_refptr<gl::GLImage>& image, - bool can_bind_to_sampler)>; + base::RepeatingCallback<bool(uint32_t client_texture_id, + uint32_t texture_target, + const scoped_refptr<gl::GLImage>& image, + bool can_bind_to_sampler)>; - // Return a WeakPtr to a GLES2Decoder, if one is available. - using GetGLES2DecoderCallback = - base::Callback<base::WeakPtr<gpu::gles2::GLES2Decoder>(void)>; + // Return a ContextGroup*, if one is available. + using GetContextGroupCallback = + base::RepeatingCallback<gpu::gles2::ContextGroup*(void)>; static std::unique_ptr<GpuVideoDecodeAcceleratorFactory> Create( const GetGLContextCallback& get_gl_context_cb, @@ -67,7 +67,7 @@ const GetGLContextCallback& get_gl_context_cb, const MakeGLContextCurrentCallback& make_context_current_cb, const BindGLImageCallback& bind_image_cb, - const GetGLES2DecoderCallback& get_gles2_decoder_cb, + const GetContextGroupCallback& get_context_group_cb, const AndroidOverlayMojoFactoryCB& overlay_factory_cb); static std::unique_ptr<GpuVideoDecodeAcceleratorFactory> CreateWithNoGL(); @@ -87,7 +87,7 @@ const GetGLContextCallback& get_gl_context_cb, const MakeGLContextCurrentCallback& make_context_current_cb, const BindGLImageCallback& bind_image_cb, - const GetGLES2DecoderCallback& get_gles2_decoder_cb, + const GetContextGroupCallback& get_context_group_cb, const AndroidOverlayMojoFactoryCB& overlay_factory_cb); #if defined(OS_WIN) @@ -125,7 +125,7 @@ const GetGLContextCallback get_gl_context_cb_; const MakeGLContextCurrentCallback make_context_current_cb_; const BindGLImageCallback bind_image_cb_; - const GetGLES2DecoderCallback get_gles2_decoder_cb_; + const GetContextGroupCallback get_context_group_cb_; const AndroidOverlayMojoFactoryCB overlay_factory_cb_; base::ThreadChecker thread_checker_;
diff --git a/media/gpu/gpu_video_decode_accelerator_helpers.h b/media/gpu/gpu_video_decode_accelerator_helpers.h index 0dbfba1..02573bd 100644 --- a/media/gpu/gpu_video_decode_accelerator_helpers.h +++ b/media/gpu/gpu_video_decode_accelerator_helpers.h
@@ -15,7 +15,7 @@ namespace gpu { namespace gles2 { -class GLES2Decoder; +class ContextGroup; } } @@ -31,25 +31,25 @@ // thread (i.e. the thread which the VDAs are initialized on). // Return current GLContext. -using GetGLContextCallback = base::Callback<gl::GLContext*(void)>; +using GetGLContextCallback = base::RepeatingCallback<gl::GLContext*(void)>; // Make the applicable GL context current. To be called by VDAs before // executing any GL calls. Return true on success, false otherwise. -using MakeGLContextCurrentCallback = base::Callback<bool(void)>; +using MakeGLContextCurrentCallback = base::RepeatingCallback<bool(void)>; // Bind |image| to |client_texture_id| given |texture_target|. If // |can_bind_to_sampler| is true, then the image may be used as a sampler // directly, otherwise a copy to a staging buffer is required. // Return true on success, false otherwise. using BindGLImageCallback = - base::Callback<bool(uint32_t client_texture_id, - uint32_t texture_target, - const scoped_refptr<gl::GLImage>& image, - bool can_bind_to_sampler)>; + base::RepeatingCallback<bool(uint32_t client_texture_id, + uint32_t texture_target, + const scoped_refptr<gl::GLImage>& image, + bool can_bind_to_sampler)>; -// Return a WeakPtr to a GLES2Decoder, if one is available. -using GetGLES2DecoderCallback = - base::Callback<base::WeakPtr<gpu::gles2::GLES2Decoder>(void)>; +// Return a ContextGroup*, if one is available. +using GetContextGroupCallback = + base::RepeatingCallback<gpu::gles2::ContextGroup*(void)>; } // namespace media
diff --git a/media/gpu/ipc/service/gpu_video_decode_accelerator.cc b/media/gpu/ipc/service/gpu_video_decode_accelerator.cc index e278125..c3be705 100644 --- a/media/gpu/ipc/service/gpu_video_decode_accelerator.cc +++ b/media/gpu/ipc/service/gpu_video_decode_accelerator.cc
@@ -74,15 +74,16 @@ return true; } -static base::WeakPtr<gpu::gles2::GLES2Decoder> GetGLES2Decoder( +static gpu::gles2::ContextGroup* GetContextGroup( const base::WeakPtr<gpu::CommandBufferStub>& stub) { if (!stub) { DLOG(ERROR) << "Stub is gone; no GLES2Decoder."; - return base::WeakPtr<gpu::gles2::GLES2Decoder>(); + return nullptr; } - return stub->decoder()->AsWeakPtr(); + return stub->context_group().get(); } + } // anonymous namespace // DebugAutoLock works like AutoLock but only acquires the lock when @@ -161,11 +162,12 @@ weak_factory_for_io_(this) { DCHECK(stub_); stub_->AddDestructionObserver(this); - get_gl_context_cb_ = base::Bind(&GetGLContext, stub_->AsWeakPtr()); + get_gl_context_cb_ = base::BindRepeating(&GetGLContext, stub_->AsWeakPtr()); make_context_current_cb_ = - base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); - bind_image_cb_ = base::Bind(&BindImage, stub_->AsWeakPtr()); - get_gles2_decoder_cb_ = base::Bind(&GetGLES2Decoder, stub_->AsWeakPtr()); + base::BindRepeating(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); + bind_image_cb_ = base::BindRepeating(&BindImage, stub_->AsWeakPtr()); + get_context_group_cb_ = + base::BindRepeating(&GetContextGroup, stub_->AsWeakPtr()); } GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { @@ -350,7 +352,7 @@ std::unique_ptr<GpuVideoDecodeAcceleratorFactory> vda_factory = GpuVideoDecodeAcceleratorFactory::CreateWithGLES2Decoder( get_gl_context_cb_, make_context_current_cb_, bind_image_cb_, - get_gles2_decoder_cb_, overlay_factory_cb_); + get_context_group_cb_, overlay_factory_cb_); if (!vda_factory) { LOG(ERROR) << "Failed creating the VDA factory";
diff --git a/media/gpu/ipc/service/gpu_video_decode_accelerator.h b/media/gpu/ipc/service/gpu_video_decode_accelerator.h index 027ef01..eb998ce 100644 --- a/media/gpu/ipc/service/gpu_video_decode_accelerator.h +++ b/media/gpu/ipc/service/gpu_video_decode_accelerator.h
@@ -127,8 +127,8 @@ // Callback to bind a GLImage to a given texture id and target. BindGLImageCallback bind_image_cb_; - // Callback to return a WeakPtr to GLES2Decoder. - GetGLES2DecoderCallback get_gles2_decoder_cb_; + // Callback to return a ContextGroup*. + GetContextGroupCallback get_context_group_cb_; // The texture dimensions as requested by ProvidePictureBuffers(). gfx::Size texture_dimensions_;
diff --git a/media/media_options.gni b/media/media_options.gni index e5ffcdda..0c95074 100644 --- a/media/media_options.gni +++ b/media/media_options.gni
@@ -228,6 +228,7 @@ mojo_media_host = "gpu" } else if (enable_library_cdms) { mojo_media_services = [ "cdm" ] + mojo_media_host = "gpu" enable_standalone_cdm_service = true }
diff --git a/media/mojo/interfaces/BUILD.gn b/media/mojo/interfaces/BUILD.gn index 6671d93..1c8aed47 100644 --- a/media/mojo/interfaces/BUILD.gn +++ b/media/mojo/interfaces/BUILD.gn
@@ -6,11 +6,14 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("interfaces") { + # TODO(crbug.com/676224): Conditionally add source files in this list when we + # support EnabledIf attribute in mojom files. sources = [ "audio_decoder.mojom", "audio_input_stream.mojom", "audio_output_stream.mojom", "audio_parameters.mojom", + "cdm_proxy.mojom", "cdm_storage.mojom", "content_decryption_module.mojom", "decryptor.mojom", @@ -31,16 +34,11 @@ "watch_time_recorder.mojom", ] - if (enable_library_cdms) { - sources += [ "cdm_proxy.mojom" ] - } - if (is_android) { - sources += [ "media_drm_storage.mojom" ] - } - - if (is_android) { - sources += [ "android_overlay.mojom" ] + sources += [ + "android_overlay.mojom", + "media_drm_storage.mojom", + ] } public_deps = [ @@ -52,8 +50,8 @@ "//url/mojo:url_mojom_origin", ] - # TODO(xhwang): Remove media_service_mac.mojom when we support EnabledIf - # attribute in mojom files. See https://crbug.com/676224 + # TODO(crbug.com/676224): Remove media_service_mac.mojom when we support + # EnabledIf attribute in mojom files. if (is_mac) { sources += [ "media_service_mac.mojom" ]
diff --git a/media/mojo/interfaces/cdm_proxy.mojom b/media/mojo/interfaces/cdm_proxy.mojom index be185f96..f7650b9 100644 --- a/media/mojo/interfaces/cdm_proxy.mojom +++ b/media/mojo/interfaces/cdm_proxy.mojom
@@ -4,9 +4,11 @@ module media.mojom; +// An interface that helps proxy part of ContentDecryptionModule (CDM) +// functionalities to a different entity, e.g. hardware CDM modules. // In general, the interpretation of the method and callback parameters are // protocol dependent. -// CdmProxy implemenation is hosted in the GPU process. +// CdmProxy implementation is hosted in the GPU process. interface CdmProxy { // See media/cdm/cdm_proxy.h. [Native] @@ -20,13 +22,51 @@ [Native] enum Function; - // TODO(xhwang): Add methods for this interface so that they match - // the methods in media/cdm/cdm_proxy.h. + // Initializes the proxy. + // If the proxy created a crypto session, then the ID for the crypto session + // is |crypto_session_id|. + Initialize(associated CdmProxyClient client) => (Status status, + Protocol protocol, + uint32 crypto_session_id); + + // Processes and updates the state of the proxy. + // |function| specifies what type of function to use. + // |crypto_session_id| is a value returned from Initialize() or + // CreateMediaCryptoSessions(). + // |input_data| is the input data to be processed. + // |output_data_size| is the expected size of |output_data|. Some protocols + // require this field in order to determine the size of the output, but some + // may completely ignore it. + // The output data is passed back in |output_data|. + Process(Function function, + uint32 crypto_session_id, + array<uint8> input_data, + uint32 output_data_size) => (Status status, + array<uint8> output_data); + + // Creates a crypto session for handling media. + // If extra data has to be passed to further setup the media crypto session, + // pass the data as |input_data|. + // |crypto_session_id| is the ID for the crypto session. + // |output_data| is extra value, if any. + CreateMediaCryptoSession(array<uint8> input_data) => ( + Status status, uint32 crypto_session_id, uint64 output_data); + + // Sets a key in the proxy. + // |crypto_session_id| is the crypto session for decryption. + // |key_id| is the ID of the key. + // |key_blob| is the opaque key blob for decrypting or decoding. + SetKey(uint32 crypto_session_id, array<uint8> key_id, array<uint8> key_blob); + + // Removes a key from the proxy. + // |crypto_session_id| is the crypto session for decryption. + // |key_id| is the ID of the key. + RemoveKey(uint32 crypto_session_id, array<uint8> key_id); }; // Client of CdmProxy. -// CdmProxyClient is running in CDM utility process. +// CdmProxyClient is running in the fully sandboxed CDM (e.g. utility) process. interface CdmProxyClient { // Notifies the client that there has been a hardware reset. NotifyHardwareReset(); -}; \ No newline at end of file +};
diff --git a/media/mojo/interfaces/cdm_proxy.typemap b/media/mojo/interfaces/cdm_proxy.typemap index f887340..ac4ce48 100644 --- a/media/mojo/interfaces/cdm_proxy.typemap +++ b/media/mojo/interfaces/cdm_proxy.typemap
@@ -6,16 +6,15 @@ public_headers = [ "//media/cdm/cdm_proxy.h" ] -public_deps = [ - "//media", -] +traits_headers = [ "//media/base/ipc/media_param_traits_macros.h" ] deps = [ + "//media", "//media/base/ipc", ] type_mappings = [ - "media.mojom.CdmProxy.Status=media::CdmProxy::Status", - "media.mojom.CdmProxy.Protocol=media::CdmProxy::Protocol", "media.mojom.CdmProxy.Function=media::CdmProxy::Function", + "media.mojom.CdmProxy.Protocol=media::CdmProxy::Protocol", + "media.mojom.CdmProxy.Status=media::CdmProxy::Status", ]
diff --git a/media/mojo/interfaces/interface_factory.mojom b/media/mojo/interfaces/interface_factory.mojom index 3a00ffe..d91d614 100644 --- a/media/mojo/interfaces/interface_factory.mojom +++ b/media/mojo/interfaces/interface_factory.mojom
@@ -5,6 +5,7 @@ module media.mojom; import "media/mojo/interfaces/audio_decoder.mojom"; +import "media/mojo/interfaces/cdm_proxy.mojom"; import "media/mojo/interfaces/content_decryption_module.mojom"; import "media/mojo/interfaces/renderer.mojom"; import "media/mojo/interfaces/video_decoder.mojom"; @@ -27,4 +28,10 @@ // this call may be initiated by an untrusted process (e.g. renderer), so the // implementation must fully validate |key_system| before creating the CDM. CreateCdm(string key_system, ContentDecryptionModule& cdm); + + // Creates a CdmProxy that proxies part of CDM functionalities to a different + // entity, e.g. hardware CDM modules. + // TODO(crbug.com/676224): Conditionally enable this when EnabledIf attribute + // is supported in mojom files. + CreateCdmProxy(CdmProxy& cdm_proxy); };
diff --git a/media/mojo/services/BUILD.gn b/media/mojo/services/BUILD.gn index 47560c1..2defc60 100644 --- a/media/mojo/services/BUILD.gn +++ b/media/mojo/services/BUILD.gn
@@ -120,6 +120,10 @@ "mojo_cdm_file_io.h", "mojo_cdm_helper.cc", "mojo_cdm_helper.h", + "mojo_cdm_proxy.cc", + "mojo_cdm_proxy.h", + "mojo_cdm_proxy_service.cc", + "mojo_cdm_proxy_service.h", ] deps += [ "//media/cdm:cdm_api" ]
diff --git a/media/mojo/services/gpu_mojo_media_client.cc b/media/mojo/services/gpu_mojo_media_client.cc index fcc75518..d5e9bce 100644 --- a/media/mojo/services/gpu_mojo_media_client.cc +++ b/media/mojo/services/gpu_mojo_media_client.cc
@@ -34,6 +34,10 @@ #include "media/gpu/windows/d3d11_video_decoder.h" #endif // defined(OS_WIN) +#if BUILDFLAG(ENABLE_LIBRARY_CDMS) +#include "media/cdm/cdm_proxy.h" +#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) + namespace media { namespace { @@ -143,4 +147,11 @@ #endif // defined(OS_ANDROID) } +#if BUILDFLAG(ENABLE_LIBRARY_CDMS) +std::unique_ptr<CdmProxy> GpuMojoMediaClient::CreateCdmProxy() { + // TODO(rkuroiwa): Create the CdmProxy here. + return nullptr; +} +#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) + } // namespace media
diff --git a/media/mojo/services/gpu_mojo_media_client.h b/media/mojo/services/gpu_mojo_media_client.h index 54f28972..cb1f5bf7 100644 --- a/media/mojo/services/gpu_mojo_media_client.h +++ b/media/mojo/services/gpu_mojo_media_client.h
@@ -41,6 +41,9 @@ RequestOverlayInfoCB request_overlay_info_cb) final; std::unique_ptr<CdmFactory> CreateCdmFactory( service_manager::mojom::InterfaceProvider* interface_provider) final; +#if BUILDFLAG(ENABLE_LIBRARY_CDMS) + std::unique_ptr<CdmProxy> CreateCdmProxy() final; +#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) private: gpu::GpuPreferences gpu_preferences_;
diff --git a/media/mojo/services/interface_factory_impl.cc b/media/mojo/services/interface_factory_impl.cc index 8684e3c..04e8836 100644 --- a/media/mojo/services/interface_factory_impl.cc +++ b/media/mojo/services/interface_factory_impl.cc
@@ -34,6 +34,10 @@ #include "media/mojo/services/mojo_cdm_service.h" #endif // BUILDFLAG(ENABLE_MOJO_CDM) +#if BUILDFLAG(ENABLE_LIBRARY_CDMS) +#include "media/mojo/services/mojo_cdm_proxy_service.h" +#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) + namespace media { namespace { @@ -108,7 +112,7 @@ std::unique_ptr<AudioDecoder> audio_decoder = mojo_media_client_->CreateAudioDecoder(task_runner); if (!audio_decoder) { - LOG(ERROR) << "AudioDecoder creation failed."; + DLOG(ERROR) << "AudioDecoder creation failed."; return; } @@ -148,7 +152,7 @@ task_runner, task_runner, audio_sink.get(), video_sink.get(), RequestOverlayInfoCB(), gfx::ColorSpace()); if (!renderer) { - LOG(ERROR) << "Renderer creation failed."; + DLOG(ERROR) << "Renderer creation failed."; return; } @@ -185,6 +189,21 @@ #endif // BUILDFLAG(ENABLE_MOJO_CDM) } +void InterfaceFactoryImpl::CreateCdmProxy(mojom::CdmProxyRequest request) { +#if BUILDFLAG(ENABLE_LIBRARY_CDMS) + auto cdm_proxy = mojo_media_client_->CreateCdmProxy(); + if (!cdm_proxy) { + DLOG(ERROR) << "CdmProxy creation failed."; + return; + } + + cdm_proxy_bindings_.AddBinding( + std::make_unique<MojoCdmProxyService>(std::move(cdm_proxy), + &cdm_service_context_), + std::move(request)); +#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) +} + #if BUILDFLAG(ENABLE_MOJO_RENDERER) RendererFactory* InterfaceFactoryImpl::GetRendererFactory() { if (!renderer_factory_) {
diff --git a/media/mojo/services/interface_factory_impl.h b/media/mojo/services/interface_factory_impl.h index 6a20406..7a8af26f 100644 --- a/media/mojo/services/interface_factory_impl.h +++ b/media/mojo/services/interface_factory_impl.h
@@ -39,6 +39,7 @@ mojom::RendererRequest request) final; void CreateCdm(const std::string& key_system, mojom::ContentDecryptionModuleRequest request) final; + void CreateCdmProxy(mojom::CdmProxyRequest request) final; private: #if BUILDFLAG(ENABLE_MOJO_RENDERER) @@ -74,6 +75,10 @@ mojo::StrongBindingSet<mojom::ContentDecryptionModule> cdm_bindings_; #endif // BUILDFLAG(ENABLE_MOJO_CDM) +#if BUILDFLAG(ENABLE_LIBRARY_CDMS) + mojo::StrongBindingSet<mojom::CdmProxy> cdm_proxy_bindings_; +#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) + std::unique_ptr<DelayedReleaseServiceContextRef> connection_ref_; MojoMediaClient* mojo_media_client_;
diff --git a/media/mojo/services/mojo_cdm_helper.cc b/media/mojo/services/mojo_cdm_helper.cc index ef254d70..cb2582eb 100644 --- a/media/mojo/services/mojo_cdm_helper.cc +++ b/media/mojo/services/mojo_cdm_helper.cc
@@ -37,6 +37,20 @@ return cdm_file_io; } +cdm::CdmProxy* MojoCdmHelper::CreateCdmProxy() { + mojom::CdmProxyPtr cdm_proxy_ptr; + service_manager::GetInterface<mojom::CdmProxy>(interface_provider_, + &cdm_proxy_ptr); + auto mojo_cdm_proxy = + std::make_unique<MojoCdmProxy>(this, std::move(cdm_proxy_ptr)); + + cdm::CdmProxy* cdm_proxy = mojo_cdm_proxy.get(); + DVLOG(3) << __func__ << ": cdm_proxy = " << cdm_proxy; + + cdm_proxy_set_.push_back(std::move(mojo_cdm_proxy)); + return cdm_proxy; +} + cdm::Buffer* MojoCdmHelper::CreateCdmBuffer(size_t capacity) { return GetAllocator()->CreateCdmBuffer(capacity); } @@ -86,6 +100,14 @@ }); } +void MojoCdmHelper::DestroyCdmProxy(MojoCdmProxy* cdm_proxy) { + DVLOG(3) << __func__ << ": cdm_proxy = " << cdm_proxy; + base::EraseIf(cdm_proxy_set_, + [cdm_proxy](const std::unique_ptr<MojoCdmProxy>& ptr) { + return ptr.get() == cdm_proxy; + }); +} + void MojoCdmHelper::ReportFileReadSize(int file_size_bytes) { DVLOG(3) << __func__ << ": file_size_bytes = " << file_size_bytes; if (file_read_cb_)
diff --git a/media/mojo/services/mojo_cdm_helper.h b/media/mojo/services/mojo_cdm_helper.h index 964745c..2d971282 100644 --- a/media/mojo/services/mojo_cdm_helper.h +++ b/media/mojo/services/mojo_cdm_helper.h
@@ -12,11 +12,13 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "media/cdm/cdm_auxiliary_helper.h" +#include "media/mojo/interfaces/cdm_proxy.mojom.h" #include "media/mojo/interfaces/cdm_storage.mojom.h" #include "media/mojo/interfaces/output_protection.mojom.h" #include "media/mojo/interfaces/platform_verification.mojom.h" #include "media/mojo/services/media_mojo_export.h" #include "media/mojo/services/mojo_cdm_file_io.h" +#include "media/mojo/services/mojo_cdm_proxy.h" namespace service_manager { namespace mojom { @@ -30,7 +32,8 @@ // additional services (FileIO, memory allocation, output protection, and // platform verification) are lazily created. class MEDIA_MOJO_EXPORT MojoCdmHelper final : public CdmAuxiliaryHelper, - public MojoCdmFileIO::Delegate { + public MojoCdmFileIO::Delegate, + public MojoCdmProxy::Delegate { public: explicit MojoCdmHelper( service_manager::mojom::InterfaceProvider* interface_provider); @@ -39,6 +42,7 @@ // CdmAuxiliaryHelper implementation. void SetFileReadCB(FileReadCB file_read_cb) final; cdm::FileIO* CreateCdmFileIO(cdm::FileIOClient* client) final; + cdm::CdmProxy* CreateCdmProxy() final; cdm::Buffer* CreateCdmBuffer(size_t capacity) final; std::unique_ptr<VideoFrameImpl> CreateCdmVideoFrame() final; void QueryStatus(QueryStatusCB callback) final; @@ -53,6 +57,9 @@ void CloseCdmFileIO(MojoCdmFileIO* cdm_file_io) final; void ReportFileReadSize(int file_size_bytes) final; + // MojoCdmProxy::Delegate implementation. + void DestroyCdmProxy(MojoCdmProxy* cdm_proxy) final; + private: // All services are created lazily. void ConnectToCdmStorage(); @@ -75,7 +82,9 @@ FileReadCB file_read_cb_; // A list of open cdm::FileIO objects. + // TODO(xhwang): Switch to use UniquePtrComparator. std::vector<std::unique_ptr<MojoCdmFileIO>> cdm_file_io_set_; + std::vector<std::unique_ptr<MojoCdmProxy>> cdm_proxy_set_; base::WeakPtrFactory<MojoCdmHelper> weak_factory_; DISALLOW_COPY_AND_ASSIGN(MojoCdmHelper);
diff --git a/media/mojo/services/mojo_cdm_proxy.cc b/media/mojo/services/mojo_cdm_proxy.cc new file mode 100644 index 0000000..64e6c095 --- /dev/null +++ b/media/mojo/services/mojo_cdm_proxy.cc
@@ -0,0 +1,190 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/mojo/services/mojo_cdm_proxy.h" + +#include <vector> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/logging.h" +#include "media/base/scoped_callback_runner.h" + +namespace media { + +namespace { + +inline std::ostream& operator<<(std::ostream& out, CdmProxy::Status status) { + switch (status) { + case CdmProxy::Status::kOk: + return out << "kOk"; + case CdmProxy::Status::kFail: + return out << "kFail"; + } + NOTREACHED(); + return out << "Invalid Status!"; +} + +cdm::CdmProxyClient::Status ToCdmStatus(CdmProxy::Status status) { + switch (status) { + case CdmProxy::Status::kOk: + return cdm::CdmProxyClient::Status::kOk; + case CdmProxy::Status::kFail: + return cdm::CdmProxyClient::Status::kFail; + } + + NOTREACHED() << "Unexpected status: " << status; + return cdm::CdmProxyClient::Status::kFail; +} + +cdm::CdmProxyClient::Protocol ToCdmProtocol(CdmProxy::Protocol protocol) { + switch (protocol) { + case CdmProxy::Protocol::kIntelConvergedSecurityAndManageabilityEngine: + return cdm::CdmProxyClient::Protocol:: + kIntelConvergedSecurityAndManageabilityEngine; + } + + // TODO(xhwang): Return an invalid protocol? + NOTREACHED() << "Unexpected protocol: " << static_cast<int32_t>(protocol); + return cdm::CdmProxyClient::Protocol:: + kIntelConvergedSecurityAndManageabilityEngine; +} + +CdmProxy::Function ToMediaFunction(cdm::CdmProxy::Function function) { + switch (function) { + case cdm::CdmProxy::Function::kIntelNegotiateCryptoSessionKeyExchange: + return CdmProxy::Function::kIntelNegotiateCryptoSessionKeyExchange; + } + + // TODO(xhwang): Return an invalid function? + NOTREACHED() << "Unexpected function: " << static_cast<int32_t>(function); + return CdmProxy::Function::kIntelNegotiateCryptoSessionKeyExchange; +} + +} // namespace + +MojoCdmProxy::MojoCdmProxy(Delegate* delegate, mojom::CdmProxyPtr cdm_proxy_ptr) + : delegate_(delegate), + cdm_proxy_ptr_(std::move(cdm_proxy_ptr)), + client_binding_(this), + weak_factory_(this) { + DVLOG(1) << __func__; + DCHECK(delegate_); +} + +MojoCdmProxy::~MojoCdmProxy() { + DVLOG(1) << __func__; +} + +void MojoCdmProxy::Initialize(cdm::CdmProxyClient* client) { + DVLOG(2) << __func__; + + DCHECK(client); + client_ = client; + + mojom::CdmProxyClientAssociatedPtrInfo client_ptr_info; + client_binding_.Bind(mojo::MakeRequest(&client_ptr_info)); + + auto callback = ScopedCallbackRunner( + base::BindOnce(&MojoCdmProxy::OnInitialized, weak_factory_.GetWeakPtr()), + media::CdmProxy::Status::kFail, + media::CdmProxy::Protocol::kIntelConvergedSecurityAndManageabilityEngine, + 0); + cdm_proxy_ptr_->Initialize(std::move(client_ptr_info), std::move(callback)); +} + +void MojoCdmProxy::Process(Function function, + uint32_t crypto_session_id, + const uint8_t* input_data, + uint32_t input_data_size, + uint32_t expected_output_data_size) { + DVLOG(3) << __func__; + CHECK(client_) << "Initialize not called."; + + auto callback = ScopedCallbackRunner( + base::BindOnce(&MojoCdmProxy::OnProcessed, weak_factory_.GetWeakPtr()), + media::CdmProxy::Status::kFail, std::vector<uint8_t>()); + + cdm_proxy_ptr_->Process( + ToMediaFunction(function), crypto_session_id, + std::vector<uint8_t>(input_data, input_data + input_data_size), + expected_output_data_size, std::move(callback)); +} + +void MojoCdmProxy::CreateMediaCryptoSession(const uint8_t* input_data, + uint32_t input_data_size) { + DVLOG(3) << __func__; + CHECK(client_) << "Initialize not called."; + + auto callback = ScopedCallbackRunner( + base::BindOnce(&MojoCdmProxy::OnMediaCryptoSessionCreated, + weak_factory_.GetWeakPtr()), + media::CdmProxy::Status::kFail, 0, 0); + + cdm_proxy_ptr_->CreateMediaCryptoSession( + std::vector<uint8_t>(input_data, input_data + input_data_size), + std::move(callback)); +} + +void MojoCdmProxy::SetKey(uint32_t crypto_session_id, + const uint8_t* key_id, + uint32_t key_id_size, + const uint8_t* key_blob, + uint32_t key_blob_size) { + DVLOG(3) << __func__; + CHECK(client_) << "Initialize not called."; + + cdm_proxy_ptr_->SetKey( + crypto_session_id, std::vector<uint8_t>(key_id, key_id + key_id_size), + std::vector<uint8_t>(key_blob, key_blob + key_blob_size)); +} + +void MojoCdmProxy::RemoveKey(uint32_t crypto_session_id, + const uint8_t* key_id, + uint32_t key_id_size) { + DVLOG(3) << __func__; + CHECK(client_) << "Initialize not called."; + + cdm_proxy_ptr_->RemoveKey(crypto_session_id, + std::vector<uint8_t>(key_id, key_id + key_id_size)); +} + +void MojoCdmProxy::Destroy() { + DVLOG(3) << __func__; + + // Note: |this| could be deleted as part of this call. + delegate_->DestroyCdmProxy(this); +} + +void MojoCdmProxy::NotifyHardwareReset() { + DVLOG(2) << __func__; + client_->NotifyHardwareReset(); +} + +void MojoCdmProxy::OnInitialized(media::CdmProxy::Status status, + media::CdmProxy::Protocol protocol, + uint32_t crypto_session_id) { + DVLOG(3) << __func__ << ": status = " << status + << ", crypto_session_id = " << crypto_session_id; + client_->OnInitialized(ToCdmStatus(status), ToCdmProtocol(protocol), + crypto_session_id); +} + +void MojoCdmProxy::OnProcessed(media::CdmProxy::Status status, + const std::vector<uint8_t>& output_data) { + DVLOG(3) << __func__ << ": status = " << status; + client_->OnProcessed(ToCdmStatus(status), output_data.data(), + output_data.size()); +} + +void MojoCdmProxy::OnMediaCryptoSessionCreated(media::CdmProxy::Status status, + uint32_t crypto_session_id, + uint64_t output_data) { + DVLOG(3) << __func__ << ": status = " << status + << ", crypto_session_id = " << crypto_session_id; + client_->OnMediaCryptoSessionCreated(ToCdmStatus(status), crypto_session_id, + output_data); +} + +} // namespace media
diff --git a/media/mojo/services/mojo_cdm_proxy.h b/media/mojo/services/mojo_cdm_proxy.h new file mode 100644 index 0000000..fff5787f --- /dev/null +++ b/media/mojo/services/mojo_cdm_proxy.h
@@ -0,0 +1,80 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_MOJO_SERVICES_MOJO_CDM_PROXY_H_ +#define MEDIA_MOJO_SERVICES_MOJO_CDM_PROXY_H_ + +#include <stdint.h> + +#include <vector> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "media/cdm/api/content_decryption_module.h" +#include "media/mojo/interfaces/cdm_proxy.mojom.h" +#include "media/mojo/services/media_mojo_export.h" +#include "mojo/public/cpp/bindings/associated_binding.h" + +namespace media { + +// Implements a cdm::CdmProxy that communicates with mojom::CdmProxy. +class MEDIA_MOJO_EXPORT MojoCdmProxy : public cdm::CdmProxy, + mojom::CdmProxyClient { + public: + class Delegate { + public: + // Notifies the delegate to close |cdm_proxy|. + virtual void DestroyCdmProxy(MojoCdmProxy* cdm_proxy) = 0; + }; + + MojoCdmProxy(Delegate* delegate, mojom::CdmProxyPtr cdm_proxy_ptr); + ~MojoCdmProxy() override; + + // cdm::CdmProxy implementation. + void Initialize(cdm::CdmProxyClient* client) final; + void Process(Function function, + uint32_t crypto_session_id, + const uint8_t* input_data, + uint32_t input_data_size, + uint32_t expected_output_data_size) final; + void CreateMediaCryptoSession(const uint8_t* input_data, + uint32_t input_data_size) final; + void SetKey(uint32_t crypto_session_id, + const uint8_t* key_id, + uint32_t key_id_size, + const uint8_t* key_blob, + uint32_t key_blob_size) final; + void RemoveKey(uint32_t crypto_session_id, + const uint8_t* key_id, + uint32_t key_id_size) final; + void Destroy() final; + + // mojom::CdmProxyClient implementation. + void NotifyHardwareReset() final; + + private: + void OnInitialized(media::CdmProxy::Status status, + media::CdmProxy::Protocol protocol, + uint32_t crypto_session_id); + void OnProcessed(media::CdmProxy::Status status, + const std::vector<uint8_t>& output_data); + void OnMediaCryptoSessionCreated(media::CdmProxy::Status status, + uint32_t crypto_session_id, + uint64_t output_data); + + Delegate* const delegate_; + mojom::CdmProxyPtr cdm_proxy_ptr_; + cdm::CdmProxyClient* client_; + + mojo::AssociatedBinding<mojom::CdmProxyClient> client_binding_; + + // NOTE: Weak pointers must be invalidated before all other member variables. + base::WeakPtrFactory<MojoCdmProxy> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(MojoCdmProxy); +}; + +} // namespace media + +#endif // MEDIA_MOJO_SERVICES_MOJO_CDM_PROXY_H_
diff --git a/media/mojo/services/mojo_cdm_proxy_service.cc b/media/mojo/services/mojo_cdm_proxy_service.cc new file mode 100644 index 0000000..a2ba538 --- /dev/null +++ b/media/mojo/services/mojo_cdm_proxy_service.cc
@@ -0,0 +1,71 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/mojo/services/mojo_cdm_proxy_service.h" + +#include "base/bind.h" +#include "base/macros.h" +#include "media/mojo/services/mojo_cdm_service_context.h" + +namespace media { + +MojoCdmProxyService::MojoCdmProxyService( + std::unique_ptr<::media::CdmProxy> cdm_proxy, + MojoCdmServiceContext* context) + : cdm_proxy_(std::move(cdm_proxy)), context_(context) { + DVLOG(1) << __func__; + DCHECK(cdm_proxy_); + DCHECK(context_); +} + +MojoCdmProxyService::~MojoCdmProxyService() { + DVLOG(1) << __func__; +} + +void MojoCdmProxyService::Initialize( + mojom::CdmProxyClientAssociatedPtrInfo client, + InitializeCallback callback) { + DVLOG(2) << __func__; + client_.Bind(std::move(client)); + + // TODO(xhwang): Register |this| in the |context| to implement SetCdm(). + cdm_proxy_->Initialize(this, std::move(callback)); +} + +void MojoCdmProxyService::Process(media::CdmProxy::Function function, + uint32_t crypto_session_id, + const std::vector<uint8_t>& input_data, + uint32_t expected_output_data_size, + ProcessCallback callback) { + DVLOG(3) << __func__; + cdm_proxy_->Process(function, crypto_session_id, input_data, + expected_output_data_size, std::move(callback)); +} + +void MojoCdmProxyService::CreateMediaCryptoSession( + const std::vector<uint8_t>& input_data, + CreateMediaCryptoSessionCallback callback) { + DVLOG(3) << __func__; + cdm_proxy_->CreateMediaCryptoSession(input_data, std::move(callback)); +} + +void MojoCdmProxyService::SetKey(uint32_t crypto_session_id, + const std::vector<uint8_t>& key_id, + const std::vector<uint8_t>& key_blob) { + DVLOG(3) << __func__; + cdm_proxy_->SetKey(crypto_session_id, key_id, key_blob); +} + +void MojoCdmProxyService::RemoveKey(uint32_t crypto_session_id, + const std::vector<uint8_t>& key_id) { + DVLOG(3) << __func__; + cdm_proxy_->RemoveKey(crypto_session_id, key_id); +} + +void MojoCdmProxyService::NotifyHardwareReset() { + DVLOG(2) << __func__; + client_->NotifyHardwareReset(); +} + +} // namespace media
diff --git a/media/mojo/services/mojo_cdm_proxy_service.h b/media/mojo/services/mojo_cdm_proxy_service.h new file mode 100644 index 0000000..d88fe73 --- /dev/null +++ b/media/mojo/services/mojo_cdm_proxy_service.h
@@ -0,0 +1,62 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_MOJO_SERVICES_MOJO_CDM_PROXY_SERVICE_H_ +#define MEDIA_MOJO_SERVICES_MOJO_CDM_PROXY_SERVICE_H_ + +#include <stdint.h> + +#include <memory> + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "media/cdm/cdm_proxy.h" +#include "media/mojo/interfaces/cdm_proxy.mojom.h" +#include "media/mojo/services/media_mojo_export.h" + +namespace media { + +class MojoCdmServiceContext; + +// A mojom::CdmProxy implementation backed by a media::CdmProxy. +class MEDIA_MOJO_EXPORT MojoCdmProxyService : public mojom::CdmProxy, + public CdmProxy::Client { + public: + MojoCdmProxyService(std::unique_ptr<::media::CdmProxy> cdm_proxy, + MojoCdmServiceContext* context); + + ~MojoCdmProxyService() final; + + // mojom::CdmProxy implementation. + void Initialize(mojom::CdmProxyClientAssociatedPtrInfo client, + InitializeCallback callback) final; + void Process(media::CdmProxy::Function function, + uint32_t crypto_session_id, + const std::vector<uint8_t>& input_data, + uint32_t expected_output_data_size, + ProcessCallback callback) final; + void CreateMediaCryptoSession( + const std::vector<uint8_t>& input_data, + CreateMediaCryptoSessionCallback callback) final; + void SetKey(uint32_t crypto_session_id, + const std::vector<uint8_t>& key_id, + const std::vector<uint8_t>& key_blob) final; + void RemoveKey(uint32_t crypto_session_id, + const std::vector<uint8_t>& key_id) final; + + // CdmProxy::Client implementation. + void NotifyHardwareReset() final; + + private: + std::unique_ptr<::media::CdmProxy> cdm_proxy_; + MojoCdmServiceContext* context_ = nullptr; + + mojom::CdmProxyClientAssociatedPtr client_; + + DISALLOW_COPY_AND_ASSIGN(MojoCdmProxyService); +}; + +} // namespace media + +#endif // MEDIA_MOJO_SERVICES_MOJO_CDM_PROXY_SERVICE_H_
diff --git a/media/mojo/services/mojo_media_client.cc b/media/mojo/services/mojo_media_client.cc index f7fe3b8..315a3da 100644 --- a/media/mojo/services/mojo_media_client.cc +++ b/media/mojo/services/mojo_media_client.cc
@@ -13,6 +13,10 @@ #include "media/base/video_decoder.h" #include "media/base/video_renderer_sink.h" +#if BUILDFLAG(ENABLE_LIBRARY_CDMS) +#include "media/cdm/cdm_proxy.h" +#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) + namespace media { MojoMediaClient::MojoMediaClient() = default; @@ -56,6 +60,12 @@ return nullptr; } +#if BUILDFLAG(ENABLE_LIBRARY_CDMS) +std::unique_ptr<CdmProxy> MojoMediaClient::CreateCdmProxy() { + return nullptr; +} +#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) + #if BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION) void MojoMediaClient::AddCdmHostFilePaths( std::vector<media::CdmHostFilePath>* /* cdm_host_file_paths */) {}
diff --git a/media/mojo/services/mojo_media_client.h b/media/mojo/services/mojo_media_client.h index a8a18e7..37ac277 100644 --- a/media/mojo/services/mojo_media_client.h +++ b/media/mojo/services/mojo_media_client.h
@@ -32,6 +32,7 @@ class AudioDecoder; class AudioRendererSink; class CdmFactory; +class CdmProxy; class MediaLog; class RendererFactory; class VideoDecoder; @@ -82,6 +83,12 @@ virtual std::unique_ptr<CdmFactory> CreateCdmFactory( service_manager::mojom::InterfaceProvider* host_interfaces); +#if BUILDFLAG(ENABLE_LIBRARY_CDMS) + // Creates a CdmProxy that proxies part of CDM functionalities to a different + // entity, e.g. hardware CDM modules. + virtual std::unique_ptr<CdmProxy> CreateCdmProxy(); +#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) + #if BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION) // Gets a list of CDM host file paths and put them in |cdm_host_file_paths|. virtual void AddCdmHostFilePaths(
diff --git a/media/video/BUILD.gn b/media/video/BUILD.gn index d04a6484..c5aacea 100644 --- a/media/video/BUILD.gn +++ b/media/video/BUILD.gn
@@ -45,8 +45,11 @@ ] } - deps = [ + public_deps = [ "//gpu/command_buffer/client:gles2_interface", + ] + + deps = [ "//gpu/command_buffer/common", "//media/base", "//third_party/libyuv",
diff --git a/net/BUILD.gn b/net/BUILD.gn index d083b7a..35cacac 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -2476,11 +2476,11 @@ "data/ssl/certificates/prime256v1-ecdsa-ee-by-prime256v1-ecdsa-intermediate.pem", "data/ssl/certificates/prime256v1-ecdsa-intermediate.pem", "data/ssl/certificates/punycodetest.pem", + "data/ssl/certificates/quic-cert.key", + "data/ssl/certificates/quic-chain.pem", + "data/ssl/certificates/quic-root.pem", "data/ssl/certificates/quic_chain.crt", - "data/ssl/certificates/quic_intermediate.crt", - "data/ssl/certificates/quic_intermediate.key", "data/ssl/certificates/quic_root.crt", - "data/ssl/certificates/quic_root.key", "data/ssl/certificates/quic_test.example.com.crt", "data/ssl/certificates/quic_test.example.com.key", "data/ssl/certificates/quic_test.example.com.key.pkcs8", @@ -5329,6 +5329,7 @@ if (enable_reporting) { sources += [ + "network_error_logging/network_error_logging_end_to_end_test.cc", "network_error_logging/network_error_logging_service_unittest.cc", "reporting/reporting_browsing_data_remover_unittest.cc", "reporting/reporting_cache_unittest.cc",
diff --git a/net/data/ssl/certificates/README b/net/data/ssl/certificates/README index e703162..bb2e779 100644 --- a/net/data/ssl/certificates/README +++ b/net/data/ssl/certificates/README
@@ -114,12 +114,17 @@ NSS certificate nickname for a user certificate. This certificate's Subject field doesn't have a common name. -- quic_intermediate.crt - quic_test_ecc.example.com.crt - quic_test.example.com.crt - quic_root.crt These certificates are used by the ProofVerifier's unit tests of QUIC. +===== From net/data/ssl/scripts/generate-quic-chain.sh +- quic-cert.key +- quic-chain.pem +- quic-root.pem + These certificates are used by integration tests that use QUIC. + ===== From net/data/ssl/scripts/generate-test-certs.sh - expired_cert.pem - ok_cert.pem
diff --git a/net/data/ssl/certificates/quic-cert.key b/net/data/ssl/certificates/quic-cert.key new file mode 100644 index 0000000..e509d72 --- /dev/null +++ b/net/data/ssl/certificates/quic-cert.key Binary files differ
diff --git a/net/data/ssl/certificates/quic-chain.pem b/net/data/ssl/certificates/quic-chain.pem new file mode 100644 index 0000000..ab0893b --- /dev/null +++ b/net/data/ssl/certificates/quic-chain.pem
@@ -0,0 +1,147 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=Test Intermediate CA + Validity + Not Before: Dec 18 23:44:03 2017 GMT + Not After : Dec 16 23:44:03 2027 GMT + Subject: CN=test.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b2:56:6f:7e:d4:b4:b6:4e:e3:15:8e:8a:e9:46: + 06:15:63:4c:6d:3a:32:67:c7:14:a4:17:fc:b7:04: + 98:fb:b5:11:ae:93:1c:20:73:15:cd:b3:bc:ee:61: + 82:8e:cb:b8:78:ca:6d:e6:57:73:f3:45:6e:1e:c3: + 27:5d:af:5e:52:6d:12:47:44:72:3d:7d:8a:c1:47: + 50:19:4a:21:a4:08:b4:cc:2e:9c:a2:2a:ce:1b:87: + 82:ae:3a:23:b0:dd:d2:3e:64:fe:ce:a6:35:34:93: + 07:f8:88:6e:c8:be:b2:0b:5f:9c:96:0e:79:1c:a3: + 2b:c9:23:5a:8a:1f:1e:17:e2:a9:d4:3c:49:22:29: + 43:fa:63:55:3c:72:62:4a:d1:72:5a:ae:75:a8:14: + 67:eb:58:88:ce:11:0c:bf:09:67:f2:bb:c8:80:3e: + 4a:f0:35:ad:d2:dc:43:a3:2f:da:c6:3b:1c:6e:76: + 70:31:73:cc:33:5b:4f:36:dc:f3:8f:9f:a6:07:6d: + 61:e0:66:6f:2c:76:bd:85:a3:8b:d0:8a:ce:c4:bc: + 97:e0:ed:e1:29:df:a1:62:b9:ad:d8:0f:1a:f8:ae: + 44:fe:a6:28:95:c4:cc:df:b5:f7:6d:46:ae:ef:9b: + af:73:50:1d:9f:f0:c7:a0:ef:37:4b:13:73:96:24: + 95:0f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + X509v3 Subject Alternative Name: + DNS:test.example.com + Signature Algorithm: sha256WithRSAEncryption + bd:55:54:e5:ac:2b:e6:6f:c9:45:b7:77:97:af:37:e6:6b:60: + cb:51:0f:b0:2c:40:71:39:73:7a:0b:6f:37:a5:cc:40:4f:d1: + 43:3d:8e:1d:37:ba:ff:2d:7b:80:21:fd:ec:e4:7c:20:6a:ce: + 6e:28:9b:c1:4e:9e:1e:17:1f:cb:04:61:c1:d0:72:0c:31:f6: + ee:2b:a9:9c:29:6b:45:bd:97:57:a6:25:f3:f0:6b:08:3f:4e: + 00:33:cf:47:3b:50:4a:15:a7:a0:c8:e0:8b:86:7b:48:3e:39: + 15:00:0a:aa:79:3c:8d:fd:d7:4a:68:2f:05:2b:60:2a:d1:7e: + 1c:bc:06:e9:b7:51:35:71:d7:6b:f4:b8:f3:17:d7:f1:d4:8d: + f8:0e:4a:11:34:4d:d9:19:70:33:0a:66:e6:4c:11:93:90:5c: + 5d:a1:f3:8a:1c:ce:0c:12:5e:a9:6b:e1:1f:eb:b3:65:b8:bc: + 1a:48:af:cc:af:fc:db:3e:0b:32:47:8d:fc:ed:b3:50:9a:65: + b8:19:eb:db:18:21:5f:e4:1d:c5:87:57:9b:5a:8a:59:16:84: + 8d:27:3e:f9:7a:c0:fa:e7:84:90:da:1a:03:98:b5:c6:a9:52: + ed:df:0e:7a:02:c7:e6:82:d2:06:cb:97:75:90:89:d6:d1:cf: + 43:74:09:f7 +-----BEGIN CERTIFICATE----- +MIIDATCCAemgAwIBAgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0 +IEludGVybWVkaWF0ZSBDQTAeFw0xNzEyMTgyMzQ0MDNaFw0yNzEyMTYyMzQ0MDNa +MBsxGTAXBgNVBAMMEHRlc3QuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCyVm9+1LS2TuMVjorpRgYVY0xtOjJnxxSkF/y3BJj7tRGu +kxwgcxXNs7zuYYKOy7h4ym3mV3PzRW4ewyddr15SbRJHRHI9fYrBR1AZSiGkCLTM +LpyiKs4bh4KuOiOw3dI+ZP7OpjU0kwf4iG7IvrILX5yWDnkcoyvJI1qKHx4X4qnU +PEkiKUP6Y1U8cmJK0XJarnWoFGfrWIjOEQy/CWfyu8iAPkrwNa3S3EOjL9rGOxxu +dnAxc8wzW0823POPn6YHbWHgZm8sdr2Fo4vQis7EvJfg7eEp36Fiua3YDxr4rkT+ +piiVxMzftfdtRq7vm69zUB2f8Meg7zdLE3OWJJUPAgMBAAGjTDBKMAwGA1UdEwEB +/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBsGA1UdEQQUMBKC +EHRlc3QuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBAL1VVOWsK+ZvyUW3 +d5evN+ZrYMtRD7AsQHE5c3oLbzelzEBP0UM9jh03uv8te4Ah/ezkfCBqzm4om8FO +nh4XH8sEYcHQcgwx9u4rqZwpa0W9l1emJfPwawg/TgAzz0c7UEoVp6DI4IuGe0g+ +ORUACqp5PI3910poLwUrYCrRfhy8Bum3UTVx12v0uPMX1/HUjfgOShE0TdkZcDMK +ZuZMEZOQXF2h84oczgwSXqlr4R/rs2W4vBpIr8yv/Ns+CzJHjfzts1CaZbgZ69sY +IV/kHcWHV5tailkWhI0nPvl6wPrnhJDaGgOYtcapUu3fDnoCx+aC0gbLl3WQidbR +z0N0Cfc= +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=Test Root CA + Validity + Not Before: Dec 18 23:44:03 2017 GMT + Not After : Dec 16 23:44:03 2027 GMT + Subject: CN=Test Intermediate CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e4:cd:89:4c:65:4f:4d:68:bd:2a:7a:4f:0b:10: + 3f:02:d6:2a:5b:5b:76:c8:97:59:67:19:6e:95:45: + c3:38:a4:c7:29:f5:f7:95:52:97:a3:01:19:b2:b3: + ec:09:97:08:4f:f1:db:43:67:50:59:ac:ca:9a:05: + 56:fc:73:42:f3:90:e1:e5:3e:03:75:35:33:d2:df: + aa:3d:f8:ca:16:5e:7e:ef:01:9c:2a:30:eb:c7:cc: + 06:04:90:14:c0:54:f5:96:22:26:30:39:73:c5:c0: + 9d:0d:b0:9f:b0:e5:cf:f6:b1:0c:10:ab:f0:c9:54: + a6:30:d5:b4:fd:a7:23:7f:1e:57:7b:72:d7:af:0d: + a2:3e:4d:b2:c5:51:70:2a:06:2f:66:21:ca:7f:7d: + 6b:60:24:5e:ed:5f:74:ee:4b:b1:f1:ec:54:a0:fb: + 89:05:69:94:78:9b:a4:85:8c:ea:e6:b5:d6:fd:c5: + 6d:98:28:e4:1d:81:1b:26:3b:21:c2:e4:df:bd:a1: + 0d:51:35:40:43:a0:a4:00:66:fa:97:46:d6:9d:95: + ca:da:62:f8:c7:60:6c:e4:89:c2:d0:74:30:fe:2a: + db:54:95:5b:68:5f:ca:bd:e9:af:27:13:fc:c4:6f: + e6:5d:05:92:cc:bc:e4:76:8a:2e:34:0b:5e:39:11: + 75:57 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + Signature Algorithm: sha256WithRSAEncryption + 60:4e:38:f3:7b:00:46:75:8f:d0:4e:08:76:2d:ed:9f:bf:cc: + 50:1b:bf:e4:6d:76:50:fe:fa:7d:46:90:1c:75:f1:3f:47:19: + eb:02:38:cb:3e:56:0f:8f:09:ae:a8:42:d0:e6:5a:31:54:24: + b2:fe:4b:a2:e4:44:14:64:44:d8:50:12:62:4a:06:60:29:22: + 95:bb:c8:7e:dd:d4:7d:a6:dd:3c:0d:fb:71:67:6f:9b:49:05: + 09:7c:5c:63:2b:df:71:aa:ae:92:28:98:73:c2:60:b6:54:10: + f6:f5:54:d6:93:0a:22:56:0a:fd:45:8a:a4:d7:a7:21:df:f5: + 53:07:1c:3b:63:c1:7c:4e:f0:3d:5c:c4:c9:cc:55:ae:ec:fb: + 2e:4f:b0:f9:5b:1d:c3:46:ba:38:f6:ff:8d:b3:3b:d0:7d:15: + 3f:fd:6a:bd:a1:59:18:ff:57:fc:d6:c0:3d:7e:75:61:ff:13: + 09:81:5f:38:82:22:78:78:97:5e:e6:7c:fb:16:a8:92:40:97: + eb:7c:a5:37:da:ca:5f:28:69:e4:63:b7:07:61:ad:e8:5a:e8: + 06:55:c0:34:7c:30:66:1e:9a:7e:ed:cb:c8:14:c1:e3:b3:ac: + 8d:89:9c:6b:b1:ea:eb:71:94:c0:1d:63:b7:d9:82:74:13:0c: + ee:8a:ca:dc +-----BEGIN CERTIFICATE----- +MIIC1DCCAbygAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxUZXN0 +IFJvb3QgQ0EwHhcNMTcxMjE4MjM0NDAzWhcNMjcxMjE2MjM0NDAzWjAfMR0wGwYD +VQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAOTNiUxlT01ovSp6TwsQPwLWKltbdsiXWWcZbpVFwzikxyn195VS +l6MBGbKz7AmXCE/x20NnUFmsypoFVvxzQvOQ4eU+A3U1M9Lfqj34yhZefu8BnCow +68fMBgSQFMBU9ZYiJjA5c8XAnQ2wn7Dlz/axDBCr8MlUpjDVtP2nI38eV3ty168N +oj5NssVRcCoGL2Yhyn99a2AkXu1fdO5LsfHsVKD7iQVplHibpIWM6ua11v3FbZgo +5B2BGyY7IcLk372hDVE1QEOgpABm+pdG1p2Vytpi+MdgbOSJwtB0MP4q21SVW2hf +yr3prycT/MRv5l0Fksy85HaKLjQLXjkRdVcCAwEAAaMjMCEwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAGBOOPN7AEZ1 +j9BOCHYt7Z+/zFAbv+RtdlD++n1GkBx18T9HGesCOMs+Vg+PCa6oQtDmWjFUJLL+ +S6LkRBRkRNhQEmJKBmApIpW7yH7d1H2m3TwN+3Fnb5tJBQl8XGMr33GqrpIomHPC +YLZUEPb1VNaTCiJWCv1FiqTXpyHf9VMHHDtjwXxO8D1cxMnMVa7s+y5PsPlbHcNG +ujj2/42zO9B9FT/9ar2hWRj/V/zWwD1+dWH/EwmBXziCInh4l17mfPsWqJJAl+t8 +pTfayl8oaeRjtwdhreha6AZVwDR8MGYemn7ty8gUweOzrI2JnGux6utxlMAdY7fZ +gnQTDO6Kytw= +-----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/quic-root.pem b/net/data/ssl/certificates/quic-root.pem new file mode 100644 index 0000000..f25cd2ee --- /dev/null +++ b/net/data/ssl/certificates/quic-root.pem
@@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1DCCAbygAwIBAgIJANU1FI5oBbmLMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV +BAMMDFRlc3QgUm9vdCBDQTAeFw0xNzEyMTgyMzQ0MDNaFw0yNzEyMTYyMzQ0MDNa +MBcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALqSSRbDX0cmxTOeBh4qqMtw8BA7J8l6CYZqeUgigR67xAvJGEqx +WhYDBjodWIYucrwqkRuju1ufRXVNAD8rqs47db5NPDHH+FqN33RkSa9XIdOGdnHX +NfCQ13Vpq9tnvZ3zCzvSWXDVYz6GcCBJ51tjWNZtX8O8N179HcVef3LhBGweAJJv ++FkOLiClZ1y2A5hfdmuYmIYy2Iwc7we/R6jm+Ns0pVA8NrLicEHzrxJLMlMD5+zd +WjkY6Bv9OdPipmEr1/EP3957bZ7uIUZWEq79SnQ90sKkMVS+q7Ckz7PdMBJI+fZc +HsjucLXL0tysbcF+CtYqHsbrazye0yERUFECAwEAAaMjMCEwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAJZRG2cJGaGF +Tl8H6+SltT9dlZ//Z7ZNsWEfv8xehGrRHsV2kxXvuVf1K4EpP3FAEvDJgOvP1MkA +rmcpI9SsY4cr0Zy/s+Ez8SwespXkSKvtCXCmq9/kpadFPDWwR1NAXVzSEuhXJxDR +bA+boLCu6rMFbkoRi/aFYzro+9m8RsXlyYGVGspov411lu56huoJ3ooGTIfQM8or +N6ZNWkb+RTUUj29o3qr3kiQv73mB6h47/3IkYC5mITl+vK3OtwIRwjLzXZuS40/W +RlI+SRYG4/yTzgV1DB4JlVJl4qMsF3z1zY1P7WeCU4YqZoIam/Ig/ZzxfOFTczk8 +vw1/E4YbkfE= +-----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/quic_intermediate.crt b/net/data/ssl/certificates/quic_intermediate.crt deleted file mode 100644 index 29e3a66..0000000 --- a/net/data/ssl/certificates/quic_intermediate.crt +++ /dev/null
@@ -1,75 +0,0 @@ -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 2 (0x2) - Signature Algorithm: sha1WithRSAEncryption - Issuer: O=Acme Co, CN=Root CA - Validity - Not Before: Jan 1 10:00:00 2013 GMT - Not After : Dec 31 10:00:00 2023 GMT - Subject: O=Acme Co, CN=Intermediate CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:cd:35:50:e7:0a:68:80:e5:2b:f0:01:2b:93:11: - 0c:50:f7:23:e1:d8:d2:ed:48:9a:ea:3b:64:9f:82: - fa:e4:ad:23:96:a8:a1:9b:31:d1:d6:4a:b2:79:f1: - c1:80:03:18:41:54:a5:30:3a:82:bd:57:10:9c:fd: - 5d:34:fd:19:d3:21:1b:cb:06:e7:66:40:e1:27:89: - 98:82:2d:d7:2e:0d:5c:05:9a:74:0d:45:de:32:5e: - 78:4e:81:b4:c8:60:97:f0:8b:2a:8c:e0:57:f6:b9: - db:5a:53:64:1d:27:e0:93:47:d9:93:ee:ac:f6:7b: - e7:d2:97:b1:a6:85:37:75:ff:aa:f7:8f:ae:92:4e: - 30:0b:56:54:fd:32:f9:9d:3c:d8:2e:95:f5:64:17: - ff:26:d2:65:e2:b1:78:6c:83:5d:67:a4:d8:ae:89: - 6b:6e:b3:4b:35:a5:b1:03:3c:20:97:79:ed:0b:f8: - de:25:a1:3a:50:70:40:ae:9e:04:75:a2:6a:2f:15: - 84:5b:08:c3:e0:55:4e:47:db:bc:79:25:b0:2e:58: - 0d:bc:aa:a6:f2:ee:cd:e6:b8:02:8c:5b:00:b3:3d: - 44:d0:a6:bf:b3:e7:2e:9d:46:70:de:45:d1:bd:79: - bd:c0:f2:47:0b:71:28:60:91:c2:98:73:15:2d:b4: - b1:f3 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Certificate Sign - X509v3 Extended Key Usage: - TLS Web Server Authentication - X509v3 Basic Constraints: critical - CA:TRUE - Signature Algorithm: sha1WithRSAEncryption - b5:66:2c:a1:f8:76:8a:3b:6c:06:2d:d5:1e:4b:25:5c:b8:6d: - ee:0e:7e:09:a4:43:58:65:93:e9:da:6c:42:2e:5d:74:3f:79: - 61:4d:e5:72:45:d7:2d:fd:73:8e:e2:98:fe:8e:4a:e4:11:6e: - 94:5c:d9:84:c9:cb:a1:1c:fa:95:d9:15:c1:87:72:98:2e:63: - df:67:4d:04:1f:da:d7:29:66:ec:20:ea:b6:5d:71:dd:bc:5a: - 16:55:87:8f:51:9f:40:05:00:3b:21:ee:74:bc:3b:11:9a:10: - ba:b4:e8:5e:6e:90:c3:22:ca:da:92:f8:fb:8e:73:fd:69:91: - 13:48:11:01:58:ae:f4:b2:8c:38:56:f0:a5:3b:2a:64:5c:25: - 9a:bb:fd:94:27:34:af:b4:21:4c:08:23:3c:fb:3f:08:6f:07: - b8:05:9d:85:1d:73:0e:f0:83:f4:3c:9b:cc:aa:fd:3d:fa:82: - a4:dd:01:10:9d:10:2c:c4:47:64:ca:b4:b5:6e:be:59:d1:d2: - a1:6a:b5:d3:08:23:49:fc:4f:d4:f3:a5:63:b5:e1:34:19:9d: - 8c:33:0f:8e:47:01:9a:eb:2a:eb:cb:f4:1a:0c:ee:8e:68:d3: - c1:8e:fd:4b:93:ff:40:8c:3a:11:2b:62:a3:c1:a7:13:bd:26: - 37:c5:85:c5 ------BEGIN CERTIFICATE----- -MIIC/zCCAemgAwIBAgIBAjALBgkqhkiG9w0BAQUwJDEQMA4GA1UEChMHQWNtZSBD -bzEQMA4GA1UEAxMHUm9vdCBDQTAeFw0xMzAxMDExMDAwMDBaFw0yMzEyMzExMDAw -MDBaMCwxEDAOBgNVBAoTB0FjbWUgQ28xGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBD -QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM01UOcKaIDlK/ABK5MR -DFD3I+HY0u1Imuo7ZJ+C+uStI5aooZsx0dZKsnnxwYADGEFUpTA6gr1XEJz9XTT9 -GdMhG8sG52ZA4SeJmIIt1y4NXAWadA1F3jJeeE6BtMhgl/CLKozgV/a521pTZB0n -4JNH2ZPurPZ759KXsaaFN3X/qvePrpJOMAtWVP0y+Z082C6V9WQX/ybSZeKxeGyD -XWek2K6Ja26zSzWlsQM8IJd57Qv43iWhOlBwQK6eBHWiai8VhFsIw+BVTkfbvHkl -sC5YDbyqpvLuzea4AoxbALM9RNCmv7PnLp1GcN5F0b15vcDyRwtxKGCRwphzFS20 -sfMCAwEAAaM4MDYwDgYDVR0PAQH/BAQDAgAEMBMGA1UdJQQMMAoGCCsGAQUFBwMB -MA8GA1UdEwEB/wQFMAMBAf8wCwYJKoZIhvcNAQEFA4IBAQC1Ziyh+HaKO2wGLdUe -SyVcuG3uDn4JpENYZZPp2mxCLl10P3lhTeVyRdct/XOO4pj+jkrkEW6UXNmEycuh -HPqV2RXBh3KYLmPfZ00EH9rXKWbsIOq2XXHdvFoWVYePUZ9ABQA7Ie50vDsRmhC6 -tOhebpDDIsrakvj7jnP9aZETSBEBWK70sow4VvClOypkXCWau/2UJzSvtCFMCCM8 -+z8Ibwe4BZ2FHXMO8IP0PJvMqv09+oKk3QEQnRAsxEdkyrS1br5Z0dKharXTCCNJ -/E/U86VjteE0GZ2MMw+ORwGa6yrry/QaDO6OaNPBjv1Lk/9AjDoRK2KjwacTvSY3 -xYXF ------END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/quic_intermediate.key b/net/data/ssl/certificates/quic_intermediate.key deleted file mode 100644 index a8d1b8cf..0000000 --- a/net/data/ssl/certificates/quic_intermediate.key +++ /dev/null
@@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAzTVQ5wpogOUr8AErkxEMUPcj4djS7Uia6jtkn4L65K0jlqih -mzHR1kqyefHBgAMYQVSlMDqCvVcQnP1dNP0Z0yEbywbnZkDhJ4mYgi3XLg1cBZp0 -DUXeMl54ToG0yGCX8IsqjOBX9rnbWlNkHSfgk0fZk+6s9nvn0pexpoU3df+q94+u -kk4wC1ZU/TL5nTzYLpX1ZBf/JtJl4rF4bINdZ6TYrolrbrNLNaWxAzwgl3ntC/je -JaE6UHBArp4EdaJqLxWEWwjD4FVOR9u8eSWwLlgNvKqm8u7N5rgCjFsAsz1E0Ka/ -s+cunUZw3kXRvXm9wPJHC3EoYJHCmHMVLbSx8wIDAQABAoIBAQCSQevVoA93vt8g -AlWCTmZO1raWY6mCQXtYcth28C3OCrEQ0kPMjyeV6ktmqq5VhN8mwSOzSiCgvosy -uUpTWAmt9y0N+W+364oOWf1+2xlA03jA7aLFSwThNX/dxIiLQH1KjoXXPpazXShA -KqtyNFfV4SHsU/KnAwzphgCyRMSQrk/5YZfdfkbnhKhXGtdBmja+4wB7khOcv5Vb -+S2FAxftWdyTo3AOSwSED5Evq8gML4RWl46bZ5r2Gu6W+eBxDyRT+iftNLOMO6PL -7ivn3mbZSBUxOZPvKNh6sxrUsSnxUrcZ5d819yiRolKywY5lM+BrqP9CFMfEKFP9 -R9zooJdhAoGBAOLXZviVGzOgLB418GKkw5NReeiKNPPX+w7vX+VYTiw60yRf87iS -RhgqTXQDYKExgOO/giEJ0M3VJ6RU8MqqeHtDoKPjzZmGXs/zB0WSPIYa1A4QjQHO -UNE1OvTwxHQCKZg0u46AZMnZWHpt005iVQ4LG8uHpUYdYxLn0LfPTvWpAoGBAOeW -Cecnv/1GU5ft4Y8LDlFzwFzgRjRBMuX8erQz6lJUlnWLq/ZwSbag0qK+9iVfrvUT -F9zNpfgFFsyMI8OPeJsEJkvQEZA4XDEZyvZCstjxWvI81T1bnc1/JU+YeaFcqSDq -X7+ARNquoH9ntbXRRW4ACafQdY3KNqeBCpKBlfQ7AoGAVK/cNoPcMuribajvhLRE -e7RYUfN/D2YbyZiecY4FKUgQ2ayk3cxmNNFeNyino6ZKmzw9Bb6XYLDqatR3TQJV -lpdJ2sXKVT2wGex+U3/j7qEHd/S/3+O5klFQIG/et/yysKtHNk1C04S8HoDv+XyG -ioalKtgKYOHJwh4fcvAHZ3kCgYAen25rzIvMl/IR0vjSi2m3R5EWNunRmxV55+rp -zTuc62aB4Jg6nBqDNbzknE+8HWzrJz0ui1r48uNS5O0NvPj7to7B05+e7HT0YS6/ -ZY50tWWLRpQD6wtw0vFCFy1uMuyCV7uVfQadzB2Y+0PB6Qw/QW4FbME+oJCdkaiu -OshzZQKBgQCXKYjh2fwBozDn7u8OQZ6sJt74EOZqAMfv7NQ2xbD5Jg5ABnOcFrXu -FWvE9KoiJYmDD26lFIbmQ9KlAsQjKrOiRit50IALrlfATRYpEGnlO8M+c209+5wx -FVncGUcoKbzLIrIJz7Cfd3MLbB8wSO8RBpeTa0IU5XhkTnk130Ue7A== ------END RSA PRIVATE KEY-----
diff --git a/net/data/ssl/certificates/quic_root.key b/net/data/ssl/certificates/quic_root.key deleted file mode 100644 index 9791d1fd..0000000 --- a/net/data/ssl/certificates/quic_root.key +++ /dev/null
@@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEA5CuRx32rMrc44TiuyLkLFRxkdkeEXcvn5wwwd4RqjnWVQrJ4 -yIgQrJhHlzjROn+GDSDxHXCEop3tGiivXkPdMaO7uFzEg3m4g5rnqWMEWZO2Jmct -3eYtu+QT69UXC95jRnZvEAVAsBb86vSXHNbc/jdy1UDf47TVrM/JrnwhSQEeftTB -4SoRAbRwOjE9mjO3fyDyi+dUjgbyS1/w4rmPZB9QvbOlrGlEQmwS6RGddLRJd+MP -i5yUUxcMI7ph+nA9k42tX91PMoRbB1DkWMcARYIfIRRMv0OSdvskCTPfWI2+h+61 -VOTTMvaxLWl0hq0fV36bBRF0tcRorJqAdHo0iQIDAQABAoIBAC9L/Mb+fMthgY/m -IQ0IloyEuyptfrm2t9aEB1PvBeuL4inWNwVSdypf0o89PtnCb3YvOuvgVA4lcG24 -u0luBd7xUstPp4idZasaJCVPmio7XUmun6pcuWQ2Tg7XuBREwA1uJW2LuTIHQdwu -YVigDWVA9zPPY9metaBB3kul/XxVM7+fXheCHzXTzJEaAw+7Gexe8QYuq4ftcocD -f7O/j/ts3IrKa1Xrl5RFC/tCNwpZ3yrp/Scdit32wbvCQwcdZ6/dDu6BWY4GJm8q -z7kaDZkXQa50EzT9g+DPTLC3qA2USh8M+NfqVjdHYkAqj64StCjvXHboTbDdZXoz -HvsONNUCgYEA/THRfqRpRPHW9ONSyRma6+XtzrCepVn/ceguO9bfD0e2+l1/6uXQ -hctuwelRD89Z6Ir5kW2I8fRT0mPhCcuv5TW1hOiwK6WKasYxRu3ox+bZiAoRsEBd -Xm4bvr814E/QO5DsDd5KMdEPb6ulStI1y94atCjX50r+vZWMGG82dK8CgYEA5rLF -FPBt+049Wq8bIXXVbInwPD0hHeIrhfTqsDeuLwYsmf7o29dU7sjDFS5x1cCfVsqO -UpXM5J4C3lhDC9ZTX0vVgT/TROq7etRZeBHVN+CJS0jgeMjUqWQTZYPMzE0Bu8/P -+9mqSZzkwipesG4JpdSkt/1IOIoDrbK8mYpDqEcCgYEA5wfGOOCcjaR+mAW1THpo -ukebrrXKjOaKB83sIf32m2K8u8cFKbl5hBwUfCwBI4P4bhAhmWlxRBXFRnyMovuR -DHztnNEVrz3mB3fBDw+XEJC8fT1y1nhkuf2Oo4amCn/JahDa0+y5lqtEgokE0jjt -jZCknS+Hki0ENMl4g/M2pVECgYB8oF6vbSM8+4tRjf8OGGXveKT7JdraFfCFMUYH -ZE0IwkEeAAMzoCQVywb4TlrYqnJppIs2Og6yAlpyWyP9JQ9tD76LUDuFo3kcZdLf -dmLFCNuifAAnv/aCe7muwYDFbWReXWlyGKhRlBxQeCsnDIrRtwo1CvMU+Bn8n+4a -1AKwyQKBgGpBZwN28VjqYkM5fO6RDNBvgQ1ApfSh/Kfwg0MrO8uhmvlWDuWCoei4 -v08pchPRO75ktIv4r9bR7ylTpB9JhCe2kNABWma4mnlUg4+nmiWMTZo6Pyabstkt -yzGIGZYdMDzOBjph7JxQZhGijz3uVc9CiFg+2AElbpCYDRHn5N3s ------END RSA PRIVATE KEY-----
diff --git a/net/data/ssl/scripts/generate-quic-chain.sh b/net/data/ssl/scripts/generate-quic-chain.sh new file mode 100755 index 0000000..84c0bb4c --- /dev/null +++ b/net/data/ssl/scripts/generate-quic-chain.sh
@@ -0,0 +1,96 @@ +#!/bin/sh + +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This script generates a test chain of (end-entity, intermediate, root) +# certificates used to run a test QUIC server. + +try() { + "$@" || (e=$?; echo "$@" > /dev/stderr; exit $e) +} + +try rm -rf out +try mkdir out + +# Create the serial number files. +try /bin/sh -c "echo 01 > out/quic-test-root-serial" +try /bin/sh -c "echo 01 > out/quic-test-intermediate-serial" + +# Create the signers' DB files. +touch out/quic-test-root-index.txt +touch out/quic-test-intermediate-index.txt + +# Generate the keys +try openssl genrsa -out out/quic-test-root.key 2048 +try openssl genrsa -out out/quic-test-intermediate.key 2048 +try openssl genrsa -out out/quic-test-cert.key 2048 + +# Generate the root certificate +CA_COMMON_NAME="Test Root CA" \ + CA_DIR=out \ + CA_NAME=test-root \ + try openssl req \ + -new \ + -key out/quic-test-root.key \ + -out out/quic-test-root.csr \ + -config quic-test.cnf + +CA_COMMON_NAME="Test Root CA" \ + CA_DIR=out \ + CA_NAME=quic-test-root \ + try openssl x509 \ + -req -days 3650 \ + -in out/quic-test-root.csr \ + -out out/quic-test-root.pem \ + -signkey out/quic-test-root.key \ + -extfile quic-test.cnf \ + -extensions ca_cert \ + -text + +# Generate the intermediate +CA_COMMON_NAME="Test Intermediate CA" \ + CA_DIR=out \ + CA_NAME=quic-test-root \ + try openssl req \ + -new \ + -key out/quic-test-intermediate.key \ + -out out/quic-test-intermediate.csr \ + -config quic-test.cnf + +CA_COMMON_NAME="Test Intermediate CA" \ + CA_DIR=out \ + CA_NAME=quic-test-root \ + try openssl ca \ + -batch \ + -in out/quic-test-intermediate.csr \ + -out out/quic-test-intermediate.pem \ + -config quic-test.cnf \ + -extensions ca_cert + +# Generate the leaf +CA_COMMON_NAME="test.example.com" \ +CA_DIR=out \ +CA_NAME=quic-test-intermediate \ +try openssl req \ + -new \ + -key out/quic-test-cert.key \ + -out out/quic-test-cert.csr \ + -config quic-test.cnf + +CA_COMMON_NAME="Test Intermediate CA" \ + HOST_NAME="test.example.com" \ + CA_DIR=out \ + CA_NAME=quic-test-intermediate \ + try openssl ca \ + -batch \ + -in out/quic-test-cert.csr \ + -out out/quic-test-cert.pem \ + -config quic-test.cnf \ + -extensions user_cert + +# Copy to the file names that are actually checked in. +try openssl pkcs8 -topk8 -inform pem -outform der -in out/quic-test-cert.key -out ../certificates/quic-cert.key -nocrypt +try cat out/quic-test-cert.pem out/quic-test-intermediate.pem > ../certificates/quic-chain.pem +try cp out/quic-test-root.pem ../certificates/quic-root.pem
diff --git a/net/data/ssl/scripts/quic-test.cnf.txt b/net/data/ssl/scripts/quic-test.cnf.txt new file mode 100644 index 0000000..13ad8d9c --- /dev/null +++ b/net/data/ssl/scripts/quic-test.cnf.txt
@@ -0,0 +1,54 @@ +CA_DIR=out +CA_NAME=quic-test-root +HOST_NAME=test.example.com + +[ca] +default_ca = CA_root +preserve = yes + +[CA_root] +dir = ${ENV::CA_DIR} +key_size = 2048 +algo = sha256 +database = $dir/${ENV::CA_NAME}-index.txt +new_certs_dir = $dir +serial = $dir/${ENV::CA_NAME}-serial +certificate = $dir/${ENV::CA_NAME}.pem +private_key = $dir/${ENV::CA_NAME}.key +RANDFILE = $dir/.rand +default_days = 3650 +default_crl_days = 30 +default_md = sha256 +policy = policy_anything +unique_subject = no +copy_extensions = copy + +[user_cert] +basicConstraints = critical, CA:false +extendedKeyUsage = serverAuth, clientAuth +subjectAltName = DNS:${ENV::HOST_NAME} + +[ca_cert] +basicConstraints = critical, CA:true +keyUsage = critical, keyCertSign, cRLSign + +[policy_anything] +# Default signing policy +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = optional +emailAddress = optional + +[req] +default_bits = 2048 +default_md = sha256 +string_mask = utf8only +prompt = no +encrypt_key = no +distinguished_name = req_env_dn + +[req_env_dn] +CN = ${ENV::CA_COMMON_NAME}
diff --git a/net/network_error_logging/network_error_logging_end_to_end_test.cc b/net/network_error_logging/network_error_logging_end_to_end_test.cc new file mode 100644 index 0000000..3da56ed6a --- /dev/null +++ b/net/network_error_logging/network_error_logging_end_to_end_test.cc
@@ -0,0 +1,232 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/macros.h" +#include "base/run_loop.h" +#include "base/strings/stringprintf.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/values_test_util.h" +#include "base/time/time.h" +#include "base/values.h" +#include "build/build_config.h" +#include "net/base/net_errors.h" +#include "net/network_error_logging/network_error_logging_service.h" +#include "net/reporting/reporting_feature.h" +#include "net/reporting/reporting_policy.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_request.h" +#include "net/test/embedded_test_server/http_response.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_builder.h" +#include "net/url_request/url_request_status.h" +#include "net/url_request/url_request_test_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if defined(OS_LINUX) || defined(OS_ANDROID) +#include "net/proxy/proxy_config.h" +#include "net/proxy/proxy_config_service_fixed.h" +#endif // defined(OS_LINUX) || defined(OS_ANDROID) + +namespace net { +namespace { + +const char kGroup[] = "network-errors"; +const int kMaxAgeSec = 86400; + +const char kConfigurePath[] = "/configure"; +const char kFailPath[] = "/fail"; +const char kReportPath[] = "/report"; + +class HungHttpResponse : public test_server::HttpResponse { + public: + HungHttpResponse() = default; + + void SendResponse(const test_server::SendBytesCallback& send, + const test_server::SendCompleteCallback& done) override {} + + private: + DISALLOW_COPY_AND_ASSIGN(HungHttpResponse); +}; + +class NetworkErrorLoggingEndToEndTest : public ::testing::Test { + protected: + NetworkErrorLoggingEndToEndTest() + : test_server_(test_server::EmbeddedTestServer::TYPE_HTTPS), + upload_should_hang_(false), + upload_received_(false) { + scoped_feature_list_.InitWithFeatures( + {features::kReporting, features::kNetworkErrorLogging}, {}); + + // Make report delivery happen instantly. + auto policy = std::make_unique<ReportingPolicy>(); + policy->delivery_interval = base::TimeDelta::FromSeconds(0); + + URLRequestContextBuilder builder; +#if defined(OS_LINUX) || defined(OS_ANDROID) + builder.set_proxy_config_service( + std::make_unique<ProxyConfigServiceFixed>(ProxyConfig::CreateDirect())); +#endif // defined(OS_LINUX) || defined(OS_ANDROID) + builder.set_reporting_policy(std::move(policy)); + builder.set_network_error_logging_enabled(true); + url_request_context_ = builder.Build(); + + EXPECT_TRUE(url_request_context_->reporting_service()); + EXPECT_TRUE(url_request_context_->network_error_logging_delegate()); + + test_server_.RegisterRequestHandler(base::BindRepeating( + &NetworkErrorLoggingEndToEndTest::HandleConfigureRequest, + base::Unretained(this))); + test_server_.RegisterRequestHandler( + base::BindRepeating(&NetworkErrorLoggingEndToEndTest::HandleFailRequest, + base::Unretained(this))); + test_server_.RegisterRequestHandler(base::BindRepeating( + &NetworkErrorLoggingEndToEndTest::HandleReportRequest, + base::Unretained(this))); + EXPECT_TRUE(test_server_.Start()); + } + + GURL GetConfigureURL() { return test_server_.GetURL(kConfigurePath); } + + GURL GetFailURL() { return test_server_.GetURL(kFailPath); } + + GURL GetReportURL() { return test_server_.GetURL(kReportPath); } + + std::unique_ptr<test_server::HttpResponse> HandleConfigureRequest( + const test_server::HttpRequest& request) { + if (request.relative_url != kConfigurePath) + return nullptr; + + GURL endpoint_url = GetReportURL(); + + auto response = std::make_unique<test_server::BasicHttpResponse>(); + response->AddCustomHeader( + "Report-To", + base::StringPrintf("{\"url\":\"%s\",\"group\":\"%s\",\"max-age\":%d}", + endpoint_url.spec().c_str(), kGroup, kMaxAgeSec)); + response->AddCustomHeader( + "NEL", base::StringPrintf("{\"report-to\":\"%s\",\"max-age\":%d}", + kGroup, kMaxAgeSec)); + response->set_content_type("text/plain"); + response->set_content(""); + return std::move(response); + } + + std::unique_ptr<test_server::HttpResponse> HandleFailRequest( + const test_server::HttpRequest& request) { + if (request.relative_url != kFailPath) + return nullptr; + + return std::make_unique<test_server::RawHttpResponse>("", ""); + } + + std::unique_ptr<test_server::HttpResponse> HandleReportRequest( + const test_server::HttpRequest& request) { + if (request.relative_url != kReportPath) + return nullptr; + + EXPECT_FALSE(upload_received_); + upload_received_ = true; + + EXPECT_TRUE(request.has_content); + upload_content_ = request.content; + + if (!upload_closure_.is_null()) + std::move(upload_closure_).Run(); + + if (upload_should_hang_) + return std::make_unique<HungHttpResponse>(); + + auto response = std::make_unique<test_server::BasicHttpResponse>(); + response->set_content_type("text/plain"); + response->set_content(""); + return std::move(response); + } + + base::test::ScopedFeatureList scoped_feature_list_; + std::unique_ptr<URLRequestContext> url_request_context_; + test_server::EmbeddedTestServer test_server_; + + bool upload_should_hang_; + bool upload_received_; + std::string upload_content_; + base::OnceClosure upload_closure_; + + private: + DISALLOW_COPY_AND_ASSIGN(NetworkErrorLoggingEndToEndTest); +}; + +TEST_F(NetworkErrorLoggingEndToEndTest, ReportNetworkError) { + TestDelegate configure_delegate; + auto configure_request = url_request_context_->CreateRequest( + GetConfigureURL(), DEFAULT_PRIORITY, &configure_delegate, + TRAFFIC_ANNOTATION_FOR_TESTS); + configure_request->set_method("GET"); + configure_request->Start(); + base::RunLoop().Run(); + EXPECT_TRUE(configure_request->status().is_success()); + + TestDelegate fail_delegate; + auto fail_request = url_request_context_->CreateRequest( + GetFailURL(), DEFAULT_PRIORITY, &fail_delegate, + TRAFFIC_ANNOTATION_FOR_TESTS); + fail_request->set_method("GET"); + fail_request->Start(); + base::RunLoop().Run(); + EXPECT_EQ(URLRequestStatus::FAILED, fail_request->status().status()); + EXPECT_EQ(ERR_EMPTY_RESPONSE, fail_request->status().error()); + + if (!upload_received_) { + base::RunLoop run_loop; + upload_closure_ = run_loop.QuitClosure(); + run_loop.Run(); + } + + auto reports = base::test::ParseJson(upload_content_); + + base::ListValue* reports_list; + ASSERT_TRUE(reports->GetAsList(&reports_list)); + ASSERT_EQ(1u, reports_list->GetSize()); + base::DictionaryValue* report_dict; + ASSERT_TRUE(reports_list->GetDictionary(0u, &report_dict)); + + ExpectDictStringValue("network-error", *report_dict, "type"); + ExpectDictStringValue(GetFailURL().spec(), *report_dict, "url"); + base::DictionaryValue* body_dict; + ASSERT_TRUE(report_dict->GetDictionary("report", &body_dict)); + + ExpectDictStringValue("http.response.empty", *body_dict, "type"); + ExpectDictIntegerValue(0, *body_dict, "status-code"); + ExpectDictStringValue(GetFailURL().spec(), *body_dict, "uri"); +} + +// Make sure an upload that is in progress at shutdown does not crash. +// This verifies that https://crbug.com/792978 is fixed. +TEST_F(NetworkErrorLoggingEndToEndTest, UploadAtShutdown) { + upload_should_hang_ = true; + + TestDelegate configure_delegate; + auto configure_request = url_request_context_->CreateRequest( + GetConfigureURL(), DEFAULT_PRIORITY, &configure_delegate, + TRAFFIC_ANNOTATION_FOR_TESTS); + configure_request->set_method("GET"); + configure_request->Start(); + base::RunLoop().Run(); + EXPECT_TRUE(configure_request->status().is_success()); + + TestDelegate fail_delegate; + auto fail_request = url_request_context_->CreateRequest( + GetFailURL(), DEFAULT_PRIORITY, &fail_delegate, + TRAFFIC_ANNOTATION_FOR_TESTS); + fail_request->set_method("GET"); + fail_request->Start(); + base::RunLoop().RunUntilIdle(); + + // Let Reporting and NEL shut down with the upload still pending to see if + // they crash. +} + +} // namespace +} // namespace net
diff --git a/net/network_error_logging/network_error_logging_service.cc b/net/network_error_logging/network_error_logging_service.cc index e0125fe2..726f49f 100644 --- a/net/network_error_logging/network_error_logging_service.cc +++ b/net/network_error_logging/network_error_logging_service.cc
@@ -171,16 +171,21 @@ if (!reporting_service_) return; - url::Origin origin = url::Origin::Create(details.uri); + // It is expected for Reporting uploads to terminate with ERR_ABORTED, since + // the ReportingUploader cancels them after receiving the response code and + // headers. + if (details.is_reporting_upload && details.type == ERR_ABORTED) + return; // NEL is only available to secure origins, so ignore network errors from // insecure origins. (The check in OnHeader prevents insecure origins from // setting policies, but this check is needed to ensure that insecure origins // can't match wildcard policies from secure origins.) - if (!origin.GetURL().SchemeIsCryptographic()) + if (!details.uri.SchemeIsCryptographic()) return; - const OriginPolicy* policy = FindPolicyForOrigin(origin); + const OriginPolicy* policy = + FindPolicyForOrigin(url::Origin::Create(details.uri)); if (!policy) return;
diff --git a/net/network_error_logging/network_error_logging_service_unittest.cc b/net/network_error_logging/network_error_logging_service_unittest.cc index b0c7a63..7e18097 100644 --- a/net/network_error_logging/network_error_logging_service_unittest.cc +++ b/net/network_error_logging/network_error_logging_service_unittest.cc
@@ -74,12 +74,17 @@ NOTREACHED(); } - void RemoveBrowsingData( - int data_type_mask, - base::RepeatingCallback<bool(const GURL&)> origin_filter) override { + void RemoveBrowsingData(int data_type_mask, + const base::RepeatingCallback<bool(const GURL&)>& + origin_filter) override { NOTREACHED(); } + bool RequestIsUpload(const URLRequest& request) override { + NOTREACHED(); + return true; + } + private: std::vector<Report> reports_; @@ -119,6 +124,7 @@ details.status_code = 0; details.elapsed_time = base::TimeDelta::FromSeconds(1); details.type = error_type; + details.is_reporting_upload = false; return details; }
diff --git a/net/quic/chromium/quic_stream_factory_fuzzer.cc b/net/quic/chromium/quic_stream_factory_fuzzer.cc index 67c0635..a4789685 100644 --- a/net/quic/chromium/quic_stream_factory_fuzzer.cc +++ b/net/quic/chromium/quic_stream_factory_fuzzer.cc
@@ -7,8 +7,8 @@ #include "base/test/fuzzed_data_provider.h" #include "net/base/test_completion_callback.h" -#include "net/cert/cert_verifier.h" -#include "net/cert/multi_log_ct_verifier.h" +#include "net/cert/do_nothing_ct_verifier.h" +#include "net/cert/mock_cert_verifier.h" #include "net/cert/x509_certificate.h" #include "net/dns/fuzzed_host_resolver.h" #include "net/http/http_server_properties_impl.h" @@ -22,6 +22,7 @@ #include "net/socket/fuzzed_socket_factory.h" #include "net/ssl/channel_id_service.h" #include "net/ssl/default_channel_id_store.h" +#include "net/ssl/ssl_config_service_defaults.h" #include "net/test/gtest_util.h" namespace net { @@ -32,18 +33,6 @@ #include "net/data/ssl/certificates/wildcard.inc" }; -class MockSSLConfigService : public SSLConfigService { - public: - MockSSLConfigService() {} - - void GetSSLConfig(SSLConfig* config) override { *config = config_; } - - private: - ~MockSSLConfigService() override {} - - SSLConfig config_; -}; - } // namespace namespace test { @@ -62,12 +51,12 @@ struct Env { Env() : host_port_pair(kServerHostName, kServerPort), random_generator(0) { clock.AdvanceTime(QuicTime::Delta::FromSeconds(1)); - ssl_config_service = new MockSSLConfigService; + ssl_config_service = base::MakeRefCounted<SSLConfigServiceDefaults>(); crypto_client_stream_factory.set_use_mock_crypter(true); - cert_verifier = CertVerifier::CreateDefault(); + cert_verifier = std::make_unique<MockCertVerifier>(); channel_id_service = std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr)); - cert_transparency_verifier = std::make_unique<MultiLogCTVerifier>(); + cert_transparency_verifier = std::make_unique<DoNothingCTVerifier>(); verify_details.cert_verify_result.verified_cert = X509Certificate::CreateFromBytes(kCertData, arraysize(kCertData)); CHECK(verify_details.cert_verify_result.verified_cert);
diff --git a/net/quic/chromium/quic_stream_factory_test.cc b/net/quic/chromium/quic_stream_factory_test.cc index d9fb26a..989abd3 100644 --- a/net/quic/chromium/quic_stream_factory_test.cc +++ b/net/quic/chromium/quic_stream_factory_test.cc
@@ -14,9 +14,9 @@ #include "base/run_loop.h" #include "base/strings/string_util.h" #include "net/base/mock_network_change_notifier.h" -#include "net/cert/cert_verifier.h" #include "net/cert/ct_policy_enforcer.h" -#include "net/cert/multi_log_ct_verifier.h" +#include "net/cert/do_nothing_ct_verifier.h" +#include "net/cert/mock_cert_verifier.h" #include "net/dns/mock_host_resolver.h" #include "net/http/http_response_headers.h" #include "net/http/http_response_info.h" @@ -209,10 +209,10 @@ &clock_, kDefaultServerHostName, Perspective::IS_SERVER), - cert_verifier_(CertVerifier::CreateDefault()), + cert_verifier_(std::make_unique<MockCertVerifier>()), channel_id_service_( new ChannelIDService(new DefaultChannelIDStore(nullptr))), - cert_transparency_verifier_(new MultiLogCTVerifier()), + cert_transparency_verifier_(std::make_unique<DoNothingCTVerifier>()), scoped_mock_network_change_notifier_(nullptr), factory_(nullptr), host_port_pair_(kDefaultServerHostName, kDefaultServerPort),
diff --git a/net/reporting/reporting_browsing_data_remover.cc b/net/reporting/reporting_browsing_data_remover.cc index 070fe33..8f42253 100644 --- a/net/reporting/reporting_browsing_data_remover.cc +++ b/net/reporting/reporting_browsing_data_remover.cc
@@ -17,7 +17,7 @@ void ReportingBrowsingDataRemover::RemoveBrowsingData( ReportingCache* cache, int data_type_mask, - base::RepeatingCallback<bool(const GURL&)> origin_filter) { + const base::RepeatingCallback<bool(const GURL&)>& origin_filter) { bool remove_reports = (data_type_mask & DATA_TYPE_REPORTS) != 0; bool remove_clients = (data_type_mask & DATA_TYPE_CLIENTS) != 0;
diff --git a/net/reporting/reporting_browsing_data_remover.h b/net/reporting/reporting_browsing_data_remover.h index b548d94..abb34bc9 100644 --- a/net/reporting/reporting_browsing_data_remover.h +++ b/net/reporting/reporting_browsing_data_remover.h
@@ -33,7 +33,7 @@ static void RemoveBrowsingData( ReportingCache* cache, int data_type_mask, - base::RepeatingCallback<bool(const GURL&)> origin_filter); + const base::RepeatingCallback<bool(const GURL&)>& origin_filter); private: DISALLOW_IMPLICIT_CONSTRUCTORS(ReportingBrowsingDataRemover);
diff --git a/net/reporting/reporting_service.cc b/net/reporting/reporting_service.cc index b9ef140..59976e23 100644 --- a/net/reporting/reporting_service.cc +++ b/net/reporting/reporting_service.cc
@@ -16,6 +16,7 @@ #include "net/reporting/reporting_context.h" #include "net/reporting/reporting_delegate.h" #include "net/reporting/reporting_header_parser.h" +#include "net/reporting/reporting_uploader.h" #include "url/gurl.h" namespace net { @@ -27,12 +28,17 @@ ReportingServiceImpl(std::unique_ptr<ReportingContext> context) : context_(std::move(context)) {} + // ReportingService implementation: + ~ReportingServiceImpl() override = default; void QueueReport(const GURL& url, const std::string& group, const std::string& type, std::unique_ptr<const base::Value> body) override { + DCHECK(context_); + DCHECK(context_->delegate()); + if (!context_->delegate()->CanQueueReport(url::Origin::Create(url))) return; @@ -45,13 +51,17 @@ ReportingHeaderParser::ParseHeader(context_.get(), url, header_value); } - void RemoveBrowsingData( - int data_type_mask, - base::RepeatingCallback<bool(const GURL&)> origin_filter) override { + void RemoveBrowsingData(int data_type_mask, + const base::RepeatingCallback<bool(const GURL&)>& + origin_filter) override { ReportingBrowsingDataRemover::RemoveBrowsingData( context_->cache(), data_type_mask, origin_filter); } + bool RequestIsUpload(const URLRequest& request) override { + return context_->uploader()->RequestIsUpload(request); + } + private: std::unique_ptr<ReportingContext> context_;
diff --git a/net/reporting/reporting_service.h b/net/reporting/reporting_service.h index 33cfb04..aa7dc40e 100644 --- a/net/reporting/reporting_service.h +++ b/net/reporting/reporting_service.h
@@ -22,6 +22,7 @@ class ReportingContext; struct ReportingPolicy; +class URLRequest; class URLRequestContext; // The external interface to the Reporting system, used by the embedder of //net @@ -63,7 +64,11 @@ // ReportingBrowsingDataRemover for more details. virtual void RemoveBrowsingData( int data_type_mask, - base::RepeatingCallback<bool(const GURL&)> origin_filter) = 0; + const base::RepeatingCallback<bool(const GURL&)>& origin_filter) = 0; + + // Checks whether |request| is a Reporting upload, to avoid loops of reporting + // about report uploads. + virtual bool RequestIsUpload(const URLRequest& request) = 0; protected: ReportingService() {}
diff --git a/net/reporting/reporting_test_util.cc b/net/reporting/reporting_test_util.cc index 1425069..17671b21a 100644 --- a/net/reporting/reporting_test_util.cc +++ b/net/reporting/reporting_test_util.cc
@@ -105,6 +105,11 @@ base::BindOnce(&ErasePendingUpload, &pending_uploads_))); } +bool TestReportingUploader::RequestIsUpload(const URLRequest& request) { + NOTIMPLEMENTED(); + return true; +} + TestReportingDelegate::TestReportingDelegate() = default; TestReportingDelegate::~TestReportingDelegate() = default;
diff --git a/net/reporting/reporting_test_util.h b/net/reporting/reporting_test_util.h index 35216c0..f2dff8f 100644 --- a/net/reporting/reporting_test_util.h +++ b/net/reporting/reporting_test_util.h
@@ -68,10 +68,13 @@ } // ReportingUploader implementation: + void StartUpload(const GURL& url, const std::string& json, UploadCallback callback) override; + bool RequestIsUpload(const URLRequest& request) override; + private: std::vector<std::unique_ptr<PendingUpload>> pending_uploads_;
diff --git a/net/reporting/reporting_uploader.cc b/net/reporting/reporting_uploader.cc index c7cbb92..2220858c 100644 --- a/net/reporting/reporting_uploader.cc +++ b/net/reporting/reporting_uploader.cc
@@ -23,6 +23,15 @@ namespace { +class UploadUserData : public base::SupportsUserData::Data { + public: + static const void* const kUserDataKey; +}; + +// SetUserData needs a unique const void* to serve as the key, so create a const +// void* and use its own address as the unique pointer. +const void* const UploadUserData::kUserDataKey = &UploadUserData::kUserDataKey; + ReportingUploader::Outcome ResponseCodeToOutcome(int response_code) { if (response_code >= 200 && response_code <= 299) return ReportingUploader::Outcome::SUCCESS; @@ -85,6 +94,9 @@ request->set_upload( ElementsUploadDataStream::CreateWithReader(std::move(reader), 0)); + request->SetUserData(UploadUserData::kUserDataKey, + std::make_unique<UploadUserData>()); + // This inherently sets mode = "no-cors", but that doesn't matter, because // the origins that are included in the upload don't actually get to see // the response. @@ -98,6 +110,11 @@ *upload = std::make_unique<Upload>(std::move(request), std::move(callback)); } + // static + bool RequestIsUpload(const net::URLRequest& request) override { + return request.GetUserData(UploadUserData::kUserDataKey); + } + // URLRequest::Delegate implementation: void OnReceivedRedirect(URLRequest* request,
diff --git a/net/reporting/reporting_uploader.h b/net/reporting/reporting_uploader.h index 505b24d..f6c65c7 100644 --- a/net/reporting/reporting_uploader.h +++ b/net/reporting/reporting_uploader.h
@@ -15,6 +15,7 @@ namespace net { +class URLRequest; class URLRequestContext; // Uploads already-serialized reports and converts responses to one of the @@ -35,6 +36,9 @@ const std::string& json, UploadCallback callback) = 0; + // Returns whether |request| is an upload request sent by this uploader. + virtual bool RequestIsUpload(const URLRequest& request) = 0; + // Creates a real implementation of |ReportingUploader| that uploads reports // using |context|. static std::unique_ptr<ReportingUploader> Create(
diff --git a/net/socket/sequenced_socket_data_unittest.cc b/net/socket/sequenced_socket_data_unittest.cc index 47e7a7db..8bc80e1a 100644 --- a/net/socket/sequenced_socket_data_unittest.cc +++ b/net/socket/sequenced_socket_data_unittest.cc
@@ -671,7 +671,7 @@ static const char* kExpectedFailures[] = { "Expected: (data.length()) >= (expected_data.length())", - "Expected equality of these values:\n expected_data", + "Value of: actual_data == expected_data\n Actual: false\nExpected: true", "Expected equality of these values:\n rv"}; ASSERT_EQ(arraysize(kExpectedFailures), static_cast<size_t>(gtest_failures.size()));
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc index 88344f0..363efd7 100644 --- a/net/socket/socket_test_util.cc +++ b/net/socket/socket_test_util.cc
@@ -27,6 +27,7 @@ #include "net/base/address_family.h" #include "net/base/address_list.h" #include "net/base/auth.h" +#include "net/base/hex_utils.h" #include "net/base/ip_address.h" #include "net/base/load_timing_info.h" #include "net/http/http_network_session.h" @@ -229,7 +230,9 @@ std::string expected_data(next_write.data, next_write.data_len); std::string actual_data(data.substr(0, next_write.data_len)); EXPECT_GE(data.length(), expected_data.length()); - EXPECT_EQ(expected_data, actual_data); + EXPECT_TRUE(actual_data == expected_data) + << "Actual write data:\n" << HexDump(actual_data) + << "Expected write data:\n" << HexDump(expected_data); return expected_data == actual_data; } @@ -266,10 +269,10 @@ // Not using mock writes; succeed synchronously. return MockWriteResult(SYNCHRONOUS, data.length()); } - EXPECT_FALSE(helper_.AllWriteDataConsumed()); + EXPECT_FALSE(helper_.AllWriteDataConsumed()) + << "No more mock data to match write:\n" + << HexDump(data); if (helper_.AllWriteDataConsumed()) { - // Show what the extra write actually consists of. - EXPECT_EQ("<unexpected write>", data); return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED); } @@ -445,7 +448,9 @@ MockWriteResult SequencedSocketData::OnWrite(const std::string& data) { CHECK_EQ(IDLE, write_state_); - CHECK(!helper_.AllWriteDataConsumed()); + CHECK(!helper_.AllWriteDataConsumed()) + << "\nNo more mock data to match write:\n" + << HexDump(data); NET_TRACE(1, " *** ") << "sequence_number: " << sequence_number_; const MockWrite& next_write = helper_.PeekWrite();
diff --git a/net/tools/quic/quic_http_response_cache.cc b/net/tools/quic/quic_http_response_cache.cc index 90c221a..c960fc4f 100644 --- a/net/tools/quic/quic_http_response_cache.cc +++ b/net/tools/quic/quic_http_response_cache.cc
@@ -330,7 +330,11 @@ string QuicHttpResponseCache::GetKey(QuicStringPiece host, QuicStringPiece path) const { - return host.as_string() + path.as_string(); + string host_string = host.as_string(); + size_t port = host_string.find(':'); + if (port != string::npos) + host_string = string(host_string.c_str(), port); + return host_string + path.as_string(); } void QuicHttpResponseCache::MaybeAddServerPushResources(
diff --git a/net/url_request/network_error_logging_delegate.h b/net/url_request/network_error_logging_delegate.h index ec2238c..d61ec42 100644 --- a/net/url_request/network_error_logging_delegate.h +++ b/net/url_request/network_error_logging_delegate.h
@@ -38,6 +38,8 @@ int status_code; base::TimeDelta elapsed_time; Error type; + + bool is_reporting_upload; }; static const char kHeaderName[];
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index 7b99fc9..3b76938 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc
@@ -31,6 +31,7 @@ #include "net/log/net_log.h" #include "net/log/net_log_event_type.h" #include "net/log/net_log_source_type.h" +#include "net/reporting/reporting_service.h" #include "net/ssl/ssl_cert_request_info.h" #include "net/url_request/redirect_info.h" #include "net/url_request/redirect_util.h" @@ -1194,6 +1195,10 @@ base::TimeTicks::Now() - load_timing_info_.request_start; details.type = status().ToNetError(); + details.is_reporting_upload = + context()->reporting_service() && + context()->reporting_service()->RequestIsUpload(*this); + delegate->OnNetworkError(details); } #endif // BUILDFLAG(ENABLE_REPORTING)
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc index 9a34c24e..59bcad5 100644 --- a/net/url_request/url_request_test_util.cc +++ b/net/url_request/url_request_test_util.cc
@@ -16,7 +16,7 @@ #include "net/base/host_port_pair.h" #include "net/cert/cert_verifier.h" #include "net/cert/ct_policy_enforcer.h" -#include "net/cert/multi_log_ct_verifier.h" +#include "net/cert/do_nothing_ct_verifier.h" #include "net/dns/mock_host_resolver.h" #include "net/http/http_network_session.h" #include "net/http/http_response_headers.h" @@ -82,7 +82,7 @@ } if (!cert_transparency_verifier()) { context_storage_.set_cert_transparency_verifier( - std::make_unique<MultiLogCTVerifier>()); + std::make_unique<DoNothingCTVerifier>()); } if (!ct_policy_enforcer()) { context_storage_.set_ct_policy_enforcer(
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 9d82eb5..5c00230 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -7037,12 +7037,17 @@ headers_.push_back({url, header_value}); } - void RemoveBrowsingData( - int data_type_mask, - base::Callback<bool(const GURL&)> origin_filter) override { + void RemoveBrowsingData(int data_type_mask, + const base::RepeatingCallback<bool(const GURL&)>& + origin_filter) override { NOTIMPLEMENTED(); } + bool RequestIsUpload(const URLRequest& request) override { + NOTIMPLEMENTED(); + return true; + } + private: std::vector<Header> headers_; };
diff --git a/ppapi/proxy/BUILD.gn b/ppapi/proxy/BUILD.gn index b572778..26ae885 100644 --- a/ppapi/proxy/BUILD.gn +++ b/ppapi/proxy/BUILD.gn
@@ -284,6 +284,7 @@ ":common", "//base", "//gpu/command_buffer/client:gles2_implementation", + "//gpu/command_buffer/common:gles2_utils", "//gpu/ipc/common:command_buffer_traits", "//media:shared_memory_support", "//mojo/edk/system",
diff --git a/services/resource_coordinator/BUILD.gn b/services/resource_coordinator/BUILD.gn index e6848a4..397031b 100644 --- a/services/resource_coordinator/BUILD.gn +++ b/services/resource_coordinator/BUILD.gn
@@ -38,6 +38,8 @@ "memory_instrumentation/queued_request.h", "memory_instrumentation/queued_request_dispatcher.cc", "memory_instrumentation/queued_request_dispatcher.h", + "memory_instrumentation/switches.cc", + "memory_instrumentation/switches.h", "observers/background_metrics_reporter.h", "observers/coordination_unit_graph_observer.cc", "observers/coordination_unit_graph_observer.h",
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc b/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc index cf0070e..f58f638 100644 --- a/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc +++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
@@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/command_line.h" #include "base/location.h" #include "base/logging.h" #include "base/memory/ref_counted.h" @@ -21,6 +22,7 @@ #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "services/resource_coordinator/memory_instrumentation/queued_request_dispatcher.h" +#include "services/resource_coordinator/memory_instrumentation/switches.h" #include "services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.h" #include "services/resource_coordinator/public/interfaces/memory_instrumentation/constants.mojom.h" #include "services/resource_coordinator/public/interfaces/memory_instrumentation/memory_instrumentation.mojom.h" @@ -280,14 +282,7 @@ VLOG(1) << "Received a memory dump response from an unregistered client"; return; } - - // Only add to trace if requested. auto* response = &request->responses[client]; - if (chrome_memory_dump && request->add_to_trace) { - bool added_to_trace = tracing_observer_->AddChromeDumpToTraceIfEnabled( - request->args, response->process_id, chrome_memory_dump.get()); - success = success && added_to_trace; - } response->chrome_dump = std::move(chrome_memory_dump); if (!success) {
diff --git a/services/resource_coordinator/memory_instrumentation/graph.cc b/services/resource_coordinator/memory_instrumentation/graph.cc index e9b012d..c88e9e0 100644 --- a/services/resource_coordinator/memory_instrumentation/graph.cc +++ b/services/resource_coordinator/memory_instrumentation/graph.cc
@@ -101,6 +101,9 @@ current->set_weak(weak); current->set_explicit(true); + // The final node should also have the associated |guid|. + current->set_guid(guid); + // Add to the global guid map as well if it exists. if (!guid.empty()) global_graph_->nodes_by_guid_.emplace(guid, current);
diff --git a/services/resource_coordinator/memory_instrumentation/graph.h b/services/resource_coordinator/memory_instrumentation/graph.h index 4da252c3..88b16d003 100644 --- a/services/resource_coordinator/memory_instrumentation/graph.h +++ b/services/resource_coordinator/memory_instrumentation/graph.h
@@ -150,18 +150,29 @@ double cumulative_owning_coefficient) { cumulative_owning_coefficient_ = cumulative_owning_coefficient; } + base::trace_event::MemoryAllocatorDumpGuid guid() const { return guid_; } + void set_guid(base::trace_event::MemoryAllocatorDumpGuid guid) { + guid_ = guid; + } GlobalDumpGraph::Edge* owns_edge() const { return owns_edge_; } std::map<std::string, Node*>* children() { return &children_; } + const std::map<std::string, Node*>& const_children() const { + return children_; + } std::vector<GlobalDumpGraph::Edge*>* owned_by_edges() { return &owned_by_edges_; } const Node* parent() const { return parent_; } const GlobalDumpGraph::Process* dump_graph() const { return dump_graph_; } std::map<std::string, Entry>* entries() { return &entries_; } + const std::map<std::string, Entry>& const_entries() const { + return entries_; + } private: GlobalDumpGraph::Process* dump_graph_; Node* const parent_; + base::trace_event::MemoryAllocatorDumpGuid guid_; std::map<std::string, Entry> entries_; std::map<std::string, Node*> children_; bool explicit_ = false;
diff --git a/services/resource_coordinator/memory_instrumentation/queued_request_dispatcher.cc b/services/resource_coordinator/memory_instrumentation/queued_request_dispatcher.cc index 77929be2..e67ca37 100644 --- a/services/resource_coordinator/memory_instrumentation/queued_request_dispatcher.cc +++ b/services/resource_coordinator/memory_instrumentation/queued_request_dispatcher.cc
@@ -6,18 +6,23 @@ #include <inttypes.h> +#include "base/command_line.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/strings/pattern.h" +#include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "services/resource_coordinator/memory_instrumentation/graph_processor.h" +#include "services/resource_coordinator/memory_instrumentation/switches.h" #if defined(OS_MACOSX) && !defined(OS_IOS) #include "base/mac/mac_util.h" #endif +using base::trace_event::MemoryAllocatorDump; using base::trace_event::MemoryDumpLevelOfDetail; +using base::trace_event::TracedValue; namespace memory_instrumentation { @@ -101,6 +106,100 @@ return result; } +void NodeAsValueIntoRecursively(const GlobalDumpGraph::Node& node, + TracedValue* value, + std::vector<base::StringPiece>* path) { + // Don't dump the root node. + if (!path->empty()) { + std::string string_conversion_buffer; + + std::string name = base::JoinString(*path, "/"); + value->BeginDictionaryWithCopiedName(name); + + if (!node.guid().empty()) + value->SetString("guid", node.guid().ToString()); + + value->BeginDictionary("attrs"); + for (const auto& name_to_entry : node.const_entries()) { + const auto& entry = name_to_entry.second; + value->BeginDictionaryWithCopiedName(name_to_entry.first); + switch (entry.type) { + case GlobalDumpGraph::Node::Entry::kUInt64: + base::SStringPrintf(&string_conversion_buffer, "%" PRIx64, + entry.value_uint64); + value->SetString("type", MemoryAllocatorDump::kTypeScalar); + value->SetString("value", string_conversion_buffer); + break; + case GlobalDumpGraph::Node::Entry::kString: + value->SetString("type", MemoryAllocatorDump::kTypeString); + value->SetString("value", entry.value_string); + break; + } + switch (entry.units) { + case GlobalDumpGraph::Node::Entry::ScalarUnits::kBytes: + value->SetString("units", MemoryAllocatorDump::kUnitsBytes); + break; + case GlobalDumpGraph::Node::Entry::ScalarUnits::kObjects: + value->SetString("units", MemoryAllocatorDump::kUnitsObjects); + break; + } + value->EndDictionary(); + } + value->EndDictionary(); // "attrs": { ... } + + if (node.is_weak()) + value->SetInteger("flags", MemoryAllocatorDump::Flags::WEAK); + + value->EndDictionary(); // "allocator_name/heap_subheap": { ... } + } + + for (const auto& name_to_child : node.const_children()) { + path->push_back(name_to_child.first); + NodeAsValueIntoRecursively(*name_to_child.second, value, path); + path->pop_back(); + } +} + +std::unique_ptr<TracedValue> GetChromeDumpTracedValue( + const GlobalDumpGraph::Process& process) { + std::unique_ptr<TracedValue> traced_value = std::make_unique<TracedValue>(); + if (!process.root()->const_children().empty()) { + traced_value->BeginDictionary("allocators"); + std::vector<base::StringPiece> path; + NodeAsValueIntoRecursively(*process.root(), traced_value.get(), &path); + traced_value->EndDictionary(); + } + return traced_value; +} + +std::unique_ptr<TracedValue> GetChromeDumpAndGlobalAndEdgesTracedValue( + const GlobalDumpGraph::Process& process, + const GlobalDumpGraph::Process& global_process, + const std::forward_list<GlobalDumpGraph::Edge>& edges) { + std::unique_ptr<TracedValue> traced_value = std::make_unique<TracedValue>(); + bool suppress_graphs = process.root()->const_children().empty() && + global_process.root()->const_children().empty(); + + if (!suppress_graphs) { + traced_value->BeginDictionary("allocators"); + std::vector<base::StringPiece> path; + NodeAsValueIntoRecursively(*process.root(), traced_value.get(), &path); + NodeAsValueIntoRecursively(*global_process.root(), traced_value.get(), + &path); + traced_value->EndDictionary(); + } + traced_value->BeginArray("allocators_graph"); + for (const auto& edge : edges) { + traced_value->BeginDictionary(); + traced_value->SetString("source", edge.source()->guid().ToString()); + traced_value->SetString("target", edge.target()->guid().ToString()); + traced_value->SetInteger("importance", edge.priority()); + traced_value->EndDictionary(); + } + traced_value->EndArray(); + return traced_value; +} + } // namespace void QueuedRequestDispatcher::SetUpAndDispatch( @@ -264,6 +363,31 @@ // If we have the OS dump we should have the platform private footprint. DCHECK(!raw_os_dump || raw_os_dump->platform_private_footprint); + // If the raw dump exists, create a summarised version of it. + mojom::OSMemDumpPtr os_dump = nullptr; + if (raw_os_dump) { + os_dump = CreatePublicOSDump(*raw_os_dump); + os_dump->shared_footprint_kb = shared_footprints[pid] / 1024; + } + + // Trace the OS and Chrome dumps if they exist. + if (request->add_to_trace) { + if (raw_os_dump) { + bool trace_os_success = tracing_observer->AddOsDumpToTraceIfEnabled( + request->args, pid, os_dump.get(), &raw_os_dump->memory_maps); + if (!trace_os_success) + request->failed_memory_dump_count++; + } + + if (raw_chrome_dump) { + bool trace_chrome_success = AddChromeMemoryDumpToTrace( + request->args, pid, *raw_chrome_dump, *global_graph, + pid_to_process_type, tracing_observer); + if (!trace_chrome_success) + request->failed_memory_dump_count++; + } + } + // Ignore incomplete results (can happen if the client crashes/disconnects). const bool valid = raw_os_dump && (!request->wants_chrome_dumps() || raw_chrome_dump) && @@ -272,13 +396,6 @@ if (!valid) continue; - mojom::OSMemDumpPtr os_dump = CreatePublicOSDump(*raw_os_dump); - os_dump->shared_footprint_kb = shared_footprints[pid] / 1024; - if (request->add_to_trace) { - tracing_observer->AddOsDumpToTraceIfEnabled( - request->args, pid, os_dump.get(), &raw_os_dump->memory_maps); - } - if (request->args.level_of_detail == MemoryDumpLevelOfDetail::VM_REGIONS_ONLY_FOR_HEAP_PROFILER) { DCHECK(request->wants_mmaps()); @@ -317,6 +434,38 @@ TRACE_STR_COPY(guid_str), "success", global_success); } +bool QueuedRequestDispatcher::AddChromeMemoryDumpToTrace( + const base::trace_event::MemoryDumpRequestArgs& args, + base::ProcessId pid, + const base::trace_event::ProcessMemoryDump& raw_chrome_dump, + const GlobalDumpGraph& global_graph, + const std::map<base::ProcessId, mojom::ProcessType>& pid_to_process_type, + TracingObserver* tracing_observer) { + bool is_chrome_tracing_enabled = + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableChromeTracingComputation); + if (!is_chrome_tracing_enabled) { + return tracing_observer->AddChromeDumpToTraceIfEnabled(args, pid, + &raw_chrome_dump); + } + if (!tracing_observer->ShouldAddToTrace(args)) + return false; + + const GlobalDumpGraph::Process& process = + *global_graph.process_dump_graphs().find(pid)->second; + + std::unique_ptr<TracedValue> traced_value; + if (pid_to_process_type.find(pid)->second == mojom::ProcessType::BROWSER) { + traced_value = GetChromeDumpAndGlobalAndEdgesTracedValue( + process, *global_graph.shared_memory_graph(), global_graph.edges()); + } else { + traced_value = GetChromeDumpTracedValue(process); + } + tracing_observer->AddToTrace(args, pid, std::move(traced_value)); + + return true; +} + QueuedRequestDispatcher::ClientInfo::ClientInfo(mojom::ClientProcess* client, base::ProcessId pid, mojom::ProcessType process_type)
diff --git a/services/resource_coordinator/memory_instrumentation/queued_request_dispatcher.h b/services/resource_coordinator/memory_instrumentation/queued_request_dispatcher.h index 69c7fbf..56c09f96 100644 --- a/services/resource_coordinator/memory_instrumentation/queued_request_dispatcher.h +++ b/services/resource_coordinator/memory_instrumentation/queued_request_dispatcher.h
@@ -11,6 +11,7 @@ #include "base/trace_event/memory_dump_request_args.h" #include "services/resource_coordinator/memory_instrumentation/coordinator_impl.h" +#include "services/resource_coordinator/memory_instrumentation/graph.h" #include "services/resource_coordinator/memory_instrumentation/queued_request.h" namespace memory_instrumentation { @@ -53,6 +54,15 @@ // |tracing_observer| if the |request| requires it. static void Finalize(QueuedRequest* request, TracingObserver* tracing_observer); + + private: + static bool AddChromeMemoryDumpToTrace( + const base::trace_event::MemoryDumpRequestArgs& args, + base::ProcessId pid, + const base::trace_event::ProcessMemoryDump& raw_chrome_dump, + const GlobalDumpGraph& global_graph, + const std::map<base::ProcessId, mojom::ProcessType>& pid_to_process_type, + TracingObserver* tracing_observer); }; } // namespace memory_instrumentation
diff --git a/services/resource_coordinator/memory_instrumentation/switches.cc b/services/resource_coordinator/memory_instrumentation/switches.cc new file mode 100644 index 0000000..d4f0f68 --- /dev/null +++ b/services/resource_coordinator/memory_instrumentation/switches.cc
@@ -0,0 +1,15 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/resource_coordinator/memory_instrumentation/switches.h" + +namespace memory_instrumentation { +namespace switches { + +// Enable the tracing service. +const char kEnableChromeTracingComputation[] = + "enable-chrome-tracing-computation"; + +} // namespace switches +} // namespace memory_instrumentation \ No newline at end of file
diff --git a/services/resource_coordinator/memory_instrumentation/switches.h b/services/resource_coordinator/memory_instrumentation/switches.h new file mode 100644 index 0000000..9ca825d --- /dev/null +++ b/services/resource_coordinator/memory_instrumentation/switches.h
@@ -0,0 +1,18 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_RESOURCE_COORDINATOR_MEMORY_INSTRUMENTATION_SWITCHES_H_ +#define SERVICES_RESOURCE_COORDINATOR_MEMORY_INSTRUMENTATION_SWITCHES_H_ + +namespace memory_instrumentation { +namespace switches { + +// All switches in alphabetical order. The switches should be documented +// alongside the definition of their values in the .cc file. +extern const char kEnableChromeTracingComputation[]; + +} // namespace switches +} // namespace memory_instrumentation + +#endif // SERVICES_RESOURCE_COORDINATOR_MEMORY_INSTRUMENTATION_SWITCHES_H_ \ No newline at end of file
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.h b/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.h index 8abbb575..02f9192 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.h +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.h
@@ -42,15 +42,17 @@ base::trace_event::TracedValue* value, bool is_argument_filtering_enabled); - private: - // Returns true if the dump mode is allowed for current tracing session. - bool IsDumpModeAllowed(base::trace_event::MemoryDumpLevelOfDetail) const; - + // TODO(lalitm): make these private again after TracingObserver is moved + // to private space. bool ShouldAddToTrace(const base::trace_event::MemoryDumpRequestArgs&); void AddToTrace(const base::trace_event::MemoryDumpRequestArgs&, const base::ProcessId, std::unique_ptr<base::trace_event::TracedValue>); + private: + // Returns true if the dump mode is allowed for current tracing session. + bool IsDumpModeAllowed(base::trace_event::MemoryDumpLevelOfDetail) const; + base::trace_event::MemoryDumpManager* const memory_dump_manager_; base::trace_event::TraceLog* const trace_log_; std::unique_ptr<base::trace_event::TraceConfig::MemoryDumpConfig>
diff --git a/services/ui/public/cpp/gpu/context_provider_command_buffer.cc b/services/ui/public/cpp/gpu/context_provider_command_buffer.cc index 7e36c276..fc2e105 100644 --- a/services/ui/public/cpp/gpu/context_provider_command_buffer.cc +++ b/services/ui/public/cpp/gpu/context_provider_command_buffer.cc
@@ -134,6 +134,7 @@ ContextProviderCommandBuffer::ContextProviderCommandBuffer( scoped_refptr<gpu::GpuChannelHost> channel, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, int32_t stream_id, gpu::SchedulingPriority stream_priority, gpu::SurfaceHandle surface_handle, @@ -156,7 +157,8 @@ shared_providers_(shared_context_provider ? shared_context_provider->shared_providers_ : new SharedProviders), - channel_(std::move(channel)) { + channel_(std::move(channel)), + gpu_memory_buffer_manager_(gpu_memory_buffer_manager) { DCHECK(main_thread_checker_.CalledOnValidThread()); DCHECK(channel_); context_thread_checker_.DetachFromThread(); @@ -238,7 +240,8 @@ // This command buffer is a client-side proxy to the command buffer in the // GPU process. command_buffer_ = std::make_unique<gpu::CommandBufferProxyImpl>( - std::move(channel_), stream_id_, task_runner); + std::move(channel_), gpu_memory_buffer_manager_, stream_id_, + task_runner); bind_result_ = command_buffer_->Initialize(surface_handle_, shared_command_buffer, stream_priority_, attributes_, active_url_);
diff --git a/services/ui/public/cpp/gpu/context_provider_command_buffer.h b/services/ui/public/cpp/gpu/context_provider_command_buffer.h index d0a9922..3fa465f 100644 --- a/services/ui/public/cpp/gpu/context_provider_command_buffer.h +++ b/services/ui/public/cpp/gpu/context_provider_command_buffer.h
@@ -29,6 +29,7 @@ class CommandBufferProxyImpl; class GpuChannelHost; struct GpuFeatureInfo; +class GpuMemoryBufferManager; class TransferBuffer; namespace gles2 { class GLES2CmdHelper; @@ -54,6 +55,7 @@ public: ContextProviderCommandBuffer( scoped_refptr<gpu::GpuChannelHost> channel, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, int32_t stream_id, gpu::SchedulingPriority stream_priority, gpu::SurfaceHandle surface_handle, @@ -138,6 +140,7 @@ scoped_refptr<SharedProviders> shared_providers_; scoped_refptr<gpu::GpuChannelHost> channel_; + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_; scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; base::Lock context_lock_; // Referenced by command_buffer_.
diff --git a/services/ui/public/cpp/gpu/gpu.cc b/services/ui/public/cpp/gpu/gpu.cc index 5d9b315..bbcc1f21 100644 --- a/services/ui/public/cpp/gpu/gpu.cc +++ b/services/ui/public/cpp/gpu/gpu.cc
@@ -121,8 +121,7 @@ received_ = true; if (channel_handle.is_valid()) { gpu_channel_ = base::MakeRefCounted<gpu::GpuChannelHost>( - client_id, gpu_info, gpu_feature_info, std::move(channel_handle), - parent_->gpu_memory_buffer_manager()); + client_id, gpu_info, gpu_feature_info, std::move(channel_handle)); } if (establish_event_) { @@ -199,9 +198,10 @@ attributes.lose_context_when_out_of_memory = true; ContextProviderCommandBuffer* shared_context_provider = nullptr; return base::MakeRefCounted<ContextProviderCommandBuffer>( - std::move(gpu_channel), stream_id, stream_priority, - gpu::kNullSurfaceHandle, GURL("chrome://gpu/MusContextFactory"), - automatic_flushes, support_locking, gpu::SharedMemoryLimits(), attributes, + std::move(gpu_channel), GetGpuMemoryBufferManager(), stream_id, + stream_priority, gpu::kNullSurfaceHandle, + GURL("chrome://gpu/MusContextFactory"), automatic_flushes, + support_locking, gpu::SharedMemoryLimits(), attributes, shared_context_provider, command_buffer_metrics::MUS_CLIENT_CONTEXT); }
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 009ce31..a94b92f1 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -8812,51 +8812,6 @@ }, { "args": [ - "--disable-browser-side-navigation", - "--recover-devices" - ], - "merge": { - "args": [ - "--bucket", - "chromium-result-details", - "--test-name", - "renderer_side_navigation_content_browsertests" - ], - "script": "//build/android/pylib/results/presentation/test_results_presentation.py" - }, - "name": "renderer_side_navigation_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/luci/logdog/butler/${platform}", - "location": "bin", - "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" - } - ], - "dimension_sets": [ - { - "device_os": "MMB29Q", - "device_type": "bullhead" - } - ], - "hard_timeout": 1200, - "output_links": [ - { - "link": [ - "https://luci-logdog.appspot.com/v/?s", - "=android%2Fswarming%2Flogcats%2F", - "${TASK_ID}%2F%2B%2Funified_logcats" - ], - "name": "shard #${SHARD_INDEX} logcats" - } - ], - "shards": 6 - }, - "test": "content_browsertests" - }, - { - "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices" ], @@ -8901,52 +8856,6 @@ }, { "args": [ - "--disable-browser-side-navigation", - "--gs-results-bucket=chromium-result-details", - "--recover-devices" - ], - "merge": { - "args": [ - "--bucket", - "chromium-result-details", - "--test-name", - "renderer_side_navigation_content_shell_test_apk" - ], - "script": "//build/android/pylib/results/presentation/test_results_presentation.py" - }, - "name": "renderer_side_navigation_content_shell_test_apk", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/luci/logdog/butler/${platform}", - "location": "bin", - "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" - } - ], - "dimension_sets": [ - { - "device_os": "MMB29Q", - "device_type": "bullhead" - } - ], - "hard_timeout": 960, - "output_links": [ - { - "link": [ - "https://luci-logdog.appspot.com/v/?s", - "=android%2Fswarming%2Flogcats%2F", - "${TASK_ID}%2F%2B%2Funified_logcats" - ], - "name": "shard #${SHARD_INDEX} logcats" - } - ], - "shards": 3 - }, - "test": "content_shell_test_apk" - }, - { - "args": [ "--recover-devices" ], "merge": { @@ -8989,50 +8898,6 @@ }, { "args": [ - "--disable-browser-side-navigation", - "--recover-devices" - ], - "merge": { - "args": [ - "--bucket", - "chromium-result-details", - "--test-name", - "renderer_side_navigation_content_unittests" - ], - "script": "//build/android/pylib/results/presentation/test_results_presentation.py" - }, - "name": "renderer_side_navigation_content_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/luci/logdog/butler/${platform}", - "location": "bin", - "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" - } - ], - "dimension_sets": [ - { - "device_os": "MMB29Q", - "device_type": "bullhead" - } - ], - "hard_timeout": 960, - "output_links": [ - { - "link": [ - "https://luci-logdog.appspot.com/v/?s", - "=android%2Fswarming%2Flogcats%2F", - "${TASK_ID}%2F%2B%2Funified_logcats" - ], - "name": "shard #${SHARD_INDEX} logcats" - } - ] - }, - "test": "content_unittests" - }, - { - "args": [ "--recover-devices" ], "merge": { @@ -9916,52 +9781,6 @@ "shards": 8 }, "test": "webview_instrumentation_test_apk" - }, - { - "args": [ - "--disable-browser-side-navigation", - "--gs-results-bucket=chromium-result-details", - "--recover-devices" - ], - "merge": { - "args": [ - "--bucket", - "chromium-result-details", - "--test-name", - "renderer_side_navigation_webview_instrumentation_test_apk" - ], - "script": "//build/android/pylib/results/presentation/test_results_presentation.py" - }, - "name": "renderer_side_navigation_webview_instrumentation_test_apk", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/luci/logdog/butler/${platform}", - "location": "bin", - "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" - } - ], - "dimension_sets": [ - { - "device_os": "MMB29Q", - "device_type": "bullhead" - } - ], - "hard_timeout": 1200, - "output_links": [ - { - "link": [ - "https://luci-logdog.appspot.com/v/?s", - "=android%2Fswarming%2Flogcats%2F", - "${TASK_ID}%2F%2B%2Funified_logcats" - ], - "name": "shard #${SHARD_INDEX} logcats" - } - ], - "shards": 8 - }, - "test": "webview_instrumentation_test_apk" } ] },
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index e42a756b..1a41e51 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -311,73 +311,6 @@ } ] }, - "Browser Side Navigation Linux": { - "gtest_tests": [ - { - "args": [ - "--disable-browser-side-navigation", - "--test-launcher-retry-limit=6" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 5 - }, - "test": "browser_tests" - }, - { - "args": [ - "--disable-browser-side-navigation" - ], - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_browsertests" - }, - { - "args": [ - "--disable-browser-side-navigation" - ], - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_unittests" - }, - { - "args": [ - "--disable-browser-side-navigation" - ], - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "unit_tests" - } - ], - "isolated_scripts": [ - { - "args": [ - "--additional-driver-flag", - "--disable-browser-side-navigation" - ], - "isolate_name": "webkit_layout_tests_exparchive", - "merge": { - "args": [ - "--verbose" - ], - "script": "//third_party/WebKit/Tools/Scripts/merge-layout-test-results" - }, - "name": "webkit_layout_tests", - "results_handler": "layout tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04" - } - ] - } - } - ] - }, "CFI Linux (icall)": { "gtest_tests": [ { @@ -2564,26 +2497,6 @@ "test": "content_browsertests" }, { - "args": [ - "--disable-browser-side-navigation" - ], - "name": "renderer_side_navigation_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_unittests" - }, - { - "args": [ - "--disable-browser-side-navigation" - ], - "name": "renderer_side_navigation_content_unittests", "swarming": { "can_use_on_swarming_builders": true }, @@ -4280,7 +4193,7 @@ { "args": [ "--enable-viz", - "--test-launcher-filter-file=../../testing/buildbot/filters/viz.content_unitests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/viz.content_unittests.filter" ], "name": "viz_content_unittests", "swarming": { @@ -4549,7 +4462,7 @@ { "args": [ "--enable-viz", - "--test-launcher-filter-file=../../testing/buildbot/filters/viz.content_unitests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/viz.content_unittests.filter" ], "name": "viz_content_unittests", "swarming": { @@ -4691,7 +4604,7 @@ { "args": [ "--enable-viz", - "--test-launcher-filter-file=../../testing/buildbot/filters/viz.content_unitests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/viz.content_unittests.filter" ], "name": "viz_content_unittests", "swarming": {
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index 0656533..1a23c96 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -663,16 +663,6 @@ }, { "args": [ - "--disable-browser-side-navigation" - ], - "name": "renderer_side_navigation_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_browsertests" - }, - { - "args": [ "--site-per-process", "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" ], @@ -702,16 +692,6 @@ }, { "args": [ - "--disable-browser-side-navigation" - ], - "name": "renderer_side_navigation_content_unittests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_unittests" - }, - { - "args": [ "--site-per-process" ], "name": "site_per_process_content_unittests", @@ -1360,16 +1340,6 @@ }, { "args": [ - "--disable-browser-side-navigation" - ], - "name": "renderer_side_navigation_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_browsertests" - }, - { - "args": [ "--site-per-process", "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter" ], @@ -1399,16 +1369,6 @@ }, { "args": [ - "--disable-browser-side-navigation" - ], - "name": "renderer_side_navigation_content_unittests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_unittests" - }, - { - "args": [ "--site-per-process" ], "name": "site_per_process_content_unittests",
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 565e939..525496f 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -3988,20 +3988,6 @@ }, 'modifications': { # chromium.fyi - 'Browser Side Navigation Linux': { - 'args': [ - '--additional-driver-flag', - '--disable-browser-side-navigation', - ], - 'swarming': { - # TODO(kbr): specify this for this builder instead. - 'dimension_sets': [ - { - 'os': 'Ubuntu-14.04', - }, - ], - }, - }, 'WebKit Linux layout_ng Dummy Builder': { 'args': [ '--additional-driver-flag=--enable-blink-features=LayoutNG',
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 82b41be..18f8867 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -298,20 +298,6 @@ 'hard_timeout': 300, }, }, - 'renderer_side_navigation_content_shell_test_apk': { - 'args': [ - '--disable-browser-side-navigation', - '--gs-results-bucket=chromium-result-details', - ], - 'test': 'content_shell_test_apk', - }, - 'renderer_side_navigation_webview_instrumentation_test_apk': { - 'args': [ - '--disable-browser-side-navigation', - '--gs-results-bucket=chromium-result-details', - ], - 'test': 'webview_instrumentation_test_apk', - }, 'ui_android_unittests': {}, 'webview_instrumentation_test_apk': { 'args': [ @@ -336,33 +322,6 @@ 'keyboard_unittests': {}, }, - 'browser_side_navigation_disabled_gtests': { - 'browser_tests': { - 'args': [ - '--disable-browser-side-navigation', - '--test-launcher-retry-limit=6', - ], - 'swarming': { - 'shards': 5, - }, - }, - 'content_browsertests': { - 'args': [ - '--disable-browser-side-navigation', - ], - }, - 'content_unittests': { - 'args': [ - '--disable-browser-side-navigation', - ], - }, - 'unit_tests': { - 'args': [ - '--disable-browser-side-navigation', - ], - }, - }, - 'cast_audio_specific_chromium_gtests': { 'cast_audio_backend_unittests': {}, 'cast_base_unittests': {}, @@ -925,21 +884,6 @@ 'content_unittests': {}, }, - 'linux_and_android_and_fyi_specific_chromium_gtests': { - 'renderer_side_navigation_content_browsertests': { - 'args': [ - '--disable-browser-side-navigation', - ], - 'test': 'content_browsertests', - }, - 'renderer_side_navigation_content_unittests': { - 'args': [ - '--disable-browser-side-navigation', - ], - 'test': 'content_unittests', - }, - }, - 'linux_and_chromeos_non_clang_specific_chromium_gtests': { # TOOD(kbr): rename back to linux_and_chromeos_specific_chromium_gtests. 'media_service_unittests': {}, @@ -1688,7 +1632,7 @@ 'viz_content_unittests': { 'args': [ '--enable-viz', - '--test-launcher-filter-file=../../testing/buildbot/filters/viz.content_unitests.filter', + '--test-launcher-filter-file=../../testing/buildbot/filters/viz.content_unittests.filter', ], 'test': 'content_unittests', } @@ -1805,7 +1749,6 @@ 'chromium_gtests_for_non_clang_win_devices_with_graphical_output', 'chromium_swarm_android_gtests', 'clang_gl_gtests', - 'linux_and_android_and_fyi_specific_chromium_gtests', 'linux_flavor_specific_chromium_gtests', 'non_clang_mac_win_chromium_gtests', 'non_clang_win_chromium_gtests', @@ -1819,7 +1762,6 @@ 'chromium_gtests_for_devices_with_graphical_output', 'chromium_gtests_for_non_clang_and_fyi_mac_win_devices_with_graphical_output', 'chromium_gtests_for_non_clang_win_devices_with_graphical_output', - 'linux_and_android_and_fyi_specific_chromium_gtests', 'linux_flavor_specific_chromium_gtests', 'non_clang_android_mac_win_chromium_gtests', 'non_clang_and_mac_fyi_chromium_gtests', @@ -1909,7 +1851,6 @@ 'chromium_gtests_for_devices_with_graphical_output', 'chromium_gtests_for_non_clang_and_fyi_mac_win_devices_with_graphical_output', 'chromium_gtests_for_non_clang_win_devices_with_graphical_output', - 'linux_and_android_and_fyi_specific_chromium_gtests', 'linux_and_chromeos_non_clang_specific_chromium_gtests', 'linux_and_mac_non_clang_specific_chromium_gtests', 'linux_flavor_specific_chromium_gtests', @@ -1947,7 +1888,6 @@ 'chromium_gtests_for_devices_with_graphical_output', 'chromium_gtests_for_non_clang_and_fyi_mac_win_devices_with_graphical_output', 'chromium_gtests_for_non_clang_win_devices_with_graphical_output', - 'linux_and_android_and_fyi_specific_chromium_gtests', 'linux_and_chromeos_non_clang_specific_chromium_gtests', 'linux_and_mac_non_clang_specific_chromium_gtests', 'linux_chromeos_specific_gtests', @@ -1975,7 +1915,6 @@ 'chromium_gtests_for_devices_with_graphical_output', 'chromium_gtests_for_non_clang_and_fyi_mac_win_devices_with_graphical_output', 'chromium_gtests_for_non_clang_win_devices_with_graphical_output', - 'linux_and_android_and_fyi_specific_chromium_gtests', 'linux_and_chromeos_non_clang_specific_chromium_gtests', 'linux_and_mac_non_clang_specific_chromium_gtests', 'linux_chromeos_specific_gtests', @@ -2207,7 +2146,6 @@ 'chromium_gtests_for_devices_with_graphical_output', 'chromium_gtests_for_non_clang_and_fyi_mac_win_devices_with_graphical_output', 'chromium_gtests_for_non_clang_win_devices_with_graphical_output', - 'linux_and_android_and_fyi_specific_chromium_gtests', 'non_android_chromium_gtests', 'non_android_and_cast_chromium_gtests', 'non_android_and_cast_and_chromeos_and_clang_android_mac_win_chromium_gtests',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index aab1979..4e57b09a 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -909,12 +909,6 @@ 'os_type': 'android', 'skip_output_links': True, }, - 'Browser Side Navigation Linux': { - 'test_suites': { - 'gtest_tests': 'browser_side_navigation_disabled_gtests', - 'isolated_scripts': 'webkit_layout_tests_isolated_scripts', - }, - }, 'CFI Linux (icall)': { 'test_suites': { 'gtest_tests': 'chromium_linux_clang_and_gl_gtests',
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 45efc54..db68651 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -3108,6 +3108,7 @@ # crbug.com/736177: Failures likely related to different results on Mac with different GPUs crbug.com/736177 [ Mac10.12 ] fast/forms/form-element-geometry.html [ Failure Pass ] crbug.com/736177 [ Mac ] fast/forms/input-appearance-height.html [ Failure Pass ] +crbug.com/736177 [ Mac ] svg/as-border-image/svg-as-border-image.html [ Failure Pass ] # These tests are failing on Mac-10.12 when using an Intel GPU and Mac Retina crbug.com/736177 [ Mac10.12 Retina ] compositing/overflow/theme-affects-visual-overflow.html [ Failure Pass ] crbug.com/736177 [ Mac10.12 Retina ] css1/box_properties/acid_test.html [ Failure Pass ] @@ -3143,9 +3144,6 @@ crbug.com/736177 [ Mac10.12 Retina ] tables/mozilla_expected_failures/core/captions2.html [ Failure Pass ] crbug.com/736177 [ Mac10.12 Retina ] virtual/prefer_compositing_to_lcd_text/compositing/overflow/theme-affects-visual-overflow.html [ Failure Pass ] crbug.com/736177 [ Mac10.12 Retina ] virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi.html [ Failure Pass ] -# fast/css/text-overflow-input.html test is flaky on all Mac platforms -crbug.com/736177 [ Mac ] fast/css/text-overflow-input.html [ Failure Pass ] -crbug.com/736177 [ Mac ] svg/as-border-image/svg-as-border-image.html [ Failure Pass ] crbug.com/734762 inspector-protocol/timeline/page-frames.js [ Failure ] @@ -3710,3 +3708,6 @@ # Sheriff failures 2017-12-15 crbug.com/795250 [ Win7 ] virtual/scroll_customization/fast/events/touch/gesture/gesture-tap-hover-state-iframe.html [ Pass Failure ] + +# Does not work on Mac +crbug.com/793771 [ Mac ] virtual/modern-media-controls/media/controls/modern/scrubbing.html [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index faae3ef..f39be2fe 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -53773,6 +53773,18 @@ {} ] ], + "css/css-transforms/css-transform-inherit-scale.html": [ + [ + "/css/css-transforms/css-transform-inherit-scale.html", + [ + [ + "/css/reference/ref-filled-green-200px-square.html", + "==" + ] + ], + {} + ] + ], "css/css-transforms/css-transform-scale-001.html": [ [ "/css/css-transforms/css-transform-scale-001.html", @@ -224873,12 +224885,6 @@ {} ] ], - "css/css-transforms/css-transform-inherit-scale.html": [ - [ - "/css/css-transforms/css-transform-inherit-scale.html", - {} - ] - ], "css/css-transforms/rotate-180-degrees-001.html": [ [ "/css/css-transforms/rotate-180-degrees-001.html", @@ -234399,7 +234405,7 @@ "support" ], "compat/OWNERS": [ - "80579a1e88af8e60c7446f34446b90bd3e9cf8c7", + "f3e5dc135a9cd96d4cacaf0bc21c67a7899d08d2", "support" ], "compat/green-ref.html": [ @@ -276487,8 +276493,8 @@ "visual" ], "css/css-transforms/css-transform-inherit-scale.html": [ - "79bf0552c20649ba4f4c8442176ce349616bf750", - "visual" + "1afd10f480afbd37ba7f55daae31003146fd22c1", + "reftest" ], "css/css-transforms/css-transform-property-existence-expected.txt": [ "eb9d27b3271cb67f632f085588d8da89e1a508df", @@ -302463,7 +302469,7 @@ "support" ], "fullscreen/OWNERS": [ - "e44bfebe003740cd4a9fa5aabdae87eafe1a8449", + "b97db394860afcd858ccfd1a4982ba6dfca2078c", "support" ], "fullscreen/api/document-exit-fullscreen-active-document-expected.txt": [ @@ -303303,7 +303309,7 @@ "testharness" ], "html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-fragment-scrolling-cross-origin.html": [ - "0f8425ba4fcdd12e357ec975c6439c89c72c1c3e", + "a94f2df91002c5cf36e6a4607c2f95e3ba130c30", "testharness" ], "html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-fragment-scrolling-samedoc.html": [ @@ -307671,7 +307677,7 @@ "testharness" ], "html/dom/usvstring-reflection.html": [ - "9171bb8bd4b190263327c92f1d52e9a2465253ae", + "2878d29f3e16b437247315b2f31229649a7bd6b3", "testharness" ], "html/editing/.gitkeep": [ @@ -349967,7 +349973,7 @@ "support" ], "webvtt/OWNERS": [ - "dcf85b8b4c54addc98e82ecc66501eee0368e475", + "a15decea1641861b0388cc5f7606e5bcfebf67a0", "support" ], "webvtt/README.md": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/open-url-encoding-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/open-url-encoding-expected.txt deleted file mode 100644 index ba9f4c4f..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/XMLHttpRequest/open-url-encoding-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This is a testharness.js-based test. -PASS percent encode characters -FAIL lone surrogate assert_equals: expected "&%2365533;" but got "%26%2365533%3B" -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-transforms/css-transform-inherit-scale.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-transforms/css-transform-inherit-scale.html index b4702f8f..fa9b5bb 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-transforms/css-transform-inherit-scale.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-transforms/css-transform-inherit-scale.html
@@ -1,50 +1,49 @@ <!DOCTYPE html> <html> -<head> + <head> <title>CSS Transforms Test: CSS transforms scale 2 inheritance on div elements</title> <link rel="author" title="Delong Gao" href="mailto:gaodl@uw.edu"> <link rel="reviewer" title="Rebecca Hauck" href="mailto:rhauck@adobe.com"> <link rel="help" href="http://www.w3.org/TR/css-transforms-1/#transform-property"> <link rel="help" href="http://www.w3.org/TR/css-transforms-1/#two-d-transform-functions"> - <!--<link rel="match" href="reference/ttwf-reftest-tutorial-ref.html"> - <meta name="flags" content="svg">--> + <link rel="match" href="../reference/ref-filled-green-200px-square.html"> <meta name="assert" content="While child div inherits property from its parent, scaling 2 on parent div will course the child to scale 4 and totally cover the red div. The test passes if there is a green square and no red. "> <style type="text/css"> - * { - margin: 0; - padding: 0; - } - .red { - position: absolute; - width: 200px; - height: 200px; - background-color: red; - } - .parent { - background: yellow; - width: 50px; - height: 50px; - position: absolute; - top: 75px; - left: 75px; - transform: scale(2); + .test { + position: relative; + } + .red { + position: absolute; + width: 200px; + height: 200px; + background-color: red; + } + .parent { + background: yellow; + width: 50px; + height: 50px; + position: absolute; + top: 75px; + left: 75px; + transform: scale(2); - } - .child { - position: absolute; - top: 10px; - transform: inherit; - width: 50px; - height: 50px; - background-color: green; - } + } + .child { + position: absolute; + transform: inherit; + width: 50px; + height: 50px; + background-color: green; + } </style> -</head> -<body> - <p>The test passes if there is a green square and no red. </p> - <div class="red"></div> - <div class="parent"> - <div class="child"></div> - </div> -</body> + </head> + <body> + <p>Test passes if there is a filled green square and <strong>no red</strong>.</p> + <div class="test"> + <div class="red"></div> + <div class="parent"> + <div class="child"></div> + </div> + </div> + </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/encoding/big5-encoder-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/encoding/big5-encoder-expected.txt deleted file mode 100644 index af399bc..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/encoding/big5-encoder-expected.txt +++ /dev/null
@@ -1,16 +0,0 @@ -This is a testharness.js-based test. -PASS big5 encoder: very basic -FAIL big5 encoder: Highest-pointer BMP character excluded from encoder assert_equals: expected "X&%2340614;X" but got "X%26%2340614%3BX" -FAIL big5 encoder: Highest-pointer character excluded from encoder assert_equals: expected "X&%23156267;X" but got "X%26%23156267%3BX" -PASS big5 encoder: Lowest-pointer character included in encoder -PASS big5 encoder: Euro; the highest-pointer character before a range of 30 unmapped pointers -PASS big5 encoder: The lowest-pointer character after the range of 30 unmapped pointers -PASS big5 encoder: The highest-pointer character before a range of 41 unmapped pointers -PASS big5 encoder: The lowest-pointer character after the range of 41 unmapped pointers -PASS big5 encoder: The last character in the index -FAIL big5 encoder: The canonical BMP test character that is not in the index assert_equals: expected "X&%239731;X" but got "X%26%239731%3BX" -FAIL big5 encoder: The canonical astral test character that is not in the index assert_equals: expected "X&%23128169;X" but got "X%26%23128169%3BX" -PASS big5 encoder: A Plane 2 character whose low 16 bits match a BMP character that has a lower pointer -PASS big5 encoder: A duplicate-mapped code point that prefers the highest pointer in the encoder -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/encoding/gbk-encoder-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/encoding/gbk-encoder-expected.txt deleted file mode 100644 index c4b35d1..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/encoding/gbk-encoder-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -This is a testharness.js-based test. -PASS gbk encoder: very basic -PASS gbk encoder: Euro -PASS gbk encoder: character -PASS gbk encoder: PUA -PASS gbk encoder: PUA #2 -FAIL gbk encoder: poo assert_equals: expected "&%23128169;" but got "%26%23128169%3B" -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-fragment-scrolling-cross-origin.html b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-fragment-scrolling-cross-origin.html index 4594a1e..7d9a31d0 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-fragment-scrolling-cross-origin.html +++ b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-fragment-scrolling-cross-origin.html
@@ -1,20 +1,18 @@ <!DOCTYPE html> <meta name=timeout content=long> <title>Precedence of scroll restoration mode over fragment scrolling in cross-origin history traversal</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> <style> iframe { height: 300px; width: 300px; } </style> - -<body> - <iframe></iframe> -</body> - -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script type="text/javascript"> +<div id="log"></div> +<iframe></iframe> +<script> 'use strict'; // The test does the following navigation steps for iframe @@ -23,13 +21,16 @@ // 3. go back to page-with-fragment.html async_test(function(t) { var iframe = document.querySelector('iframe'); - var baseURL = location.href.substring(0, location.href.lastIndexOf('/')); + var hostInfo = get_host_info(); + var basePath = location.pathname.substring(0, location.pathname.lastIndexOf('/')); + var localURL = hostInfo.HTTP_ORIGIN + basePath + '/resources/page-with-fragment.html#fragment'; + var remoteURL = hostInfo.HTTP_REMOTE_ORIGIN + basePath + "/resources/blank1.html" var steps = [ function() { iframe.src = 'resources/page-with-fragment.html#fragment'; }, function() { - assert_equals(iframe.contentWindow.location.href, baseURL + '/resources/page-with-fragment.html#fragment', 'should be on page-with-fragment page'); + assert_equals(iframe.contentWindow.location.href, localURL, 'should be on page-with-fragment page'); // wait one animation frame to ensure layout is run and fragment scrolling is complete iframe.contentWindow.requestAnimationFrame(function() { assert_equals(iframe.contentWindow.scrollY, 800, 'should scroll to fragment'); @@ -40,13 +41,13 @@ }); }, function() { // navigate to a new page from a different origin - iframe.src = iframe.src.replace("http://", "http://www.").replace("page-with-fragment.html#fragment", "blank1.html"); + iframe.src = remoteURL; }, function() { // going back causes the iframe to traverse back history.back(); }, function() { // coming back from history, scrollRestoration should be set to manual and respected - assert_equals(iframe.contentWindow.location.href, baseURL + '/resources/page-with-fragment.html#fragment', 'should be back on page-with-fragment page'); + assert_equals(iframe.contentWindow.location.href, localURL, 'should be back on page-with-fragment page'); iframe.contentWindow.requestAnimationFrame(t.step_func_done(function() { assert_equals(iframe.contentWindow.history.scrollRestoration, 'manual', 'navigating back should retain scrollRestoration value'); assert_equals(iframe.contentWindow.scrollX, 0, 'should not scroll to fragment');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt index 2f15fa99..f758808 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 5287 tests; 5165 PASS, 122 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 5287 tests; 5166 PASS, 121 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Test driver PASS Document interface: attribute domain PASS Document interface: attribute referrer @@ -44,7 +44,7 @@ PASS Document interface: operation clear() PASS Document interface: operation captureEvents() PASS Document interface: operation releaseEvents() -FAIL Document interface: attribute all assert_equals: setter must be undefined for readonly attributes expected (undefined) undefined but got (function) function "function () { [native code] }" +PASS Document interface: attribute all PASS Document interface: attribute onabort PASS Document interface: attribute onauxclick PASS Document interface: attribute onblur
diff --git a/third_party/WebKit/LayoutTests/fast/dom/undetectable-document-all-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/undetectable-document-all-expected.txt index 937759ee..1d5914c 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/undetectable-document-all-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/undetectable-document-all-expected.txt
@@ -1,4 +1,4 @@ -This tests that document.all should be undetectable, and that it should be possible to set document.all to something else. If this test is successful, the text "SUCCESS" should be shown below. +This tests that document.all should be undetectable, and that it should not be possible to set document.all to something else. If this test is successful, the text "SUCCESS" should be shown below. document.all: [object HTMLAllCollection] SUCCESS!
diff --git a/third_party/WebKit/LayoutTests/fast/dom/undetectable-document-all.html b/third_party/WebKit/LayoutTests/fast/dom/undetectable-document-all.html index 0fa3c89..16d8a507 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/undetectable-document-all.html +++ b/third_party/WebKit/LayoutTests/fast/dom/undetectable-document-all.html
@@ -46,8 +46,8 @@ // Try replacing document.all with something else document.all = { 'foo': 42} - if (document.all.foo != 42) { - debug('FAILURE: replacing document.all did not work') + if (document.all.foo == 42) { + debug('FAILURE: replacing document.all must not be allowed') return; } @@ -70,7 +70,7 @@ </script> </head> <body onload="runTests();"> -This tests that document.all should be undetectable, and that it should be possible to set document.all to something else. If this test is successful, the text "SUCCESS" should be shown below. +This tests that document.all should be undetectable, and that it should not be possible to set document.all to something else. If this test is successful, the text "SUCCESS" should be shown below. <pre id="console"></pre> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/javascript-cannot-access-suggested-value.html b/third_party/WebKit/LayoutTests/fast/forms/javascript-cannot-access-suggested-value.html index d3baba91..d03660f 100644 --- a/third_party/WebKit/LayoutTests/fast/forms/javascript-cannot-access-suggested-value.html +++ b/third_party/WebKit/LayoutTests/fast/forms/javascript-cannot-access-suggested-value.html
@@ -22,7 +22,8 @@ var val = field.value.trim(); field.value=''; - assert_equals(val, '', 'The JavaScript should not be able to access the suggested values.'); + var empty_or_initial = val == "" || val == "Homer"; + assert_true(empty_or_initial, 'The JavaScript should not be able to access the suggested values.'); } // Test that tries to grab the suggested value on empty fields.
diff --git a/third_party/WebKit/LayoutTests/fast/forms/suggested-value-after-empty-suggested-value-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/suggested-value-after-empty-suggested-value-expected.txt index 98f18b8..6269e5c 100644 --- a/third_party/WebKit/LayoutTests/fast/forms/suggested-value-after-empty-suggested-value-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/forms/suggested-value-after-empty-suggested-value-expected.txt
@@ -91,6 +91,7 @@ | shadow:pseudoId="-internal-input-suggested" | "suggested value" | <div> +| "initial value" | <br> | " " @@ -122,6 +123,7 @@ | shadow:pseudoId="-internal-input-suggested" | "suggested value" | <div> +| "initial value" | <br> | " "
diff --git a/third_party/WebKit/LayoutTests/fast/forms/suggested-value-after-setvalue-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/suggested-value-after-setvalue-expected.txt index c42a487..8c023727 100644 --- a/third_party/WebKit/LayoutTests/fast/forms/suggested-value-after-setvalue-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/forms/suggested-value-after-setvalue-expected.txt
@@ -14,6 +14,7 @@ | shadow:pseudoId="-internal-input-suggested" | "suggested value" | <div> +| "initial value" | "input.value: initial value" | "internals.suggestedValue(input): suggested value" | "input.selectionStart: 0"
diff --git a/third_party/WebKit/LayoutTests/fast/forms/suggested-value-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/suggested-value-expected.txt index 86c7f7a..961998a 100644 --- a/third_party/WebKit/LayoutTests/fast/forms/suggested-value-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/forms/suggested-value-expected.txt
@@ -14,6 +14,7 @@ | shadow:pseudoId="-internal-input-suggested" | "suggested value" | <div> +| "initial value" | <input> | id="month" | type="month" @@ -75,6 +76,7 @@ | shadow:pseudoId="-internal-input-suggested" | "suggested value" | <div> +| "initial value" | <select> | id="select" | <option>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/text/input-appearance-autocomplete-with-initial-value-expected.html b/third_party/WebKit/LayoutTests/fast/forms/text/input-appearance-autocomplete-with-initial-value-expected.html index 18a14ac5..8d30029 100644 --- a/third_party/WebKit/LayoutTests/fast/forms/text/input-appearance-autocomplete-with-initial-value-expected.html +++ b/third_party/WebKit/LayoutTests/fast/forms/text/input-appearance-autocomplete-with-initial-value-expected.html
@@ -1,6 +1,4 @@ -<input id="input" value="hello" style="width: 99px" > +<input id="input" value="hello" style="width: 99px"> <script> -input.focus(); -input.setSelectionRange(0,0); internals.setAutofilled(input, true); -</script> \ No newline at end of file +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/text/input-appearance-autocomplete-with-initial-value.html b/third_party/WebKit/LayoutTests/fast/forms/text/input-appearance-autocomplete-with-initial-value.html index b791583..66eae59 100644 --- a/third_party/WebKit/LayoutTests/fast/forms/text/input-appearance-autocomplete-with-initial-value.html +++ b/third_party/WebKit/LayoutTests/fast/forms/text/input-appearance-autocomplete-with-initial-value.html
@@ -1,6 +1,6 @@ <input id="input" > <script> -input.focus(); +// TODO(crbug.com/794966): SetFocus once the caret issue is resolved. input.value = "initial value"; internals.setSuggestedValue(input, 'hello'); internals.setAutofilled(input, true);
diff --git a/third_party/WebKit/LayoutTests/fast/url/query-expected.txt b/third_party/WebKit/LayoutTests/fast/url/query-expected.txt index e4816a5..54e43826 100644 --- a/third_party/WebKit/LayoutTests/fast/url/query-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/url/query-expected.txt
@@ -7,8 +7,8 @@ PASS canonicalize('http://www.example.com/?as?df') is 'http://www.example.com/?as?df' PASS canonicalize('http://www.example.com/?\x02hello bye') is 'http://www.example.com/?%02hello%7F%20bye' PASS canonicalize('http://www.example.com/?%40%41123') is 'http://www.example.com/?%40%41123' -PASS canonicalize('http://www.example.com/?q=ä½ å¥½') is 'http://www.example.com/?q=%26%2320320%3B%26%2322909%3B' -PASS canonicalize('http://www.example.com/?q=\ud800\ud800') is 'http://www.example.com/?q=%26%2355296%3B%26%2355296%3B' +PASS canonicalize('http://www.example.com/?q=ä½ å¥½') is 'http://www.example.com/?q=&%2320320;&%2322909;' +PASS canonicalize('http://www.example.com/?q=\ud800\ud800') is 'http://www.example.com/?q=&%2355296;&%2355296;' PASS canonicalize('http://www.example.com/?q=<asdf>') is 'http://www.example.com/?q=%3Casdf%3E' PASS canonicalize('http://www.example.com/?q="asdf"') is 'http://www.example.com/?q=%22asdf%22' PASS successfullyParsed is true
diff --git a/third_party/WebKit/LayoutTests/fast/url/script-tests/query.js b/third_party/WebKit/LayoutTests/fast/url/script-tests/query.js index dcb6028..0f3c153 100644 --- a/third_party/WebKit/LayoutTests/fast/url/script-tests/query.js +++ b/third_party/WebKit/LayoutTests/fast/url/script-tests/query.js
@@ -12,9 +12,9 @@ ["\\x02hello\x7f bye", "%02hello%7F%20bye"], ["%40%41123", "%40%41123"], // Chinese input/output - ["q=\u4F60\u597D", "q=%26%2320320%3B%26%2322909%3B"], + ["q=\u4F60\u597D", "q=&%2320320;&%2322909;"], // Invalid UTF-8/16 input should be replaced with invalid characters. - ["q=\\ud800\\ud800", "q=%26%2355296%3B%26%2355296%3B"], + ["q=\\ud800\\ud800", "q=&%2355296;&%2355296;"], // Don't allow < or > because sometimes they are used for XSS if the // URL is echoed in content. Firefox does this, IE doesn't. ["q=<asdf>", "q=%3Casdf%3E"],
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-bindings-frame-attach-detach-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-bindings-frame-attach-detach-expected.txt index 5d643296..3161791 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-bindings-frame-attach-detach-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-bindings-frame-attach-detach-expected.txt
@@ -3,15 +3,13 @@ Running: dumpInitialWorkspace Removed: 0 uiSourceCodes -Workspace: 3 uiSourceCodes. - debugger:///VM[XXX] +Workspace: 2 uiSourceCodes. debugger:///VM[XXX] http://127.0.0.1:8000/devtools/resources/inspected-page.html Running: attachFrame Removed: 0 uiSourceCodes -Workspace: 10 uiSourceCodes. - debugger:///VM[XXX] +Workspace: 9 uiSourceCodes. debugger:///VM[XXX] [+] debugger:///VM[XXX] dynamic-frame.html [+] debugger:///VM[XXX] dynamic-script.js @@ -27,8 +25,7 @@ [-] dynamic-script.js [-] dynamic-style.css [-] http://127.0.0.1:8000/devtools/bindings/resources/dynamic-frame.html -Workspace: 9 uiSourceCodes. - debugger:///VM[XXX] +Workspace: 8 uiSourceCodes. debugger:///VM[XXX] debugger:///VM[XXX] dynamic-frame.html debugger:///VM[XXX] dynamic-script.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-bindings-frame-attach-detach.js b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-bindings-frame-attach-detach.js index 07e9d9c..2f991e7 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-bindings-frame-attach-detach.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-bindings-frame-attach-detach.js
@@ -6,12 +6,6 @@ TestRunner.addResult( `Verify that UISourceCodes are added and removed as iframe with dynamic script and stylesheet is added and removed.\n`); await TestRunner.loadModule('bindings_test_runner'); - await TestRunner.loadHTML(` - <p> - Verify that UISourceCodes are added and removed as iframe with dynamic script - and stylesheet is added and removed. - </p> - `); TestRunner.markStep('dumpInitialWorkspace'); var snapshot = BindingsTestRunner.dumpWorkspace();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-navigator-frame-attach-detach.js b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-navigator-frame-attach-detach.js index 3b056c2..90078397 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-navigator-frame-attach-detach.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-navigator-frame-attach-detach.js
@@ -7,12 +7,6 @@ `Verify that navigator is rendered properly when frame with dynamic script and style is added and removed.\n`); await TestRunner.loadModule('sources_test_runner'); await TestRunner.loadModule('bindings_test_runner'); - await TestRunner.loadHTML(` - <p> - Verify that navigator is rendered properly when frame with dynamic script and - style is added and removed. - </p> - `); var sourcesNavigator = new Sources.SourcesNavigatorView(); sourcesNavigator.show(UI.inspectorView.element);
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-api-on-call-frame.js b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-api-on-call-frame.js index f2af54d..cf55aa34a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-api-on-call-frame.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-api-on-call-frame.js
@@ -10,13 +10,6 @@ await TestRunner.loadModule('sources_test_runner'); await TestRunner.showPanel('console'); - await TestRunner.loadHTML(` - <p> - Test that command line api does not mask values of scope variables while evaluating - on a call frame. - </p> - `); - await TestRunner.evaluateInPagePromise(` window.inspect = "inspect"; var clear = "clear";
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-format-style-whitelist-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-format-style-whitelist-expected.txt index 9078d1e..da9f93a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-format-style-whitelist-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-format-style-whitelist-expected.txt
@@ -1,15 +1,15 @@ Tests that console logging dumps properly styled messages, and that the whole message gets the same style, regardless of multiple %c settings. -console-format-style-whitelist.js:18 Colors are awesome. +console-format-style-whitelist.js:13 Colors are awesome. Styled text #0: color: blue; -console-format-style-whitelist.js:19 So are fonts! +console-format-style-whitelist.js:14 So are fonts! Styled text #0: font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: normal; font-family: Helvetica; -console-format-style-whitelist.js:20 And borders and margins and paddings! +console-format-style-whitelist.js:15 And borders and margins and paddings! Styled text #0: border: 1px solid red; margin: 20px; padding: 10px; -console-format-style-whitelist.js:21 text-* is fine by us! +console-format-style-whitelist.js:16 text-* is fine by us! Styled text #0: text-decoration: none; -console-format-style-whitelist.js:23 Display, on the other hand, is bad news. +console-format-style-whitelist.js:18 Display, on the other hand, is bad news. Styled text #0: NO STYLES DEFINED -console-format-style-whitelist.js:24 And position too. +console-format-style-whitelist.js:19 And position too. Styled text #0: NO STYLES DEFINED
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-format-style-whitelist.js b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-format-style-whitelist.js index 4734efb8..14219df 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-format-style-whitelist.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-format-style-whitelist.js
@@ -9,11 +9,6 @@ await TestRunner.loadModule('console_test_runner'); await TestRunner.showPanel('console'); - await TestRunner.loadHTML(` - <p>Tests that console logging dumps properly styled messages, and that - the whole message gets the same style, regardless of multiple %c - settings.</p> - `); await TestRunner.evaluateInPagePromise(` console.log('%cColors are awesome.', 'color: blue;'); console.log('%cSo are fonts!', 'font: 1em Helvetica;');
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-links-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-links-expected.txt index e723ca3..1920feb 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-links-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-links-expected.txt
@@ -1,10 +1,10 @@ Test that console.log() would linkify the links. Bug 231074. -console-log-linkify-links.js:16 http://www.chromium.org/ console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link -console-log-linkify-links.js:17 follow http://www.chromium.org/ console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link -console-log-linkify-links.js:18 string http://www.chromium.org/ console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link -console-log-linkify-links.js:19 123 "http://www.chromium.org/" console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > object-value-number source-code > object-value-string source-code > object-value-string-quote > devtools-link > object-value-string-quote -console-log-linkify-links.js:20 http://www.chromium.org/some?v=114:56:57 console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link +console-log-linkify-links.js:11 http://www.chromium.org/ console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link +console-log-linkify-links.js:12 follow http://www.chromium.org/ console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link +console-log-linkify-links.js:13 string http://www.chromium.org/ console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link +console-log-linkify-links.js:14 123 "http://www.chromium.org/" console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > object-value-number source-code > object-value-string source-code > object-value-string-quote > devtools-link > object-value-string-quote +console-log-linkify-links.js:15 http://www.chromium.org/some?v=114:56:57 console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link Dump urls in messages linked url:null linked url:http://www.chromium.org/
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-links.js b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-links.js index 0595d08..78edefa 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-links.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-links.js
@@ -7,11 +7,6 @@ await TestRunner.loadModule('console_test_runner'); await TestRunner.showPanel('console'); - await TestRunner.loadHTML(` - <p> - Test that console.log() would linkify the links. <a href="http://crbug.com/231074">Bug 231074.</a> - </p> - `); await TestRunner.evaluateInPagePromise(` console.log("http://www.chromium.org/"); console.log("follow http://www.chromium.org/");
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-stack-in-errors-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-stack-in-errors-expected.txt index 455750c..faaafb9 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-stack-in-errors-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-stack-in-errors-expected.txt
@@ -3,62 +3,62 @@ foob.js:5 Error: Some test at namedFunction (foob.js:5) at foob.js:8 console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link -console-log-linkify-…ack-in-errors.js:20 Error: line +console-log-linkify-…ack-in-errors.js:15 Error: line break - at forStack (console-log-linkify-…ack-in-errors.js:20) - at console-log-linkify-…ack-in-errors.js:23 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis -console-log-linkify-…ack-in-errors.js:39 Error: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node. - at domError (console-log-linkify-…ack-in-errors.js:37) - at console-log-linkify-…ack-in-errors.js:43 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis -console-log-linkify-…ack-in-errors.js:50 Error: some error - at logError (console-log-linkify-…ack-in-errors.js:48) - at console-log-linkify-…ack-in-errors.js:54 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > object-value-error source-code > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis -console-log-linkify-…ack-in-errors.js:56 Error message without stacks http://www.chromium.org/ console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link -console-log-linkify-…ack-in-errors.js:58 Error valid stack #2 + at forStack (console-log-linkify-…ack-in-errors.js:15) + at console-log-linkify-…ack-in-errors.js:18 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis +console-log-linkify-…ack-in-errors.js:34 Error: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node. + at domError (console-log-linkify-…ack-in-errors.js:32) + at console-log-linkify-…ack-in-errors.js:38 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis +console-log-linkify-…ack-in-errors.js:45 Error: some error + at logError (console-log-linkify-…ack-in-errors.js:43) + at console-log-linkify-…ack-in-errors.js:49 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > object-value-error source-code > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis +console-log-linkify-…ack-in-errors.js:51 Error message without stacks http://www.chromium.org/ console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link +console-log-linkify-…ack-in-errors.js:53 Error valid stack #2 at www.chromium.org/boo.js:40 at foo(www.chromium.org/foo.js:10) console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link -console-log-linkify-…ack-in-errors.js:59 Error valid stack #3 +console-log-linkify-…ack-in-errors.js:54 Error valid stack #3 at www.chromium.org/foo.js:40 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link -console-log-linkify-…ack-in-errors.js:60 Error: MyError +console-log-linkify-…ack-in-errors.js:55 Error: MyError at throwError (www.chromium.org/foo.js:40) at eval (eval at <anonymous> (www.chromium.org/foo.js:42), <anonymous>:1:1) at www.chromium.org/foo.js:239 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link > devtools-link -console-log-linkify-…ack-in-errors.js:29 ReferenceError: valid stack - at stack2 (console-log-linkify-…ack-in-errors.js:29) - at stack1 (console-log-linkify-…ack-in-errors.js:31) +console-log-linkify-…ack-in-errors.js:24 ReferenceError: valid stack + at stack2 (console-log-linkify-…ack-in-errors.js:24) + at stack1 (console-log-linkify-…ack-in-errors.js:26) + at console-log-linkify-…ack-in-errors.js:57 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis +console-log-linkify-…ack-in-errors.js:24 EvalError: valid stack + at stack2 (console-log-linkify-…ack-in-errors.js:24) + at stack1 (console-log-linkify-…ack-in-errors.js:26) + at console-log-linkify-…ack-in-errors.js:58 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis +console-log-linkify-…ack-in-errors.js:24 SyntaxError: valid stack + at stack2 (console-log-linkify-…ack-in-errors.js:24) + at stack1 (console-log-linkify-…ack-in-errors.js:26) + at console-log-linkify-…ack-in-errors.js:59 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis +console-log-linkify-…ack-in-errors.js:24 RangeError: valid stack + at stack2 (console-log-linkify-…ack-in-errors.js:24) + at stack1 (console-log-linkify-…ack-in-errors.js:26) + at console-log-linkify-…ack-in-errors.js:60 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis +console-log-linkify-…ack-in-errors.js:24 TypeError: valid stack + at stack2 (console-log-linkify-…ack-in-errors.js:24) + at stack1 (console-log-linkify-…ack-in-errors.js:26) + at console-log-linkify-…ack-in-errors.js:61 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis +console-log-linkify-…ack-in-errors.js:24 URIError: valid stack + at stack2 (console-log-linkify-…ack-in-errors.js:24) + at stack1 (console-log-linkify-…ack-in-errors.js:26) at console-log-linkify-…ack-in-errors.js:62 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis -console-log-linkify-…ack-in-errors.js:29 EvalError: valid stack - at stack2 (console-log-linkify-…ack-in-errors.js:29) - at stack1 (console-log-linkify-…ack-in-errors.js:31) - at console-log-linkify-…ack-in-errors.js:63 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis -console-log-linkify-…ack-in-errors.js:29 SyntaxError: valid stack - at stack2 (console-log-linkify-…ack-in-errors.js:29) - at stack1 (console-log-linkify-…ack-in-errors.js:31) - at console-log-linkify-…ack-in-errors.js:64 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis -console-log-linkify-…ack-in-errors.js:29 RangeError: valid stack - at stack2 (console-log-linkify-…ack-in-errors.js:29) - at stack1 (console-log-linkify-…ack-in-errors.js:31) - at console-log-linkify-…ack-in-errors.js:65 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis -console-log-linkify-…ack-in-errors.js:29 TypeError: valid stack - at stack2 (console-log-linkify-…ack-in-errors.js:29) - at stack1 (console-log-linkify-…ack-in-errors.js:31) - at console-log-linkify-…ack-in-errors.js:66 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis -console-log-linkify-…ack-in-errors.js:29 URIError: valid stack - at stack2 (console-log-linkify-…ack-in-errors.js:29) - at stack1 (console-log-linkify-…ack-in-errors.js:31) - at console-log-linkify-…ack-in-errors.js:67 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis > devtools-link > devtools-link-ellipsis -console-log-linkify-…ack-in-errors.js:69 Error broken stack +console-log-linkify-…ack-in-errors.js:64 Error broken stack at function_name(foob.js foob.js:30) at foob.js:40 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link > devtools-link -console-log-linkify-…ack-in-errors.js:70 Error broken stack #2 +console-log-linkify-…ack-in-errors.js:65 Error broken stack #2 at function_name(foob.js:20 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link -console-log-linkify-…ack-in-errors.js:71 Error broken stack #3 +console-log-linkify-…ack-in-errors.js:66 Error broken stack #3 at function_name(foob:20.js:30 bla console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link -console-log-linkify-…ack-in-errors.js:72 Error broken stack #4 +console-log-linkify-…ack-in-errors.js:67 Error broken stack #4 at function_name)foob.js:20:30( console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link -console-log-linkify-…ack-in-errors.js:73 Error broken stack #5 +console-log-linkify-…ack-in-errors.js:68 Error broken stack #5 at function_name foob.js:20:30) console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link -console-log-linkify-…ack-in-errors.js:74 Error broken stack #6 +console-log-linkify-…ack-in-errors.js:69 Error broken stack #6 at foob.js foob.js:40 console-message > source-code > console-message-anchor > devtools-link > devtools-link-ellipsis > hidden console-message-badge > hide-badge-title > console-message-text > devtools-link stack-with-sourceMap.coffee:3 Error at Failure.letsFailWithStack (stack-with-sourceMap.coffee:3)
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-stack-in-errors.js b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-stack-in-errors.js index 84a1e326..9194ea5 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-stack-in-errors.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-log-linkify-stack-in-errors.js
@@ -7,11 +7,6 @@ `Test that console.log(new Error().stack) would linkify links in stacks for sourceUrls and sourceMaps Bug 424001.\n`); await TestRunner.loadModule('console_test_runner'); await TestRunner.showPanel('console'); - await TestRunner.loadHTML(` - <p> - Test that console.log(new Error().stack) would linkify links in stacks for sourceUrls and sourceMaps <a href="http://crbug.com/424001">Bug 424001.</a> - </p> - `); await TestRunner.addScriptTag('resources/stack-with-sourceUrl.js'); await TestRunner.addScriptTag('resources/stack-with-sourceMap.js'); await TestRunner.evaluateInPagePromise(`
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/only-one-deprecation-warning-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/console/only-one-deprecation-warning-expected.txt index 8d35950..38ce616 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/only-one-deprecation-warning-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/only-one-deprecation-warning-expected.txt
@@ -1,5 +1,5 @@ This test passes if only one deprecation warning is presented in the console. -only-one-deprecation-warning.js:13 [Deprecation] 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead. -(anonymous) @ only-one-deprecation-warning.js:13 +only-one-deprecation-warning.js:10 [Deprecation] 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead. +(anonymous) @ only-one-deprecation-warning.js:10
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/only-one-deprecation-warning.js b/third_party/WebKit/LayoutTests/http/tests/devtools/console/only-one-deprecation-warning.js index 92a5c8b..09b4afd 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/console/only-one-deprecation-warning.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/only-one-deprecation-warning.js
@@ -6,9 +6,6 @@ TestRunner.addResult(`This test passes if only one deprecation warning is presented in the console.\n`); await TestRunner.showPanel('console'); await TestRunner.loadModule('console_test_runner'); - await TestRunner.loadHTML(` - <!DOCTYPE html> - `); await TestRunner.evaluateInPagePromise(` var x = window.webkitStorageInfo; var y = window.webkitStorageInfo;
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/iframe-load-event-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/iframe-load-event-expected.txt index d3c0bcf..709d06a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/iframe-load-event-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/iframe-load-event-expected.txt
@@ -17,6 +17,7 @@ </body> </html> </iframe> + "\n \n " </body> </html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/iframe-load-event.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/iframe-load-event.js index 1aca7e6..fc48714 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/iframe-load-event.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/iframe-load-event.js
@@ -6,7 +6,6 @@ TestRunner.addResult(`Tests that iframe content is available after iframe's load event fired. See http://webkit.org/b/76552\n`); await TestRunner.loadModule('elements_test_runner'); await TestRunner.showPanel('elements'); - await TestRunner.loadHTML(``); await TestRunner.addIframe('resources/iframe-load-event-iframe-1.html', {id: 'myframe'}); ElementsTestRunner.expandElementsTree(step1);
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/input-event-warning.js b/third_party/WebKit/LayoutTests/http/tests/devtools/input-event-warning.js index 7895d9f4..0676255 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/input-event-warning.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/input-event-warning.js
@@ -5,10 +5,6 @@ (async function() { TestRunner.addResult( `Tests that console warnings are issued for a blocked event listener and that there is no crash when an offending listener is removed by the handler.\n`); - await TestRunner.loadHTML(` - <p>Tests that console warnings are issued for a blocked event listener and that - there is no crash when an offending listener is removed by the handler.</p> - `); await TestRunner.evaluateInPagePromise(` function eventListenerSuicidal(event) {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/inspector-backend-commands.js b/third_party/WebKit/LayoutTests/http/tests/devtools/inspector-backend-commands.js index 9441328..9fbcd845 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/inspector-backend-commands.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/inspector-backend-commands.js
@@ -4,9 +4,6 @@ (async function() { TestRunner.addResult(`Tests correctness of promisified protocol commands.\n`); - await TestRunner.loadHTML(` - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> - `); Protocol.InspectorBackend.Options.suppressRequestErrors = false; function dumpArgument(name, value) {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-cachedresources-with-same-urls.js b/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-cachedresources-with-same-urls.js index 5e30be3..52a6e86 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-cachedresources-with-same-urls.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-cachedresources-with-same-urls.js
@@ -8,10 +8,6 @@ await TestRunner.loadModule('network_test_runner'); await TestRunner.loadModule('console_test_runner'); await TestRunner.showPanel('network'); - await TestRunner.loadHTML(` - <p>Tests that when we load two different images from the same url (e.g. counters), - their content is different in network panel as well.</p> - `); await TestRunner.evaluateInPagePromise(` function loadImages() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-xhr-async-response-type-blob.js b/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-xhr-async-response-type-blob.js index d6ed2b77..fd3df24 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-xhr-async-response-type-blob.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-xhr-async-response-type-blob.js
@@ -7,11 +7,6 @@ `Tests XHR network resource type and size for asynchronous requests when "blob" is specified as the response type.\n`); await TestRunner.loadModule('network_test_runner'); await TestRunner.showPanel('network'); - await TestRunner.loadHTML(` - <p> - Tests XHR network resource type and size for asynchronous requests when "blob" is specified as the response type. - </p> - `); NetworkTestRunner.recordNetwork(); NetworkTestRunner.makeXHR(
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-xhr-data-received-async-response-type-blob.js b/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-xhr-data-received-async-response-type-blob.js index b6a9a9e..9b97929 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-xhr-data-received-async-response-type-blob.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-xhr-data-received-async-response-type-blob.js
@@ -6,9 +6,6 @@ TestRunner.addResult(`Tests that dataReceived is called on NetworkDispatcher for XHR with responseType="blob".\n`); await TestRunner.loadModule('network_test_runner'); await TestRunner.showPanel('network'); - await TestRunner.loadHTML(` - <p>Tests that dataReceived is called on NetworkDispatcher for XHR with responseType="blob".</p> - `); TestRunner.addSniffer(SDK.NetworkDispatcher.prototype, 'dataReceived', dataReceived);
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-xhr-redirect-body.js b/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-xhr-redirect-body.js index 49fbe178..37859098 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-xhr-redirect-body.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/network/network-xhr-redirect-body.js
@@ -6,7 +6,6 @@ await TestRunner.addResult(`Tests that XHR redirects preserve request body.`); await TestRunner.loadModule('network_test_runner'); await TestRunner.showPanel('network'); - await TestRunner.loadHTML(`<p>Tests that XHR redirects preserve request body.</p>`); var offset;
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/persistence/automapping-sourcemap-nameclash.js b/third_party/WebKit/LayoutTests/http/tests/devtools/persistence/automapping-sourcemap-nameclash.js index 32b98ac..e4024ff4 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/persistence/automapping-sourcemap-nameclash.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/persistence/automapping-sourcemap-nameclash.js
@@ -8,10 +8,6 @@ await TestRunner.loadModule('bindings_test_runner'); await TestRunner.loadModule('sources_test_runner'); await TestRunner.showPanel('sources'); - await TestRunner.loadHTML(` - <p>Verify that sourcemap sources are mapped event when sourcemap compiled url matches with one of the - source urls.</p> - `); await TestRunner.addScriptTag('resources/sourcemap-name-clash/out.js'); BindingsTestRunner.initializeTestMapping();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-comparison-show-next.js b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-comparison-show-next.js index 037563f..4dead447 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-comparison-show-next.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-comparison-show-next.js
@@ -7,12 +7,6 @@ `Tests Comparison view of detailed heap snapshots. Repeated clicks on "Show Next" button must show all nodes.\n`); await TestRunner.loadModule('heap_profiler_test_runner'); await TestRunner.showPanel('heap_profiler'); - await TestRunner.loadHTML(` - <p> - Tests Comparison view of detailed heap snapshots. - Repeated clicks on "Show Next" button must show all nodes. - </p> - `); var instanceCount = 24; function createHeapSnapshotA() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-comparison-shown-node-count-preserved-when-sorting.js b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-comparison-shown-node-count-preserved-when-sorting.js index 2d7d931..53952a6 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-comparison-shown-node-count-preserved-when-sorting.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-comparison-shown-node-count-preserved-when-sorting.js
@@ -7,12 +7,6 @@ `Tests Comparison view of detailed heap snapshots. Shown node count must be preserved after sorting.\n`); await TestRunner.loadModule('heap_profiler_test_runner'); await TestRunner.showPanel('heap_profiler'); - await TestRunner.loadHTML(` - <p> - Tests Comparison view of detailed heap snapshots. - Shown node count must be preserved after sorting. - </p> - `); var instanceCount = 24; function createHeapSnapshotA() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-expansion-preserved-when-sorting.js b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-expansion-preserved-when-sorting.js index f9ad9df..2558383 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-expansion-preserved-when-sorting.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-expansion-preserved-when-sorting.js
@@ -7,12 +7,6 @@ `Tests Containment view of detailed heap snapshots. Expanded nodes must be preserved after sorting.\n`); await TestRunner.loadModule('heap_profiler_test_runner'); await TestRunner.showPanel('heap_profiler'); - await TestRunner.loadHTML(` - <p> - Tests Containment view of detailed heap snapshots. - Expanded nodes must be preserved after sorting. - </p> - `); var instanceCount = 25; function createHeapSnapshot() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-show-all.js b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-show-all.js index 3d4a658..a9c3ecc7 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-show-all.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-show-all.js
@@ -7,13 +7,6 @@ `Tests Containment view of detailed heap snapshots. The "Show All" button must show all nodes. Test object distances calculation.\n`); await TestRunner.loadModule('heap_profiler_test_runner'); await TestRunner.showPanel('heap_profiler'); - await TestRunner.loadHTML(` - <p> - Tests Containment view of detailed heap snapshots. - The "Show All" button must show all nodes. - Test object distances calculation. - </p> - `); var instanceCount = 25; function createHeapSnapshot() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-show-next.js b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-show-next.js index 423f551..31658b9 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-show-next.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-show-next.js
@@ -7,12 +7,6 @@ `Tests Containment view of detailed heap snapshots. Repeated clicks on "Show Next" button must show all nodes.\n`); await TestRunner.loadModule('heap_profiler_test_runner'); await TestRunner.showPanel('heap_profiler'); - await TestRunner.loadHTML(` - <p> - Tests Containment view of detailed heap snapshots. - Repeated clicks on "Show Next" button must show all nodes. - </p> - `); var instanceCount = 25; function createHeapSnapshot() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-shown-node-count-preserved-when-sorting.js b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-shown-node-count-preserved-when-sorting.js index 138a010..060c1344 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-shown-node-count-preserved-when-sorting.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-containment-shown-node-count-preserved-when-sorting.js
@@ -7,12 +7,6 @@ `Tests Containment view of detailed heap snapshots. Shown node count must be preserved after sorting.\n`); await TestRunner.loadModule('heap_profiler_test_runner'); await TestRunner.showPanel('heap_profiler'); - await TestRunner.loadHTML(` - <p> - Tests Containment view of detailed heap snapshots. - Shown node count must be preserved after sorting. - </p> - `); var instanceCount = 25; function createHeapSnapshot() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-expand-collapse.js b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-expand-collapse.js index cdce744b..5d5a79f 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-expand-collapse.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-expand-collapse.js
@@ -7,12 +7,6 @@ `https://crbug.com/738932 Tests the snapshot view is not empty on repeatitive expand-collapse.\n`); await TestRunner.loadModule('heap_profiler_test_runner'); await TestRunner.showPanel('heap_profiler'); - await TestRunner.loadHTML(` - <p> - https://crbug.com/738932 - Tests the snapshot view is not empty on repeatitive expand-collapse. - </p> - `); var instanceCount = 25; function createHeapSnapshot() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-expansion-preserved-when-sorting.js b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-expansion-preserved-when-sorting.js index 2bc1325d..0018820 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-expansion-preserved-when-sorting.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-expansion-preserved-when-sorting.js
@@ -7,12 +7,6 @@ `Tests Summary view of detailed heap snapshots. Expanded nodes must be preserved after sorting.\n`); await TestRunner.loadModule('heap_profiler_test_runner'); await TestRunner.showPanel('heap_profiler'); - await TestRunner.loadHTML(` - <p> - Tests Summary view of detailed heap snapshots. - Expanded nodes must be preserved after sorting. - </p> - `); var instanceCount = 25; function createHeapSnapshot() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-show-all.js b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-show-all.js index 7ede04e..a1a4d95 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-show-all.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-show-all.js
@@ -6,12 +6,6 @@ TestRunner.addResult(`Tests Summary view of detailed heap snapshots. The "Show All" button must show all nodes.\n`); await TestRunner.loadModule('heap_profiler_test_runner'); await TestRunner.showPanel('heap_profiler'); - await TestRunner.loadHTML(` - <p> - Tests Summary view of detailed heap snapshots. - The "Show All" button must show all nodes. - </p> - `); var instanceCount = 25; function createHeapSnapshot() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-show-next.js b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-show-next.js index 22ca9bc..9e723d14 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-show-next.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-show-next.js
@@ -7,12 +7,6 @@ `Tests Summary view of detailed heap snapshots. Repeated clicks on "Show Next" button must show all nodes.\n`); await TestRunner.loadModule('heap_profiler_test_runner'); await TestRunner.showPanel('heap_profiler'); - await TestRunner.loadHTML(` - <p> - Tests Summary view of detailed heap snapshots. - Repeated clicks on "Show Next" button must show all nodes. - </p> - `); var instanceCount = 25; function createHeapSnapshot() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-shown-node-count-preserved-when-sorting.js b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-shown-node-count-preserved-when-sorting.js index d8b5d80a..5c806f1b 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-shown-node-count-preserved-when-sorting.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/profiler/heap-snapshot-summary-shown-node-count-preserved-when-sorting.js
@@ -7,12 +7,6 @@ `Tests Summary view of detailed heap snapshots. Shown node count must be preserved after sorting.\n`); await TestRunner.loadModule('heap_profiler_test_runner'); await TestRunner.showPanel('heap_profiler'); - await TestRunner.loadHTML(` - <p> - Tests Summary view of detailed heap snapshots. - Shown node count must be preserved after sorting. - </p> - `); var instanceCount = 25; function createHeapSnapshot() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-cors.js b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-cors.js index bb74e50..1645adb 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-cors.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-cors.js
@@ -5,13 +5,10 @@ (async function() { TestRunner.addResult(`Tests "Bypass for network" checkbox works with CORS requests. crbug.com/771742\n`); await TestRunner.loadModule('application_test_runner'); - // Note: every test that uses a storage API must manually clean-up state from previous tests. + // Note: every test that uses a storage API must manually clean-up state from previous tests. await ApplicationTestRunner.resetState(); await TestRunner.showPanel('resources'); - await TestRunner.loadHTML(` - <p>Tests "Bypass for network" checkbox works with CORS requests. crbug.com/771742</p> - `); await TestRunner.evaluateInPagePromise(` function takeInterceptedRequests(scope) { return new Promise((resolve) => {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-navigation.js b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-navigation.js index 0d2b3396b..4d9a5ee 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-navigation.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-navigation.js
@@ -5,13 +5,10 @@ (async function() { TestRunner.addResult(`Tests "Bypass for network" checkbox works with navigations. crbug.com/746220\n`); await TestRunner.loadModule('application_test_runner'); - // Note: every test that uses a storage API must manually clean-up state from previous tests. + // Note: every test that uses a storage API must manually clean-up state from previous tests. await ApplicationTestRunner.resetState(); await TestRunner.showPanel('resources'); - await TestRunner.loadHTML(` - <p>Tests "Bypass for network" checkbox works with navigations. crbug.com/746220</p> - `); await TestRunner.evaluateInPagePromise(` function getIframeBodyText(id) { return document.getElementById(id).contentWindow.document.body.innerText;
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-redirect.js b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-redirect.js index 8f88649a..969ea1c9 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-redirect.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-bypass-for-network-redirect.js
@@ -5,14 +5,11 @@ (async function() { TestRunner.addResult(`Tests "Bypass for network" checkbox with redirection doesn't cause crash.\n`); await TestRunner.loadModule('application_test_runner'); - // Note: every test that uses a storage API must manually clean-up state from previous tests. + // Note: every test that uses a storage API must manually clean-up state from previous tests. await ApplicationTestRunner.resetState(); await TestRunner.loadModule('console_test_runner'); await TestRunner.showPanel('resources'); - await TestRunner.loadHTML(` - <p>Tests "Bypass for network" checkbox with redirection doesn't cause crash.</p> - `); const url = 'http://localhost:8000/devtools/service-workers/resources/' + 'bypass-for-network-redirect.php';
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-force-update-on-page-load.js b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-force-update-on-page-load.js index 3f36bab..456cc7c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-force-update-on-page-load.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-workers-force-update-on-page-load.js
@@ -5,13 +5,10 @@ (async function() { TestRunner.addResult(`Tests "Force update on page load" checkbox\n`); await TestRunner.loadModule('application_test_runner'); - // Note: every test that uses a storage API must manually clean-up state from previous tests. + // Note: every test that uses a storage API must manually clean-up state from previous tests. await ApplicationTestRunner.resetState(); await TestRunner.showPanel('resources'); - await TestRunner.loadHTML(` - <p>Tests "Force update on page load" checkbox</p> - `); const scriptURL = 'http://127.0.0.1:8000/devtools/service-workers/resources/force-update-on-page-load-worker.php'; const scope = 'http://127.0.0.1:8000/devtools/service-workers/resources/service-worker-force-update-on-page-load/';
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/autocomplete-general.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/autocomplete-general.js index d471d1b..ac7a9f1 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/autocomplete-general.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/autocomplete-general.js
@@ -7,12 +7,6 @@ `This test checks how text editor updates autocompletion dictionary in a response to user input.\n`); await TestRunner.loadModule('sources_test_runner'); await TestRunner.showPanel('sources'); - await TestRunner.loadHTML(` - <p> - This test checks how text editor updates autocompletion dictionary in a response - to user input. - </p> - `); await TestRunner.addScriptTag('debugger/resources/edit-me.js'); await TestRunner.addScriptTag('../resources/editor-test.js');
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-breakpoints/breakpoints-in-anonymous-script-with-two-targets.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-breakpoints/breakpoints-in-anonymous-script-with-two-targets.js index 753a618..d51002c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-breakpoints/breakpoints-in-anonymous-script-with-two-targets.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-breakpoints/breakpoints-in-anonymous-script-with-two-targets.js
@@ -6,9 +6,6 @@ TestRunner.addResult(`Tests that breakpoints work in anonymous scripts with >1 targets.\n`); await TestRunner.loadModule('sources_test_runner'); await TestRunner.showPanel('sources'); - await TestRunner.loadHTML(` - <p>Tests that breakpoints work in anonymous scripts with >1 targets.</p> - `); await TestRunner.evaluateInPagePromise(` function testFunction() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused.js index 8c09d38..1ed1fbe 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused.js
@@ -8,12 +8,6 @@ await TestRunner.loadModule('console_test_runner'); await TestRunner.loadModule('sources_test_runner'); await TestRunner.showPanel('sources'); - await TestRunner.loadHTML(` - <p> - Tests that evaluation in console works fine when script is paused. It also checks that - stack and global variables are accessible from the console. - </p> - `); await TestRunner.evaluateInPagePromise(` var globalVar = { b: 1 };
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-pause-on-debugger-statement.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-pause-on-debugger-statement.js index e02e6d0..be92ba7 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-pause-on-debugger-statement.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-pause-on-debugger-statement.js
@@ -7,11 +7,6 @@ `Tests that debugger will stop on "debugger" statement.\n`); await TestRunner.loadModule('sources_test_runner'); await TestRunner.showPanel('sources'); - await TestRunner.loadHTML(` - <p> - Tests that debugger will stop on "debugger" statement. - </p> - `); await TestRunner.evaluateInPagePromise(` function testFunction() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-pause-with-overrides-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-pause-with-overrides-expected.txt index a8a5e8e4..f056895 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-pause-with-overrides-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-pause-with-overrides-expected.txt
@@ -3,6 +3,6 @@ Set timer for test function. Script execution paused. Call stack: - 0) testFunction (debugger-pause-with-overrides.js:19) + 0) testFunction (debugger-pause-with-overrides.js:14) Script execution resumed.
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-pause-with-overrides.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-pause-with-overrides.js index f5e562d..78cf3a2 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-pause-with-overrides.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-pause-with-overrides.js
@@ -7,11 +7,6 @@ `Tests that debugger will stop on "debugger" statement w/ overriden string, etc.\n`); await TestRunner.loadModule('sources_test_runner'); await TestRunner.showPanel('sources'); - await TestRunner.loadHTML(` - <p> - Tests that debugger will stop on "debugger" statement w/ overriden string, etc. - </p> - `); await TestRunner.evaluateInPagePromise(` function testFunction() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-in-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-in-expected.txt index abcb3f25..94719b1 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-in-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-in-expected.txt
@@ -3,17 +3,17 @@ Set timer for test function. Script execution paused. Call stack: - 0) testFunction (debugger-step-in.js:22) + 0) testFunction (debugger-step-in.js:17) Stepping into... Script execution resumed. Script execution paused. Call stack: - 0) testFunction (debugger-step-in.js:23) + 0) testFunction (debugger-step-in.js:18) Stepping into... Script execution resumed. Script execution paused. Call stack: - 0) d (debugger-step-in.js:17) - 1) testFunction (debugger-step-in.js:23) + 0) d (debugger-step-in.js:12) + 1) testFunction (debugger-step-in.js:18) Script execution resumed.
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-in.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-in.js index 5fcb6a4..bf68180b 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-in.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-in.js
@@ -6,11 +6,6 @@ TestRunner.addResult(`Tests "step in" functionality in debugger.\n`); await TestRunner.loadModule('sources_test_runner'); await TestRunner.showPanel('sources'); - await TestRunner.loadHTML(` - <p> - Tests "step in" functionality in debugger. - </p> - `); await TestRunner.evaluateInPagePromise(` function d() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-out-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-out-expected.txt index 9f600ba..4c3afbe 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-out-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-out-expected.txt
@@ -3,12 +3,12 @@ Set timer for test function. Script execution paused. Call stack: - 0) d (debugger-step-out.js:17) - 1) testFunction (debugger-step-out.js:22) + 0) d (debugger-step-out.js:12) + 1) testFunction (debugger-step-out.js:17) Stepping out... Script execution resumed. Script execution paused. Call stack: - 0) testFunction (debugger-step-out.js:23) + 0) testFunction (debugger-step-out.js:18) Script execution resumed.
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-out.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-out.js index e217bd7..72df7b4 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-out.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-out.js
@@ -6,11 +6,6 @@ TestRunner.addResult(`Tests "step out" functionality in debugger.\n`); await TestRunner.loadModule('sources_test_runner'); await TestRunner.showPanel('sources'); - await TestRunner.loadHTML(` - <p> - Tests "step out" functionality in debugger. - </p> - `); await TestRunner.evaluateInPagePromise(` function d() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-over-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-over-expected.txt index 78d57d4..79815e7 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-over-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-over-expected.txt
@@ -3,19 +3,19 @@ Set timer for test function. Script execution paused. Call stack: - 0) d (debugger-step-over.js:22) - 1) testFunction (debugger-step-over.js:28) + 0) d (debugger-step-over.js:17) + 1) testFunction (debugger-step-over.js:23) Stepping over... Script execution resumed. Script execution paused. Call stack: - 0) d (debugger-step-over.js:23) - 1) testFunction (debugger-step-over.js:28) + 0) d (debugger-step-over.js:18) + 1) testFunction (debugger-step-over.js:23) Stepping over... Script execution resumed. Script execution paused. Call stack: - 0) d (debugger-step-over.js:24) - 1) testFunction (debugger-step-over.js:28) + 0) d (debugger-step-over.js:19) + 1) testFunction (debugger-step-over.js:23) Script execution resumed.
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-over.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-over.js index 1967a09..9c4b4a80 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-over.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-step/debugger-step-over.js
@@ -6,11 +6,6 @@ TestRunner.addResult(`Tests "step over" functionality in debugger.\n`); await TestRunner.loadModule('sources_test_runner'); await TestRunner.showPanel('sources'); - await TestRunner.loadHTML(` - <p> - Tests "step over" functionality in debugger. - </p> - `); await TestRunner.evaluateInPagePromise(` function f() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-function-definition-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-function-definition-expected.txt index eeb2bf3d..6e4dff8 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-function-definition-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-function-definition-expected.txt
@@ -2,7 +2,7 @@ Running: testRevealFunctionDefinition -Function location revealed: [15:24] +Function location revealed: [10:24] Running: testDumpFunctionDefinition jumpToMe
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-function-definition.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-function-definition.js index fce85b5..517f5a3 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-function-definition.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-function-definition.js
@@ -6,11 +6,6 @@ TestRunner.addResult(`Tests that "Show Function Definition" jumps to the correct location.\n`); await TestRunner.loadModule('console_test_runner'); await TestRunner.showPanel('sources'); - await TestRunner.loadHTML(` - <p> - Tests that "Show Function Definition" jumps to the correct location. - </p> - `); await TestRunner.evaluateInPagePromise(` function jumpToMe() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-generator-location-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-generator-location-expected.txt index 873bc63..0a293f9 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-generator-location-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-generator-location-expected.txt
@@ -2,17 +2,17 @@ Running: testIterNotStarted -Generator location revealed: [22:20] +Generator location revealed: [17:20] Running: testIterSuspended1 -Generator location revealed: [24:11] +Generator location revealed: [19:11] Running: testIterSuspended2 -Generator location revealed: [25:11] +Generator location revealed: [20:11] Running: testIterSuspended3 -Generator location revealed: [26:11] +Generator location revealed: [21:11] Running: testIterClosed -Generator location revealed: [22:20] +Generator location revealed: [17:20]
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-generator-location.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-generator-location.js index 3add889..8f21c435 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-generator-location.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/show-generator-location.js
@@ -6,11 +6,6 @@ TestRunner.addResult(`Tests that "Show Generator Location" jumps to the correct location.\n`); await TestRunner.loadModule('console_test_runner'); await TestRunner.showPanel('sources'); - await TestRunner.loadHTML(` - <p> - Tests that "Show Generator Location" jumps to the correct location. - </p> - `); await TestRunner.evaluateInPagePromise(` function forward(iter, step) {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/source-frame.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/source-frame.js index 42307d1..3d9c59c3 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/source-frame.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/source-frame.js
@@ -10,11 +10,6 @@ await TestRunner.loadModule('network_test_runner'); await TestRunner.loadModule('application_test_runner'); await TestRunner.showPanel('sources'); - await TestRunner.loadHTML(` - <p>Tests that it's possible to set breakpoint in source frame, and that - source frame displays breakpoints and console errors. - </p> - `); await TestRunner.evaluateInPagePromise(` function addErrorToConsole() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/debugger-completions-on-call-frame.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/debugger-completions-on-call-frame.js index 43d34c3..ce088ea9 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/debugger-completions-on-call-frame.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/debugger-completions-on-call-frame.js
@@ -7,12 +7,6 @@ `Test that completions in the context of the call frame will result in names of its scope variables.\n`); await TestRunner.loadModule('sources_test_runner'); await TestRunner.showPanel('sources'); - await TestRunner.loadHTML(` - <p> - Test that completions in the context of the call frame will result in names - of its scope variables. - </p> - `); await TestRunner.evaluateInPagePromise(` var a = 1; function testFunction()
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/navigator-view-content-scripts.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/navigator-view-content-scripts.js index 7958924..f4ce881c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/navigator-view-content-scripts.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/navigator-view-content-scripts.js
@@ -7,10 +7,6 @@ `Verify that removal of one of the multiple projects, all of which are associated with the same frame, doesn't lead navigator to discard the frame treenode.\n`); await TestRunner.loadModule('sources_test_runner'); await TestRunner.showPanel('sources'); - await TestRunner.loadHTML(` - <p>Verify that removal of one of the multiple projects, all of which are associated with the same - frame, doesn't lead navigator to discard the frame treenode.</p> - `); var rootURL = 'http://localhost:8080/LayoutTests/inspector/debugger/'; var sourcesNavigatorView = new Sources.SourcesNavigatorView();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/pretty-print-html-2.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/pretty-print-html-2.js index 37e6a54..53efb6c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/pretty-print-html-2.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/pretty-print-html-2.js
@@ -6,9 +6,6 @@ TestRunner.addResult(`Verifies JavaScript pretty-printing functionality.\n`); await TestRunner.loadModule('sources_test_runner'); await TestRunner.showPanel('sources'); - await TestRunner.loadHTML(` - <!DOCTYPE HTML><body>hello, world</body> - `); var testFormatter = SourcesTestRunner.testPrettyPrint.bind(SourcesTestRunner, 'text/html');
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/syntax-highlight-html.js b/third_party/WebKit/LayoutTests/http/tests/devtools/syntax-highlight-html.js index 8b108f8..58b7287 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/syntax-highlight-html.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/syntax-highlight-html.js
@@ -4,9 +4,6 @@ (async function() { TestRunner.addResult(`Tests that SourceHTMLTokenizer detects the tokens.\n`); - await TestRunner.loadHTML(` - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> - `); function dumpSyntaxHighlightHTML(str) { return TestRunner.dumpSyntaxHighlight(str, 'text/html');
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/buffer-usage.js b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/buffer-usage.js index 6076fff..7499491 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/buffer-usage.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/buffer-usage.js
@@ -7,12 +7,6 @@ `Tests that buffer usage update are sent when recording trace events and TimelineLifecycleDelegate methods are properly invoked in the expected order.\n`); await TestRunner.loadModule('performance_test_runner'); await TestRunner.showPanel('timeline'); - await TestRunner.loadHTML(` - <p> - Tests that buffer usage update are sent when recording trace events and - TimelineLifecycleDelegate methods are properly invoked in the expected order. - </p> - `); TestTimelineControllerClient = function() { this._hadLoadingProgress = false;
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-xhr-response-type-blob-event.js b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-xhr-response-type-blob-event.js index 928198f..d3b43dba 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-xhr-response-type-blob-event.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing/timeline-xhr-response-type-blob-event.js
@@ -7,11 +7,6 @@ await TestRunner.loadModule('performance_test_runner'); await TestRunner.loadModule('network_test_runner'); await TestRunner.showPanel('timeline'); - await TestRunner.loadHTML(` - <p> - Tests the Timeline events for XMLHttpReqeust with responseType="blob" - </p> - `); await TestRunner.evaluateInPagePromise(` function performActions() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/uri/escaped-entity-expected.txt b/third_party/WebKit/LayoutTests/http/tests/uri/escaped-entity-expected.txt index 251d339..6ac700b 100644 --- a/third_party/WebKit/LayoutTests/http/tests/uri/escaped-entity-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/uri/escaped-entity-expected.txt
@@ -2,9 +2,9 @@ Note that this exact page won't work in IE or Firefox. Firefox seems to always use UTF-8 for local files, and IE actually preserves the Unicode in the URL when we get it from JS, so we don't know what would get sent over the wire. However, both browsers will send %26%231758%3B over HTTP for the query. -"/uri/intercept/print/script.js?%26%231758%3B" (no target charset specified, should be Big5) -"/uri/intercept/print/script.js?%26%231758%3B" (Big5 specified) +"/uri/intercept/print/script.js?&%231758;" (no target charset specified, should be Big5) +"/uri/intercept/print/script.js?&%231758;" (Big5 specified) Show the source attribute of the scripts. -"http://127.0.0.1:8000/uri/intercept/print/script.js?%26%231758%3B" -"http://127.0.0.1:8000/uri/intercept/print/script.js?%26%231758%3B" +"http://127.0.0.1:8000/uri/intercept/print/script.js?&%231758;" +"http://127.0.0.1:8000/uri/intercept/print/script.js?&%231758;"
diff --git a/third_party/WebKit/LayoutTests/media/controls/modern/scrubbing-touch.html b/third_party/WebKit/LayoutTests/media/controls/modern/scrubbing-touch.html new file mode 100644 index 0000000..561c7cd69 --- /dev/null +++ b/third_party/WebKit/LayoutTests/media/controls/modern/scrubbing-touch.html
@@ -0,0 +1,58 @@ +<!DOCTYPE html> +<html> +<title>Test that player will behave correctly when scrubbing with touch events.</title> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../../media-controls.js"></script> +<video controls width=400 src="../../content/60_sec_video.webm"></video> +<script> +async_test(t => { + const video = document.querySelector('video'); + const timeline = timelineElement(video); + const timeElement = timelineThumbCurrentTime(video); + const thumb = timelineThumb(video); + + video.addEventListener('playing', t.step_func(() => { + // Get the coordinates of the thumb and the timeline. + const thumbCoordinates = elementCoordinates(thumb); + const timelineCoordinates = elementCoordinates(timeline); + + // Simulate a touch start event and then move the touch to the middle of + // the timeline to simulate a scrub. + if (window.eventSender) { + eventSender.addTouchPoint(thumbCoordinates[0], thumbCoordinates[1]); + eventSender.touchStart(); + + eventSender.updateTouchPoint( + 0, timelineCoordinates[0], timelineCoordinates[1]); + eventSender.touchMove(); + } + + // Check the scrubbing UI is shown with the correct time. + checkControlsClassName(video, 'phase-ready state-scrubbing'); + assert_equals('', timeElement.style.display); + assert_equals('0:' + Math.round(video.currentTime), + timeElement.textContent); + + // Ensure that the timeline now has a value in the middle. + assert_equals(30, Math.round(timeline.value)); + + // Add an event listener for when we start playing again after seeking. + video.addEventListener('playing', t.step_func_done(() => { + checkControlsClassName(video, 'phase-ready state-playing'); + + // Check the scrubbing UI is no longer shown. + assert_equals('none', timeElement.style.display); + }), { once: true }); + + // Release the touch. + if (window.eventSender) { + eventSender.releaseTouchPoint(0); + eventSender.touchEnd(); + } + }), { once: true }); + + video.play(); +}); +</script> +</html>
diff --git a/third_party/WebKit/LayoutTests/media/controls/modern/scrubbing.html b/third_party/WebKit/LayoutTests/media/controls/modern/scrubbing.html new file mode 100644 index 0000000..9f2f21c1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/media/controls/modern/scrubbing.html
@@ -0,0 +1,62 @@ +<!DOCTYPE html> +<html> +<title>Test that player will behave correctly when scrubbing.</title> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../../media-controls.js"></script> +<video controls width=400 src="../../content/60_sec_video.webm"></video> +<script> +async_test(t => { + const video = document.querySelector('video'); + const timeline = timelineElement(video); + const timeElement = timelineThumbCurrentTime(video); + const thumb = timelineThumb(video); + + let seeked = false; + + video.addEventListener('playing', t.step_func(() => { + // Get the coordinates of the thumb and the timeline. + const c = elementCoordinates(thumb); + const c2 = elementCoordinates(timeline); + + // Add an event listener for when we start playing again after seeking. + video.addEventListener('playing', t.step_func_done(() => { + assert_true(seeked); + checkControlsClassName(video, 'phase-ready state-playing'); + + // Check the scrubbing UI is no longer shown. + assert_equals('none', timeElement.style.display); + }), { once: true }); + + // Simulate a mouse down on those coordinates. + chrome.gpuBenchmarking.pointerActionSequence([ + { + source: 'mouse', + actions: [ + { name: 'pointerMove', x: c[0], y: c[1] }, + { name: 'pointerDown', x: c[0], y: c[1], button: 'left' }, + { name: 'pointerMove', x: c2[0], y: c2[1]}, + { name: 'pause', duration: 5 }, + { name: 'pointerUp', button: 'left' } + ] + } + ]); + }), { once: true }); + + video.addEventListener('seeking', t.step_func(() => { + checkControlsClassName(video, 'phase-ready state-scrubbing'); + + // Check the scrubbing UI is shown with the correct time. + assert_equals('', timeElement.style.display); + assert_equals('0:' + Math.round(video.currentTime), + timeElement.textContent); + }), { once: true }); + + video.addEventListener('seeked', t.step_func(() => { + seeked = true; + }), { once: true }); + + video.play(); +}); +</script> +</html>
diff --git a/third_party/WebKit/LayoutTests/media/media-controls.js b/third_party/WebKit/LayoutTests/media/media-controls.js index ed9b82d..78ce500 100644 --- a/third_party/WebKit/LayoutTests/media/media-controls.js +++ b/third_party/WebKit/LayoutTests/media/media-controls.js
@@ -193,6 +193,26 @@ return mediaControlsButton(videoElement, 'mute-button'); } +function timelineElement(videoElement) { + return mediaControlsButton(videoElement, 'timeline'); +} + +function timelineThumb(videoElement) { + const timeline = timelineElement(videoElement); + const thumb = window.internals.shadowRoot(timeline).getElementById('thumb'); + if (!thumb) + throw 'Failed to find timeline thumb'; + return thumb; +} + +function timelineThumbCurrentTime(videoElement) { + const timeline = timelineElement(videoElement); + const thumb = window.internals.shadowRoot(timeline).getElementById('thumb-current-time'); + if (!thumb) + throw 'Failed to find timeline current time'; + return thumb; +} + function clickAtCoordinates(x, y) { eventSender.mouseMoveTo(x, y);
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/text-overflow-input-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/text-overflow-input-expected.txt index 97265a3..2d07017 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/text-overflow-input-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/text-overflow-input-expected.txt
@@ -132,23 +132,23 @@ LayoutBlockFlow {DIV} at (3,3) size 125x13 LayoutText {#text} at (0,0) size 345x13 text run at (0,0) width 345: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" -layer at (11,90) size 125x13 scrollX 148.00 scrollWidth 274 +layer at (11,90) size 125x13 scrollX 149.00 scrollWidth 274 LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] LayoutText {#text} at (-148,0) size 274x13 text run at (-148,0) width 273: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (11,90) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (159,90) size 113x13 scrollX 160.00 scrollWidth 274 +layer at (159,90) size 113x13 scrollX 161.00 scrollWidth 274 LayoutBlockFlow {DIV} at (16,3) size 113x13 [color=#757575] LayoutText {#text} at (-160,0) size 274x13 text run at (-160,0) width 273: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (159,90) size 113x13 LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (283,90) size 125x13 scrollX 148.00 scrollWidth 274 +layer at (283,90) size 125x13 scrollX 149.00 scrollWidth 274 LayoutBlockFlow {DIV} at (3,3) size 125x13 LayoutText {#text} at (-148,0) size 274x13 text run at (-148,0) width 273: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (431,90) size 113x13 scrollX 160.00 scrollWidth 274 +layer at (431,90) size 113x13 scrollX 161.00 scrollWidth 274 LayoutBlockFlow {DIV} at (0,0) size 113x13 LayoutText {#text} at (-160,0) size 274x13 text run at (-160,0) width 273: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" @@ -180,23 +180,23 @@ LayoutBlockFlow {DIV} at (3,3) size 125x13 LayoutText {#text} at (0,0) size 345x13 text run at (0,0) width 345: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" -layer at (11,162) size 125x13 scrollX 148.00 scrollWidth 274 +layer at (11,162) size 125x13 scrollX 149.00 scrollWidth 274 LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] LayoutText {#text} at (-148,0) size 274x13 text run at (-148,0) width 273: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (11,162) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (159,162) size 113x13 scrollX 160.00 scrollWidth 274 +layer at (159,162) size 113x13 scrollX 161.00 scrollWidth 274 LayoutBlockFlow {DIV} at (16,3) size 113x13 [color=#757575] LayoutText {#text} at (-160,0) size 274x13 text run at (-160,0) width 273: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (159,162) size 113x13 LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (283,162) size 125x13 scrollX 148.00 scrollWidth 274 +layer at (283,162) size 125x13 scrollX 149.00 scrollWidth 274 LayoutBlockFlow {DIV} at (3,3) size 125x13 LayoutText {#text} at (-148,0) size 274x13 text run at (-148,0) width 273: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (431,162) size 113x13 scrollX 160.00 scrollWidth 274 +layer at (431,162) size 113x13 scrollX 161.00 scrollWidth 274 LayoutBlockFlow {DIV} at (0,0) size 113x13 LayoutText {#text} at (-160,0) size 274x13 text run at (-160,0) width 273: "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/css/text-overflow-input-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/css/text-overflow-input-expected.txt index 9b1d7c310..d98fb59e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/css/text-overflow-input-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/css/text-overflow-input-expected.txt
@@ -132,27 +132,27 @@ LayoutBlockFlow {DIV} at (3,3) size 125x13 LayoutText {#text} at (0,0) size 305x13 text run at (0,0) width 305: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" -layer at (11,90) size 125x13 scrollX 158.00 scrollWidth 284 +layer at (11,90) size 125x13 scrollX 159.00 scrollWidth 284 LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] LayoutText {#text} at (-158,0) size 284x13 text run at (-158,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (11,90) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (159,90) size 113x13 scrollX 170.00 scrollWidth 284 +layer at (159,90) size 113x13 scrollX 171.00 scrollWidth 284 LayoutBlockFlow {DIV} at (16,3) size 113x13 [color=#757575] LayoutText {#text} at (-170,0) size 284x13 text run at (-170,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (159,90) size 113x13 LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (283,90) size 125x13 scrollX 158.00 scrollWidth 284 +layer at (283,90) size 125x13 scrollX 159.00 scrollWidth 284 LayoutBlockFlow {DIV} at (3,3) size 125x13 LayoutText {#text} at (-158,0) size 284x13 text run at (-158,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (431,90) size 113x13 scrollX 170.00 scrollWidth 284 +layer at (431,90) size 113x13 scrollX 171.00 scrollWidth 284 LayoutBlockFlow {DIV} at (0,0) size 113x13 LayoutText {#text} at (-170,0) size 284x13 text run at (-170,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (555,90) size 125x13 scrollX 179.00 scrollWidth 305 +layer at (555,90) size 125x13 scrollX 180.00 scrollWidth 305 LayoutBlockFlow {DIV} at (3,3) size 125x13 LayoutText {#text} at (-179,0) size 305x13 text run at (-179,0) width 304 RTL: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" @@ -180,27 +180,27 @@ LayoutBlockFlow {DIV} at (3,3) size 125x13 LayoutText {#text} at (0,0) size 305x13 text run at (0,0) width 305: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" -layer at (11,162) size 125x13 scrollX 158.00 scrollWidth 284 +layer at (11,162) size 125x13 scrollX 159.00 scrollWidth 284 LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] LayoutText {#text} at (-158,0) size 284x13 text run at (-158,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (11,162) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (159,162) size 113x13 scrollX 170.00 scrollWidth 284 +layer at (159,162) size 113x13 scrollX 171.00 scrollWidth 284 LayoutBlockFlow {DIV} at (16,3) size 113x13 [color=#757575] LayoutText {#text} at (-170,0) size 284x13 text run at (-170,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (159,162) size 113x13 LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (283,162) size 125x13 scrollX 158.00 scrollWidth 284 +layer at (283,162) size 125x13 scrollX 159.00 scrollWidth 284 LayoutBlockFlow {DIV} at (3,3) size 125x13 LayoutText {#text} at (-158,0) size 284x13 text run at (-158,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (431,162) size 113x13 scrollX 170.00 scrollWidth 284 +layer at (431,162) size 113x13 scrollX 171.00 scrollWidth 284 LayoutBlockFlow {DIV} at (0,0) size 113x13 LayoutText {#text} at (-170,0) size 284x13 text run at (-170,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (555,162) size 125x13 scrollX 179.00 scrollWidth 305 +layer at (555,162) size 125x13 scrollX 180.00 scrollWidth 305 LayoutBlockFlow {DIV} at (3,3) size 125x13 LayoutText {#text} at (-179,0) size 305x13 text run at (-179,0) width 304 RTL: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/css/text-overflow-input-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/css/text-overflow-input-expected.png deleted file mode 100644 index d326f92..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/css/text-overflow-input-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/css/text-overflow-input-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/css/text-overflow-input-expected.txt deleted file mode 100644 index 9b1d7c310..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/css/text-overflow-input-expected.txt +++ /dev/null
@@ -1,242 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x266 - LayoutBlockFlow {HTML} at (0,0) size 800x266 - LayoutBlockFlow {BODY} at (8,16) size 784x234 - LayoutBlockFlow {P} at (0,0) size 784x18 - LayoutText {#text} at (0,0) size 314x18 - text run at (0,0) width 314: "This test is a basic check for using text-overflow." - LayoutBlockFlow {P} at (0,34) size 784x56 - LayoutText {#text} at (0,0) size 489x18 - text run at (0,0) width 489: "Apply \"text-overflow:clip\" to inputs. The following input should be clipped:" - LayoutBR {BR} at (488,0) size 1x18 - LayoutTextControl {INPUT} at (0,18) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (131,18) size 4x18 - text run at (131,18) width 4: " " - LayoutTextControl {INPUT} at (135,18) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (268,18) size 4x18 - text run at (268,18) width 4: " " - LayoutTextControl {INPUT} at (272,18) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (403,18) size 4x18 - text run at (403,18) width 4: " " - LayoutTextControl {INPUT} at (407,18) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (540,18) size 4x18 - text run at (540,18) width 4: " " - LayoutTextControl {INPUT} at (544,18) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutBR {BR} at (675,18) size 0x18 - LayoutTextControl {INPUT} at (0,37) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (131,37) size 4x18 - text run at (131,37) width 4: " " - LayoutTextControl {INPUT} at (135,37) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (12,0) size 113x13 - LayoutText {#text} at (268,37) size 4x18 - text run at (268,37) width 4: " " - LayoutTextControl {INPUT} at (272,37) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (403,37) size 4x18 - text run at (403,37) width 4: " " - LayoutTextControl {INPUT} at (407,37) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (12,0) size 113x13 - LayoutText {#text} at (540,37) size 4x18 - text run at (540,37) width 4: " " - LayoutTextControl {INPUT} at (544,37) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (0,0) size 0x0 - LayoutBlockFlow {P} at (0,106) size 784x56 - LayoutText {#text} at (0,0) size 546x18 - text run at (0,0) width 546: "Apply \"text-overflow:ellipsis\" to inputs. The following input should show an ellipsis:" - LayoutBR {BR} at (545,0) size 1x18 - LayoutTextControl {INPUT} at (0,18) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (131,18) size 4x18 - text run at (131,18) width 4: " " - LayoutTextControl {INPUT} at (135,18) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (268,18) size 4x18 - text run at (268,18) width 4: " " - LayoutTextControl {INPUT} at (272,18) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (403,18) size 4x18 - text run at (403,18) width 4: " " - LayoutTextControl {INPUT} at (407,18) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (540,18) size 4x18 - text run at (540,18) width 4: " " - LayoutTextControl {INPUT} at (544,18) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutBR {BR} at (675,18) size 0x18 - LayoutTextControl {INPUT} at (0,37) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (131,37) size 4x18 - text run at (131,37) width 4: " " - LayoutTextControl {INPUT} at (135,37) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (12,0) size 113x13 - LayoutText {#text} at (268,37) size 4x18 - text run at (268,37) width 4: " " - LayoutTextControl {INPUT} at (272,37) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (403,37) size 4x18 - text run at (403,37) width 4: " " - LayoutTextControl {INPUT} at (407,37) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutFlexibleBox {DIV} at (4,3) size 125x13 - LayoutBlockFlow {DIV} at (12,0) size 113x13 - LayoutText {#text} at (540,37) size 4x18 - text run at (540,37) width 4: " " - LayoutTextControl {INPUT} at (544,37) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (0,0) size 0x0 - LayoutBlockFlow {P} at (0,178) size 784x56 - LayoutText {#text} at (0,0) size 237x18 - text run at (0,0) width 237: "Dynamic style change text-overflow:" - LayoutBR {BR} at (236,0) size 1x18 - LayoutText {#text} at (0,18) size 247x18 - text run at (0,18) width 247: "Clip to ellipsis (should show ellipsis): " - LayoutTextControl {INPUT} at (246.23,18) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (377,18) size 5x18 - text run at (377,18) width 5: " " - LayoutTextControl {INPUT} at (381.23,18) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (512,18) size 5x18 - text run at (512,18) width 5: " " - LayoutBR {BR} at (0,0) size 0x0 - LayoutText {#text} at (0,37) size 270x18 - text run at (0,37) width 270: "Ellipsis to clip (should not show ellipsis): " - LayoutTextControl {INPUT} at (269.78,37) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (400,37) size 5x18 - text run at (400,37) width 5: " " - LayoutTextControl {INPUT} at (404.78,37) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] - LayoutText {#text} at (535,37) size 5x18 - text run at (535,37) width 5: " " - LayoutBR {BR} at (0,0) size 0x0 -layer at (11,71) size 125x13 scrollWidth 284 - LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (11,71) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (147,71) size 113x13 scrollWidth 284 - LayoutBlockFlow {DIV} at (4,3) size 113x13 [color=#757575] - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (147,71) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (283,71) size 125x13 scrollWidth 285 - LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (419,71) size 113x13 scrollWidth 285 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (555,71) size 125x13 scrollWidth 306 - LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (0,0) size 305x13 - text run at (0,0) width 305: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" -layer at (11,90) size 125x13 scrollX 158.00 scrollWidth 284 - LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (-158,0) size 284x13 - text run at (-158,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (11,90) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (159,90) size 113x13 scrollX 170.00 scrollWidth 284 - LayoutBlockFlow {DIV} at (16,3) size 113x13 [color=#757575] - LayoutText {#text} at (-170,0) size 284x13 - text run at (-170,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (159,90) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (283,90) size 125x13 scrollX 158.00 scrollWidth 284 - LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (-158,0) size 284x13 - text run at (-158,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (431,90) size 113x13 scrollX 170.00 scrollWidth 284 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (-170,0) size 284x13 - text run at (-170,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (555,90) size 125x13 scrollX 179.00 scrollWidth 305 - LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (-179,0) size 305x13 - text run at (-179,0) width 304 RTL: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" -layer at (11,143) size 125x13 scrollWidth 284 - LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (11,143) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (147,143) size 113x13 scrollWidth 284 - LayoutBlockFlow {DIV} at (4,3) size 113x13 [color=#757575] - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (147,143) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (283,143) size 125x13 scrollWidth 285 - LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (419,143) size 113x13 scrollWidth 285 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (555,143) size 125x13 scrollWidth 306 - LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (0,0) size 305x13 - text run at (0,0) width 305: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" -layer at (11,162) size 125x13 scrollX 158.00 scrollWidth 284 - LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (-158,0) size 284x13 - text run at (-158,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (11,162) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (159,162) size 113x13 scrollX 170.00 scrollWidth 284 - LayoutBlockFlow {DIV} at (16,3) size 113x13 [color=#757575] - LayoutText {#text} at (-170,0) size 284x13 - text run at (-170,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (159,162) size 113x13 - LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (283,162) size 125x13 scrollX 158.00 scrollWidth 284 - LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (-158,0) size 284x13 - text run at (-158,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (431,162) size 113x13 scrollX 170.00 scrollWidth 284 - LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (-170,0) size 284x13 - text run at (-170,0) width 283: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (555,162) size 125x13 scrollX 179.00 scrollWidth 305 - LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (-179,0) size 305x13 - text run at (-179,0) width 304 RTL: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" -layer at (257,215) size 125x13 scrollWidth 284 - LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (257,215) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (392,215) size 125x13 scrollWidth 285 - LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (281,234) size 125x13 scrollWidth 284 - LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (281,234) size 125x13 - LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (416,234) size 125x13 scrollWidth 285 - LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (261,72) size 11x11 transparent - LayoutBlockFlow {DIV} at (114,1) size 11x11 -layer at (533,72) size 11x11 transparent - LayoutBlockFlow {DIV} at (114,1) size 11x11 -layer at (147,91) size 11x11 transparent - LayoutBlockFlow {DIV} at (0,1) size 11x11 -layer at (419,91) size 11x11 transparent - LayoutBlockFlow {DIV} at (0,1) size 11x11 -layer at (261,144) size 11x11 transparent - LayoutBlockFlow {DIV} at (114,1) size 11x11 -layer at (533,144) size 11x11 transparent - LayoutBlockFlow {DIV} at (114,1) size 11x11 -layer at (147,163) size 11x11 transparent - LayoutBlockFlow {DIV} at (0,1) size 11x11 -layer at (419,163) size 11x11 transparent - LayoutBlockFlow {DIV} at (0,1) size 11x11
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/text-overflow-input-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/text-overflow-input-expected.png index 7531288..e9840f2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/text-overflow-input-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/text-overflow-input-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/text-overflow-input-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/css/text-overflow-input-expected.txt index cecd5576..18a10db0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/text-overflow-input-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/text-overflow-input-expected.txt
@@ -108,122 +108,122 @@ LayoutText {#text} at (535,37) size 5x18 text run at (535,37) width 5: " " LayoutBR {BR} at (0,0) size 0x0 -layer at (11,71) size 125x13 scrollWidth 285 +layer at (11,71) size 125x13 scrollWidth 288 LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" + LayoutText {#text} at (0,0) size 288x13 + text run at (0,0) width 288: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (11,71) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (147,71) size 113x13 scrollWidth 285 +layer at (147,71) size 113x13 scrollWidth 288 LayoutBlockFlow {DIV} at (4,3) size 113x13 [color=#757575] - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" + LayoutText {#text} at (0,0) size 288x13 + text run at (0,0) width 288: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (147,71) size 113x13 LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (283,71) size 125x13 scrollWidth 286 +layer at (283,71) size 125x13 scrollWidth 289 LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (419,71) size 113x13 scrollWidth 286 + LayoutText {#text} at (0,0) size 288x13 + text run at (0,0) width 288: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" +layer at (419,71) size 113x13 scrollWidth 289 LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (555,71) size 125x13 scrollWidth 306 + LayoutText {#text} at (0,0) size 288x13 + text run at (0,0) width 288: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" +layer at (555,71) size 125x13 scrollWidth 309 LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (0,0) size 305x13 - text run at (0,0) width 305: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" -layer at (11,90) size 125x13 scrollX 159.00 scrollWidth 285 + LayoutText {#text} at (0,0) size 309x13 + text run at (0,0) width 309: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" +layer at (11,90) size 125x13 scrollX 162.00 scrollWidth 287 LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (-159,0) size 285x13 - text run at (-159,0) width 284: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" + LayoutText {#text} at (-162,0) size 288x13 + text run at (-162,0) width 287: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (11,90) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (159,90) size 113x13 scrollX 171.00 scrollWidth 285 +layer at (159,90) size 113x13 scrollX 174.00 scrollWidth 287 LayoutBlockFlow {DIV} at (16,3) size 113x13 [color=#757575] - LayoutText {#text} at (-171,0) size 285x13 - text run at (-171,0) width 284: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" + LayoutText {#text} at (-174,0) size 288x13 + text run at (-174,0) width 287: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (159,90) size 113x13 LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (283,90) size 125x13 scrollX 159.00 scrollWidth 285 +layer at (283,90) size 125x13 scrollX 162.00 scrollWidth 287 LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (-159,0) size 285x13 - text run at (-159,0) width 284: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (431,90) size 113x13 scrollX 171.00 scrollWidth 285 + LayoutText {#text} at (-162,0) size 288x13 + text run at (-162,0) width 287: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" +layer at (431,90) size 113x13 scrollX 174.00 scrollWidth 287 LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (-171,0) size 285x13 - text run at (-171,0) width 284: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (555,90) size 125x13 scrollX 179.00 scrollWidth 305 + LayoutText {#text} at (-174,0) size 288x13 + text run at (-174,0) width 287: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" +layer at (555,90) size 125x13 scrollX 183.00 scrollWidth 308 LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (-179,0) size 305x13 - text run at (-179,0) width 304 RTL: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" -layer at (11,143) size 125x13 scrollWidth 285 + LayoutText {#text} at (-183,0) size 309x13 + text run at (-183,0) width 308 RTL: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" +layer at (11,143) size 125x13 scrollWidth 288 LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" + LayoutText {#text} at (0,0) size 288x13 + text run at (0,0) width 288: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (11,143) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (147,143) size 113x13 scrollWidth 285 +layer at (147,143) size 113x13 scrollWidth 288 LayoutBlockFlow {DIV} at (4,3) size 113x13 [color=#757575] - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" + LayoutText {#text} at (0,0) size 288x13 + text run at (0,0) width 288: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (147,143) size 113x13 LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (283,143) size 125x13 scrollWidth 286 +layer at (283,143) size 125x13 scrollWidth 289 LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (419,143) size 113x13 scrollWidth 286 + LayoutText {#text} at (0,0) size 288x13 + text run at (0,0) width 288: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" +layer at (419,143) size 113x13 scrollWidth 289 LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (555,143) size 125x13 scrollWidth 306 + LayoutText {#text} at (0,0) size 288x13 + text run at (0,0) width 288: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" +layer at (555,143) size 125x13 scrollWidth 309 LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (0,0) size 305x13 - text run at (0,0) width 305: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" -layer at (11,162) size 125x13 scrollX 159.00 scrollWidth 285 + LayoutText {#text} at (0,0) size 309x13 + text run at (0,0) width 309: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" +layer at (11,162) size 125x13 scrollX 162.00 scrollWidth 287 LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (-159,0) size 285x13 - text run at (-159,0) width 284: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" + LayoutText {#text} at (-162,0) size 288x13 + text run at (-162,0) width 287: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (11,162) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (159,162) size 113x13 scrollX 171.00 scrollWidth 285 +layer at (159,162) size 113x13 scrollX 174.00 scrollWidth 287 LayoutBlockFlow {DIV} at (16,3) size 113x13 [color=#757575] - LayoutText {#text} at (-171,0) size 285x13 - text run at (-171,0) width 284: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" + LayoutText {#text} at (-174,0) size 288x13 + text run at (-174,0) width 287: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (159,162) size 113x13 LayoutBlockFlow {DIV} at (0,0) size 113x13 -layer at (283,162) size 125x13 scrollX 159.00 scrollWidth 285 +layer at (283,162) size 125x13 scrollX 162.00 scrollWidth 287 LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (-159,0) size 285x13 - text run at (-159,0) width 284: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (431,162) size 113x13 scrollX 171.00 scrollWidth 285 + LayoutText {#text} at (-162,0) size 288x13 + text run at (-162,0) width 287: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" +layer at (431,162) size 113x13 scrollX 174.00 scrollWidth 287 LayoutBlockFlow {DIV} at (0,0) size 113x13 - LayoutText {#text} at (-171,0) size 285x13 - text run at (-171,0) width 284: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (555,162) size 125x13 scrollX 179.00 scrollWidth 305 + LayoutText {#text} at (-174,0) size 288x13 + text run at (-174,0) width 287: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" +layer at (555,162) size 125x13 scrollX 183.00 scrollWidth 308 LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (-179,0) size 305x13 - text run at (-179,0) width 304 RTL: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" -layer at (257,215) size 125x13 scrollWidth 285 + LayoutText {#text} at (-183,0) size 309x13 + text run at (-183,0) width 308 RTL: "\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}\x{2022}" +layer at (257,215) size 125x13 scrollWidth 288 LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" + LayoutText {#text} at (0,0) size 288x13 + text run at (0,0) width 288: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (257,215) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (392,215) size 125x13 scrollWidth 286 +layer at (392,215) size 125x13 scrollWidth 289 LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" -layer at (281,234) size 125x13 scrollWidth 285 + LayoutText {#text} at (0,0) size 288x13 + text run at (0,0) width 288: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" +layer at (281,234) size 125x13 scrollWidth 288 LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575] - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" + LayoutText {#text} at (0,0) size 288x13 + text run at (0,0) width 288: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (281,234) size 125x13 LayoutBlockFlow {DIV} at (3,3) size 125x13 -layer at (416,234) size 125x13 scrollWidth 286 +layer at (416,234) size 125x13 scrollWidth 289 LayoutBlockFlow {DIV} at (3,3) size 125x13 - LayoutText {#text} at (0,0) size 285x13 - text run at (0,0) width 285: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" + LayoutText {#text} at (0,0) size 288x13 + text run at (0,0) width 288: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" layer at (261,72) size 11x11 transparent LayoutBlockFlow {DIV} at (114,1) size 11x11 layer at (533,72) size 11x11 transparent
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 089a6e4e..5e8931fa 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
@@ -1107,7 +1107,6 @@ method write method writeln setter alinkColor - setter all setter bgColor setter body setter cookie
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 9c5cd1d..987825b1 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -1649,7 +1649,6 @@ method write method writeln setter alinkColor - setter all setter bgColor setter body setter cookie
diff --git a/third_party/WebKit/Source/core/dom/Document.idl b/third_party/WebKit/Source/core/dom/Document.idl index 5f5bb0a..3582c72 100644 --- a/third_party/WebKit/Source/core/dom/Document.idl +++ b/third_party/WebKit/Source/core/dom/Document.idl
@@ -158,8 +158,8 @@ [MeasureAs=DocumentCaptureEvents] void captureEvents(); [MeasureAs=DocumentReleaseEvents] void releaseEvents(); - // FIXME: all should not be [Replaceable]. - [Replaceable, MeasureAs=DocumentAll] readonly attribute HTMLAllCollection all; + // TODO: |all| should be [SameObject]. + [MeasureAs=DocumentAll] readonly attribute HTMLAllCollection all; // CSS Object Model (CSSOM) // https://drafts.csswg.org/cssom/#extensions-to-the-document-interface
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp index 84101d43..1d39bed 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -827,8 +827,12 @@ scoped_refptr<StaticBitmapImage> image_bitmap = ToStaticBitmapImage( source_buffer, kPreferNoAcceleration, kSnapshotReasonToBlob); - if (image_bitmap) - return ImageDataBuffer(image_bitmap).ToDataURL(encoding_mime_type, quality); + if (image_bitmap) { + std::unique_ptr<ImageDataBuffer> data_buffer = + ImageDataBuffer::Create(image_bitmap); + if (data_buffer) + return data_buffer->ToDataURL(encoding_mime_type, quality); + } return String("data:,"); }
diff --git a/third_party/WebKit/Source/core/html/forms/TextControlElement.cpp b/third_party/WebKit/Source/core/html/forms/TextControlElement.cpp index b7997e3..9633777 100644 --- a/third_party/WebKit/Source/core/html/forms/TextControlElement.cpp +++ b/third_party/WebKit/Source/core/html/forms/TextControlElement.cpp
@@ -977,16 +977,15 @@ void TextControlElement::SetSuggestedValue(const String& value) { suggested_value_ = value; if (!suggested_value_.IsEmpty() && !InnerEditorValue().IsEmpty()) { - // Save the value that is in the editor and set the editor value to an empty - // string. This will allow the suggestion placeholder to be shown to the - // user. - value_before_set_suggested_value_ = InnerEditorValue(); - SetInnerEditorValue(""); - } else if (suggested_value_.IsEmpty() && - !value_before_set_suggested_value_.IsEmpty()) { - // Reset the value that was in the editor before showing the suggestion. - SetInnerEditorValue(value_before_set_suggested_value_); - value_before_set_suggested_value_ = ""; + // If there is an inner editor value, hide it so the suggested value can be + // shown to the user. + static_cast<TextControlInnerEditorElement*>(InnerEditorElement()) + ->SetVisibility(false); + } else if (suggested_value_.IsEmpty() && InnerEditorElement()) { + // If there is no suggested value and there is an InnerEditorElement, reset + // its visibility. + static_cast<TextControlInnerEditorElement*>(InnerEditorElement()) + ->SetVisibility(true); } UpdatePlaceholderText();
diff --git a/third_party/WebKit/Source/core/html/forms/TextControlInnerElements.cpp b/third_party/WebKit/Source/core/html/forms/TextControlInnerElements.cpp index 3634e64..c1d1da1 100644 --- a/third_party/WebKit/Source/core/html/forms/TextControlInnerElements.cpp +++ b/third_party/WebKit/Source/core/html/forms/TextControlInnerElements.cpp
@@ -26,6 +26,7 @@ #include "core/html/forms/TextControlInnerElements.h" +#include "core/css/StyleChangeReason.h" #include "core/css/resolver/StyleAdjuster.h" #include "core/dom/Document.h" #include "core/dom/NodeComputedStyle.h" @@ -126,6 +127,15 @@ HTMLDivElement::DefaultEventHandler(event); } +void TextControlInnerEditorElement::SetVisibility(bool is_visible) { + if (is_visible_ != is_visible) { + is_visible_ = is_visible; + SetNeedsStyleRecalc( + kLocalStyleChange, + StyleChangeReasonForTracing::Create(StyleChangeReason::kControlValue)); + } +} + LayoutObject* TextControlInnerEditorElement::CreateLayoutObject( const ComputedStyle&) { return new LayoutTextControlInnerEditor(this); @@ -144,6 +154,8 @@ // Using StyleAdjuster::adjustComputedStyle updates unwanted style. We'd like // to apply only editing-related and alignment-related. StyleAdjuster::AdjustStyleForEditing(*inner_editor_style); + if (!is_visible_) + inner_editor_style->SetOpacity(0); return inner_editor_style; }
diff --git a/third_party/WebKit/Source/core/html/forms/TextControlInnerElements.h b/third_party/WebKit/Source/core/html/forms/TextControlInnerElements.h index 072f535..f5d15691 100644 --- a/third_party/WebKit/Source/core/html/forms/TextControlInnerElements.h +++ b/third_party/WebKit/Source/core/html/forms/TextControlInnerElements.h
@@ -59,11 +59,14 @@ void DefaultEventHandler(Event*) override; + void SetVisibility(bool is_visible); + private: explicit TextControlInnerEditorElement(Document&); LayoutObject* CreateLayoutObject(const ComputedStyle&) override; scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override; bool SupportsFocus() const override { return false; } + bool is_visible_ = true; }; class SearchFieldCancelButtonElement final : public HTMLDivElement {
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp index e4cb3e9..5376553a 100644 --- a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp +++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
@@ -104,13 +104,14 @@ // LayoutTests/media/media-controls.js. const double kTimeWithoutMouseMovementBeforeHidingMediaControls = 3; -const char* kStateCSSClasses[6] = { +const char* kStateCSSClasses[7] = { "phase-pre-ready state-no-source", // kNoSource "phase-pre-ready state-no-metadata", // kNotLoaded "state-loading-metadata", // kLoadingMetadata "phase-ready state-stopped", // kStopped "phase-ready state-playing", // kPlaying "phase-ready state-buffering", // kBuffering + "phase-ready state-scrubbing", // kScrubbing }; // The padding in pixels inside the button panel. @@ -570,12 +571,14 @@ } void MediaControlsImpl::UpdateCSSClassFromState() { + const ControlsState state = State(); StringBuilder builder; - builder.Append(kStateCSSClasses[State()]); + builder.Append(kStateCSSClasses[state]); if (MediaElement().IsHTMLVideoElement() && !VideoElement().HasAvailableVideoFrame() && - VideoElement().PosterImageURL().IsEmpty()) { + VideoElement().PosterImageURL().IsEmpty() && + state != ControlsState::kScrubbing) { builder.Append(" "); builder.Append(kShowDefaultPosterCSSClass); } @@ -589,6 +592,9 @@ } MediaControlsImpl::ControlsState MediaControlsImpl::State() const { + if (is_scrubbing_) + return ControlsState::kScrubbing; + switch (MediaElement().getNetworkState()) { case HTMLMediaElement::kNetworkEmpty: case HTMLMediaElement::kNetworkNoSource: @@ -786,6 +792,9 @@ is_paused_for_scrubbing_ = true; MediaElement().pause(); } + + is_scrubbing_ = true; + UpdateCSSClassFromState(); } void MediaControlsImpl::EndScrubbing() { @@ -794,6 +803,9 @@ if (MediaElement().paused()) MediaElement().Play(); } + + is_scrubbing_ = false; + UpdateCSSClassFromState(); } void MediaControlsImpl::UpdateCurrentTimeDisplay() {
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h index 9b11473..a1d94b5 100644 --- a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h +++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h
@@ -154,6 +154,9 @@ // Playback has stopped to buffer. kBuffering, + + // The media is being scrubbed. + kScrubbing, }; ControlsState State() const; @@ -302,6 +305,7 @@ unsigned hide_timer_behavior_flags_; bool is_mouse_over_controls_ : 1; bool is_paused_for_scrubbing_ : 1; + bool is_scrubbing_ = false; // Watches the video element for resize and updates media controls as // necessary.
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlSliderElement.h b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlSliderElement.h index 2541ba5..26cded8 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlSliderElement.h +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlSliderElement.h
@@ -29,6 +29,10 @@ double width; }; + // Width in CSS pixels * pageZoomFactor (ignores CSS transforms for + // simplicity; deliberately ignores pinch zoom's pageScaleFactor). + int Width(); + protected: class MediaControlSliderElementResizeObserverDelegate; @@ -40,10 +44,6 @@ void NotifyElementSizeChanged(); - // Width in CSS pixels * pageZoomFactor (ignores CSS transforms for - // simplicity; deliberately ignores pinch zoom's pageScaleFactor). - int Width(); - Element& GetTrackElement(); private:
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp index 963731a..7a51ef00 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.cpp
@@ -4,21 +4,27 @@ #include "modules/media_controls/elements/MediaControlTimelineElement.h" +#include "core/css/CSSStyleDeclaration.h" #include "core/dom/ShadowRoot.h" #include "core/dom/events/Event.h" #include "core/events/KeyboardEvent.h" #include "core/events/PointerEvent.h" +#include "core/events/TouchEvent.h" #include "core/html/HTMLDivElement.h" #include "core/html/HTMLStyleElement.h" #include "core/html/TimeRanges.h" #include "core/html/media/HTMLMediaElement.h" #include "core/html/shadow/ShadowElementNames.h" #include "core/html_names.h" +#include "core/input/Touch.h" +#include "core/input/TouchList.h" #include "core/input_type_names.h" -#include "core/layout/LayoutBoxModelObject.h" +#include "core/layout/LayoutBox.h" #include "core/page/ChromeClient.h" +#include "core/style/ComputedStyle.h" #include "modules/media_controls/MediaControlsImpl.h" #include "modules/media_controls/MediaControlsResourceLoader.h" +#include "modules/media_controls/elements/MediaControlCurrentTimeDisplayElement.h" #include "modules/media_controls/elements/MediaControlElementsHelper.h" #include "platform/runtime_enabled_features.h" #include "public/platform/Platform.h" @@ -28,6 +34,15 @@ const double kCurrentTimeBufferedDelta = 1.0; +// Only respond to main button of primary pointer(s). +bool IsValidPointerEvent(const blink::Event& event) { + DCHECK(event.IsPointerEvent()); + const blink::PointerEvent& pointer_event = ToPointerEvent(event); + return pointer_event.isPrimary() && + pointer_event.button() == + static_cast<short>(blink::WebPointerProperties::Button::kLeft); +} + } // namespace. namespace blink { @@ -36,6 +51,10 @@ // // MediaControlTimelineElement // (-webkit-media-controls-timeline) +// +-div#thumb (created by the HTMLSliderElement) +// +-MediaControlCurrentTimeDisplayElement#thumb-current-time +// {if IsModern() and IsHTMLVideoElement()} +// // The child elements are only present if MediaControlsImpl::IsModern() is // enabled. These three <div>'s are used to show the buffering animation. // +-div (-internal-track-segment-buffering) @@ -44,7 +63,8 @@ // +-HTMLStyleElement MediaControlTimelineElement::MediaControlTimelineElement( MediaControlsImpl& media_controls) - : MediaControlSliderElement(media_controls, kMediaSlider) { + : MediaControlSliderElement(media_controls, kMediaSlider), + current_time_display_(nullptr) { SetShadowPseudoId(AtomicString("-webkit-media-controls-timeline")); if (MediaControlsImpl::IsModern()) { @@ -56,6 +76,22 @@ MediaControlElementsHelper::CreateDiv("-internal-track-segment-buffering", &track); + // Create the current time scrubbing element. + if (MediaElement().IsHTMLVideoElement()) { + Element* thumb = track.getElementById("thumb"); + DCHECK(thumb); + + // The time display should not have a pseudo ID and have a timeline + // specific element ID. This is to ensure it does not pick up styles from + // the current time display. + current_time_display_ = + new MediaControlCurrentTimeDisplayElement(GetMediaControls()); + current_time_display_->setAttribute("pseudo", ""); + current_time_display_->setAttribute("id", "thumb-current-time"); + current_time_display_->SetIsWanted(false); + thumb->AppendChild(current_time_display_); + } + // This stylesheet element contains rules that cannot be present in the UA // stylesheet (e.g. animations). HTMLStyleElement* style = HTMLStyleElement::Create(GetDocument(), false); @@ -99,26 +135,25 @@ RenderBarSegments(); - // Only respond to main button of primary pointer(s). - if (event->IsPointerEvent() && ToPointerEvent(event)->isPrimary() && - ToPointerEvent(event)->button() == - static_cast<short>(WebPointerProperties::Button::kLeft)) { - if (event->type() == EventTypeNames::pointerdown) { - Platform::Current()->RecordAction( - UserMetricsAction("Media.Controls.ScrubbingBegin")); - GetMediaControls().BeginScrubbing(); - Element* thumb = UserAgentShadowRoot()->getElementById( - ShadowElementNames::SliderThumb()); - bool started_from_thumb = thumb && thumb == event->target()->ToNode(); - metrics_.StartGesture(started_from_thumb); - } - if (event->type() == EventTypeNames::pointerup || - event->type() == EventTypeNames::pointercancel) { - Platform::Current()->RecordAction( - UserMetricsAction("Media.Controls.ScrubbingEnd")); - GetMediaControls().EndScrubbing(); - metrics_.RecordEndGesture(Width(), MediaElement().duration()); - } + if (BeginScrubbingEvent(*event)) { + Platform::Current()->RecordAction( + UserMetricsAction("Media.Controls.ScrubbingBegin")); + GetMediaControls().BeginScrubbing(); + Element* thumb = UserAgentShadowRoot()->getElementById( + ShadowElementNames::SliderThumb()); + bool started_from_thumb = thumb && thumb == event->target()->ToNode(); + metrics_.StartGesture(started_from_thumb); + + if (current_time_display_) + current_time_display_->SetIsWanted(true); + } else if (EndScrubbingEvent(*event)) { + Platform::Current()->RecordAction( + UserMetricsAction("Media.Controls.ScrubbingEnd")); + GetMediaControls().EndScrubbing(); + metrics_.RecordEndGesture(Width(), MediaElement().duration()); + + if (current_time_display_) + current_time_display_->SetIsWanted(false); } if (event->type() == EventTypeNames::keydown) { @@ -135,11 +170,36 @@ MaybeRecordInteracted(); } - if (event->type() != EventTypeNames::input) + // Update the value based on the touchmove event. + if (is_touching_ && event->type() == EventTypeNames::touchmove) { + TouchEvent* touch_event = ToTouchEvent(event); + if (touch_event->touches()->length() != 1) + return; + + const Touch* touch = touch_event->touches()->item(0); + double position = max(0.0, fmin(1.0, touch->clientX() / Width())); + SetPosition(position * MediaElement().duration()); + } else if (event->type() != EventTypeNames::input) { return; + } double time = value().ToDouble(); + // Update the scrubbing UI with the current time. + if (current_time_display_) { + current_time_display_->SetCurrentValue(time); + + // Set the margin left based on the new width of the text so we are + // correctly centered. + if (LayoutBox* box = current_time_display_->GetLayoutBox()) { + String margin_left = + WTF::String::Number(ceil(box->LogicalWidth().Round() / 2) * -1) + + "px"; + current_time_display_->style()->setProperty( + &GetDocument(), "margin-left", margin_left, "", ASSERT_NO_EXCEPTION); + } + } + double duration = MediaElement().duration(); // Workaround for floating point error - it's possible for this element's max // attribute to be rounded to a value slightly higher than the duration. If @@ -224,4 +284,35 @@ SetAfterSegmentPosition(MediaControlSliderElement::Position(0, 0)); } +void MediaControlTimelineElement::Trace(blink::Visitor* visitor) { + MediaControlSliderElement::Trace(visitor); + visitor->Trace(current_time_display_); +} + +bool MediaControlTimelineElement::BeginScrubbingEvent(Event& event) { + if (event.type() == EventTypeNames::touchstart) { + is_touching_ = true; + return true; + } + if (event.type() == EventTypeNames::pointerdown) + return IsValidPointerEvent(event); + + return false; +} + +bool MediaControlTimelineElement::EndScrubbingEvent(Event& event) { + if (is_touching_) { + if (event.type() == EventTypeNames::touchend || + event.type() == EventTypeNames::touchcancel || + event.type() == EventTypeNames::change) { + return true; + } + } else if (event.type() == EventTypeNames::pointerup || + event.type() == EventTypeNames::pointercancel) { + return IsValidPointerEvent(event); + } + + return false; +} + } // namespace blink
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.h b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.h index 2fd98180..9ced66d 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.h +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElement.h
@@ -12,9 +12,11 @@ namespace blink { class Event; +class HTMLDivElement; +class MediaControlCurrentTimeDisplayElement; class MediaControlsImpl; -class MediaControlTimelineElement final : public MediaControlSliderElement { +class MediaControlTimelineElement : public MediaControlSliderElement { public: MODULES_EXPORT explicit MediaControlTimelineElement(MediaControlsImpl&); @@ -32,6 +34,8 @@ void RenderBarSegments(); + virtual void Trace(blink::Visitor*); + protected: const char* GetNameForHistograms() const override; @@ -39,7 +43,18 @@ void DefaultEventHandler(Event*) override; bool KeepEventInNode(Event*) override; + // Checks if we can begin or end a scrubbing event. If the event is a pointer + // event then it needs to start and end with valid pointer events. If the + // event is a pointer event followed by a touch event then it can only be + // ended when the touch has ended. + bool BeginScrubbingEvent(Event&); + bool EndScrubbingEvent(Event&); + MediaControlTimelineMetrics metrics_; + + Member<MediaControlCurrentTimeDisplayElement> current_time_display_; + + bool is_touching_ = false; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElementTest.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElementTest.cpp index 2b2295c..e7a0351 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElementTest.cpp +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlTimelineElementTest.cpp
@@ -6,6 +6,8 @@ #include "core/events/PointerEvent.h" #include "core/events/PointerEventInit.h" +#include "core/events/TouchEvent.h" +#include "core/events/TouchEventInit.h" #include "core/html/media/HTMLVideoElement.h" #include "core/testing/PageTestBase.h" #include "modules/media_controls/MediaControlsImpl.h" @@ -22,12 +24,16 @@ return init; } + static TouchEventInit GetValidTouchEventInit() { return TouchEventInit(); } + void SetUp() override { - PageTestBase::SetUp(); + PageTestBase::SetUp(IntSize(100, 100)); video_ = HTMLVideoElement::Create(GetDocument()); - timeline_ = - new MediaControlTimelineElement(*(new MediaControlsImpl(*video_))); + controls_ = new MediaControlsImpl(*video_); + timeline_ = new MediaControlTimelineElement(*controls_); + + controls_->InitializeControls(); // Connects the timeline element. Ideally, we should be able to set the // NodeFlags::kConnectedFlag. @@ -41,6 +47,7 @@ private: Persistent<HTMLVideoElement> video_; Persistent<MediaControlTimelineElement> timeline_; + Persistent<MediaControlsImpl> controls_; }; TEST_F(MediaControlTimelineElementTest, PointerDownPausesPlayback) { @@ -142,4 +149,149 @@ EXPECT_FALSE(Video()->paused()); } +TEST_F(MediaControlTimelineElementTest, TouchStartPausesPlayback) { + Video()->Play(); + ASSERT_FALSE(Video()->paused()); + + Timeline()->DispatchEvent( + TouchEvent::Create("touchstart", GetValidTouchEventInit())); + EXPECT_TRUE(Video()->paused()); +} + +TEST_F(MediaControlTimelineElementTest, TouchEndResumesPlayback) { + Video()->Play(); + ASSERT_FALSE(Video()->paused()); + + Timeline()->DispatchEvent( + TouchEvent::Create("touchstart", GetValidTouchEventInit())); + Timeline()->DispatchEvent( + TouchEvent::Create("touchend", GetValidTouchEventInit())); + EXPECT_FALSE(Video()->paused()); +} + +TEST_F(MediaControlTimelineElementTest, TouchCancelResumesPlayback) { + Video()->Play(); + ASSERT_FALSE(Video()->paused()); + + Timeline()->DispatchEvent( + TouchEvent::Create("touchstart", GetValidTouchEventInit())); + Timeline()->DispatchEvent( + TouchEvent::Create("touchcancel", GetValidTouchEventInit())); + EXPECT_FALSE(Video()->paused()); +} + +TEST_F(MediaControlTimelineElementTest, ChangeResumesPlayback) { + Video()->Play(); + ASSERT_FALSE(Video()->paused()); + + Timeline()->DispatchEvent( + TouchEvent::Create("touchstart", GetValidTouchEventInit())); + Timeline()->DispatchEvent( + TouchEvent::Create("change", GetValidTouchEventInit())); + EXPECT_FALSE(Video()->paused()); +} + +TEST_F(MediaControlTimelineElementTest, TouchMoveDoesNotResume) { + Video()->Play(); + ASSERT_FALSE(Video()->paused()); + + Timeline()->DispatchEvent( + TouchEvent::Create("touchstart", GetValidTouchEventInit())); + Timeline()->DispatchEvent( + TouchEvent::Create("touchmove", GetValidTouchEventInit())); + EXPECT_TRUE(Video()->paused()); +} + +TEST_F(MediaControlTimelineElementTest, TouchMoveAfterPointerDoesNotResume) { + Video()->Play(); + ASSERT_FALSE(Video()->paused()); + + Timeline()->DispatchEvent( + PointerEvent::Create("pointerdown", GetValidPointerEventInit())); + Timeline()->DispatchEvent( + TouchEvent::Create("touchmove", GetValidTouchEventInit())); + EXPECT_TRUE(Video()->paused()); +} + +TEST_F(MediaControlTimelineElementTest, TouchEndAfterPointerDoesNotResume) { + Video()->Play(); + ASSERT_FALSE(Video()->paused()); + + Timeline()->DispatchEvent( + PointerEvent::Create("pointerdown", GetValidPointerEventInit())); + Timeline()->DispatchEvent( + TouchEvent::Create("touchend", GetValidTouchEventInit())); + EXPECT_TRUE(Video()->paused()); +} + +TEST_F(MediaControlTimelineElementTest, TouchCancelAfterPointerDoesNotResume) { + Video()->Play(); + ASSERT_FALSE(Video()->paused()); + + Timeline()->DispatchEvent( + PointerEvent::Create("pointerdown", GetValidPointerEventInit())); + Timeline()->DispatchEvent( + TouchEvent::Create("touchcancel", GetValidTouchEventInit())); + EXPECT_TRUE(Video()->paused()); +} + +TEST_F(MediaControlTimelineElementTest, ChangeAfterPointerDoesNotResume) { + Video()->Play(); + ASSERT_FALSE(Video()->paused()); + + Timeline()->DispatchEvent( + PointerEvent::Create("pointerdown", GetValidPointerEventInit())); + Timeline()->DispatchEvent( + TouchEvent::Create("change", GetValidTouchEventInit())); + EXPECT_TRUE(Video()->paused()); +} + +TEST_F(MediaControlTimelineElementTest, PointerUpAfterTouchDoesNotResume) { + Video()->Play(); + ASSERT_FALSE(Video()->paused()); + + Timeline()->DispatchEvent( + TouchEvent::Create("touchstart", GetValidTouchEventInit())); + Timeline()->DispatchEvent( + PointerEvent::Create("pointerup", GetValidPointerEventInit())); + EXPECT_TRUE(Video()->paused()); +} + +TEST_F(MediaControlTimelineElementTest, PointerCancelAfterTouchDoesNotResume) { + Video()->Play(); + ASSERT_FALSE(Video()->paused()); + + Timeline()->DispatchEvent( + TouchEvent::Create("touchstart", GetValidTouchEventInit())); + Timeline()->DispatchEvent( + PointerEvent::Create("pointercancel", GetValidPointerEventInit())); + EXPECT_TRUE(Video()->paused()); +} + +TEST_F(MediaControlTimelineElementTest, UpgradePointerEventToTouchAllowed) { + Video()->Play(); + ASSERT_FALSE(Video()->paused()); + + Timeline()->DispatchEvent( + PointerEvent::Create("pointerdown", GetValidPointerEventInit())); + Timeline()->DispatchEvent( + TouchEvent::Create("touchstart", GetValidTouchEventInit())); + Timeline()->DispatchEvent( + TouchEvent::Create("touchend", GetValidTouchEventInit())); + EXPECT_FALSE(Video()->paused()); +} + +TEST_F(MediaControlTimelineElementTest, UpgradeTouchEventToPointerDenied) { + Video()->Play(); + ASSERT_FALSE(Video()->paused()); + + Timeline()->DispatchEvent( + TouchEvent::Create("touchstart", GetValidTouchEventInit())); + Timeline()->DispatchEvent( + PointerEvent::Create("pointerdown", GetValidPointerEventInit())); + Timeline()->DispatchEvent( + PointerEvent::Create("pointerup", GetValidPointerEventInit())); + EXPECT_TRUE(Video()->paused()); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css b/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css index 74dfb33a..cf79ed2c 100644 --- a/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css +++ b/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css
@@ -551,3 +551,12 @@ .state-loading-metadata input[pseudo="-webkit-media-controls-overlay-play-button" i]::-internal-media-controls-overlay-play-button-internal { opacity: 0; } + +/** + * Scrubbing + */ + +.state-scrubbing div[pseudo="-internal-media-controls-button-panel" i], +.state-scrubbing input[pseudo="-webkit-media-controls-overlay-play-button" i] { + display: none; +}
diff --git a/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls_timeline.css b/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls_timeline.css index 99c593b..f5554ce1 100644 --- a/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls_timeline.css +++ b/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls_timeline.css
@@ -25,3 +25,27 @@ 0% { right: 0%; } 100% { right: 100%; } } + +/** + * Scrubbing + */ + +#thumb { + position: relative; +} + +#thumb-current-time { + position: absolute; + height: 16px; + left: 5px; + bottom: 16px; + padding: 4px 12px; + opacity: 0.9; + background: #FFFFFF; + border-radius: 100px; + font-family: Roboto-Regular, Roboto, sans-serif; + font-size: 14px; + color: #000000; + letter-spacing: 0; + text-shadow: 0 0 10px #FFFFFF; +}
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index b364a52..3474e3e 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -214,6 +214,7 @@ "//services/service_manager/public/interfaces:interfaces_blink", "//skia", "//third_party:jpeg", + "//third_party/WebKit/Source/platform/heap:blink_heap_incremental_marking", "//third_party/WebKit/Source/platform/network:make_generated", "//third_party/WebKit/Source/platform/wtf", "//third_party/WebKit/common:blink_common",
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp index 3b84c939..58915ae 100644 --- a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp +++ b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
@@ -111,6 +111,13 @@ return data_; } +std::unique_ptr<ImageDataBuffer> ImageDataBuffer::Create( + scoped_refptr<StaticBitmapImage> image) { + if (!image || !image->PaintImageForCurrentFrame().GetSkImage()) + return nullptr; + return WTF::WrapUnique(new ImageDataBuffer(image)); +} + ImageDataBuffer::ImageDataBuffer(scoped_refptr<StaticBitmapImage> image) { image_bitmap_ = image; sk_sp<SkImage> skia_image = image->PaintImageForCurrentFrame().GetSkImage();
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBuffer.h b/third_party/WebKit/Source/platform/graphics/ImageBuffer.h index 65f79a32..f73b3ce 100644 --- a/third_party/WebKit/Source/platform/graphics/ImageBuffer.h +++ b/third_party/WebKit/Source/platform/graphics/ImageBuffer.h
@@ -101,8 +101,10 @@ : pixmap_(pixmap), uses_pixmap_(true), size_(IntSize(pixmap.width(), pixmap.height())) {} - PLATFORM_EXPORT ImageDataBuffer(scoped_refptr<StaticBitmapImage>); + ImageDataBuffer(scoped_refptr<StaticBitmapImage>); + static std::unique_ptr<ImageDataBuffer> PLATFORM_EXPORT + Create(scoped_refptr<StaticBitmapImage>); String PLATFORM_EXPORT ToDataURL(const String& mime_type, const double& quality) const; bool PLATFORM_EXPORT EncodeImage(const String& mime_type,
diff --git a/third_party/WebKit/Source/platform/heap/BUILD.gn b/third_party/WebKit/Source/platform/heap/BUILD.gn index ff843b2..04a6ee2 100644 --- a/third_party/WebKit/Source/platform/heap/BUILD.gn +++ b/third_party/WebKit/Source/platform/heap/BUILD.gn
@@ -7,6 +7,21 @@ import("//third_party/WebKit/Source/platform/platform.gni") import("//testing/test.gni") +declare_args() { + # Enables incremental marking in Oilpan. + enable_blink_heap_incremental_marking = false +} + +buildflag_header("blink_heap_incremental_marking") { + header = "IncrementalMarkingFlag.h" + + header_dir = "blink/platform/heap" + + flags = [ + "BLINK_HEAP_INCREMENTAL_MARKING=$enable_blink_heap_incremental_marking", + ] +} + blink_platform_sources("heap") { sources = [ "BlinkGC.h",
diff --git a/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp b/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp index 0be9cf2..8df718b 100644 --- a/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp +++ b/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp
@@ -5,13 +5,13 @@ #include "platform/heap/CallbackStack.h" #include "platform/heap/GarbageCollected.h" #include "platform/heap/Heap.h" +#include "platform/heap/IncrementalMarkingFlag.h" #include "platform/heap/Member.h" #include "platform/heap/ThreadState.h" #include "platform/heap/TraceTraits.h" #include "testing/gtest/include/gtest/gtest.h" -// TODO(mlippautz): Replace with proper build flag. -#if 0 +#if BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING) namespace blink { namespace incremental_marking_test { @@ -214,4 +214,4 @@ } // namespace incremental_marking_test } // namespace blink -#endif +#endif // BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING)
diff --git a/third_party/WebKit/Source/platform/heap/Member.h b/third_party/WebKit/Source/platform/heap/Member.h index fedefb2..3a0792f 100644 --- a/third_party/WebKit/Source/platform/heap/Member.h +++ b/third_party/WebKit/Source/platform/heap/Member.h
@@ -7,6 +7,7 @@ #include "platform/heap/Heap.h" #include "platform/heap/HeapPage.h" +#include "platform/heap/IncrementalMarkingFlag.h" #include "platform/wtf/Allocator.h" #include "platform/wtf/HashFunctions.h" #include "platform/wtf/HashTraits.h" @@ -249,8 +250,7 @@ protected: ALWAYS_INLINE void WriteBarrier(const T* value) const { -// TODO(mlippautz): Replace with proper build flag. -#if 0 +#if BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING) if (value) { // The following method for retrieving a page works as allocation of // mixins on large object pages is prohibited. @@ -260,7 +260,7 @@ ThreadState::Current()->Heap().WriteBarrierInternal(page, value); } } -#endif +#endif // BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING) } };
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp index 63a3970..d084fd08 100644 --- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp +++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
@@ -45,6 +45,7 @@ #include "platform/heap/Handle.h" #include "platform/heap/Heap.h" #include "platform/heap/HeapCompact.h" +#include "platform/heap/IncrementalMarkingFlag.h" #include "platform/heap/PagePool.h" #include "platform/heap/SafePoint.h" #include "platform/heap/Visitor.h" @@ -364,15 +365,14 @@ } bool ThreadState::ShouldScheduleIncrementalMarking() const { -// TODO(mlippautz): Replace with proper build flag. -#if 0 +#if BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING) // TODO(mlippautz): For now immediately schedule incremental marking if // the runtime flag is provided, basically exercising a stress test. return (GcState() == kNoGCScheduled || GcState() == kSweeping) && RuntimeEnabledFeatures::HeapIncrementalMarkingEnabled(); #else return false; -#endif +#endif // BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING) } bool ThreadState::ShouldScheduleIdleGC() {
diff --git a/third_party/WebKit/Source/platform/wtf/text/TextCodec.cpp b/third_party/WebKit/Source/platform/wtf/text/TextCodec.cpp index ddcafffe..67ddf59 100644 --- a/third_party/WebKit/Source/platform/wtf/text/TextCodec.cpp +++ b/third_party/WebKit/Source/platform/wtf/text/TextCodec.cpp
@@ -42,10 +42,9 @@ code_point); return static_cast<int>(strlen(replacement)); case kURLEncodedEntitiesForUnencodables: - snprintf(replacement, sizeof(UnencodableReplacementArray), - "%%26%%23%u%%3B", code_point); + snprintf(replacement, sizeof(UnencodableReplacementArray), "&%%23%u;", + code_point); return static_cast<int>(strlen(replacement)); - case kCSSEncodedEntitiesForUnencodables: snprintf(replacement, sizeof(UnencodableReplacementArray), "\\%x ", code_point);
diff --git a/third_party/WebKit/Source/platform/wtf/text/TextCodec.h b/third_party/WebKit/Source/platform/wtf/text/TextCodec.h index dddd7d74..f18c149 100644 --- a/third_party/WebKit/Source/platform/wtf/text/TextCodec.h +++ b/third_party/WebKit/Source/platform/wtf/text/TextCodec.h
@@ -46,7 +46,7 @@ // Encodes the character as en entity as above, but escaped // non-alphanumeric characters. This is used in URLs. - // For example, U+6DE would be "%26%231758%3B". + // For example, U+6DE would be "&%231758;". kURLEncodedEntitiesForUnencodables, // Encodes the character as a CSS entity. For example U+06DE
diff --git a/third_party/WebKit/Source/platform/wtf/text/TextCodecTest.cpp b/third_party/WebKit/Source/platform/wtf/text/TextCodecTest.cpp index 21a7249..d9cf9bfe 100644 --- a/third_party/WebKit/Source/platform/wtf/text/TextCodecTest.cpp +++ b/third_party/WebKit/Source/platform/wtf/text/TextCodecTest.cpp
@@ -49,9 +49,9 @@ UnencodableReplacementArray replacement; int size = TextCodec::GetUnencodableReplacement( 0xE003, kURLEncodedEntitiesForUnencodables, replacement); - EXPECT_EQ(size, 14); - EXPECT_EQ(std::string(replacement), "%26%2357347%3B"); - EXPECT_EQ(replacement[14], 0); + EXPECT_EQ(size, 10); + EXPECT_EQ(std::string(replacement), "&%2357347;"); + EXPECT_EQ(replacement[10], 0); } TEST(TextCodec, CSSEntityEncoding) {
diff --git a/third_party/WebKit/Tools/Scripts/run-inspector-tests b/third_party/WebKit/Tools/Scripts/run-inspector-tests deleted file mode 100755 index 62be761..0000000 --- a/third_party/WebKit/Tools/Scripts/run-inspector-tests +++ /dev/null
@@ -1,15 +0,0 @@ -#!/usr/bin/env vpython -# 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. - -"""Run inspector (DevTools) layout tests""" -from os import path -import sys - -from webkitpy.common import multiprocessing_bootstrap - -up = path.dirname -layout_tests = path.join(up(up(up(path.abspath(__file__)))), 'Source', 'devtools', 'layout_tests') -sys.argv.append('--layout-tests-directory={}'.format(layout_tests)) -multiprocessing_bootstrap.run('webkitpy', 'layout_tests', 'run_webkit_tests.py')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py index 257bdc4..c7c4387 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py
@@ -66,7 +66,6 @@ """A class for managing running a series of layout tests.""" HTTP_SUBDIR = 'http' - INSPECTOR_SUBDIR = 'inspector' PERF_SUBDIR = 'perf' WEBSOCKET_SUBDIR = 'websocket' ARCHIVED_RESULTS_LIMIT = 25 @@ -277,9 +276,6 @@ self._port.TEST_PATH_SEPARATOR + self.HTTP_SUBDIR + self._port.TEST_PATH_SEPARATOR in test ) - def _is_inspector_test(self, test): - return self.INSPECTOR_SUBDIR + self._port.TEST_PATH_SEPARATOR in test - def _is_websocket_test(self, test): if self._port.should_use_wptserve(test): return False @@ -399,8 +395,7 @@ self._port.start_wptserve() self._wptserve_started = True - if self._port.requires_http_server() or any((self._is_http_test(test) or self._is_inspector_test(test)) - for test in tests_to_run): + if self._port.requires_http_server() or any(self._is_http_test(test) for test in tests_to_run): self._printer.write_update('Starting HTTP server ...') self._port.start_http_server(additional_dirs={}, number_of_drivers=self._options.max_locked_shards) self._http_server_started = True
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/single_test_runner.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/single_test_runner.py index de7c506..9523ab4 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/single_test_runner.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/single_test_runner.py
@@ -159,6 +159,7 @@ return test_result def _run_compare_test(self): + """Runs the signle test and returns test result.""" driver_output = self._driver.run_test(self._driver_input(), self._stop_when_done) expected_driver_output = self._expected_driver_output() @@ -168,30 +169,34 @@ return test_result def _run_rebaseline(self): + """Similar to _run_compare_test(), but has the side effect of updating or adding baselines. + This is called when --reset-results and/or --copy-baselines are specified in the command line. + If --reset-results, in the returned result we treat baseline mismatch as success.""" driver_output = self._driver.run_test(self._driver_input(), self._stop_when_done) - if self._options.reset_results: - expected_driver_output = None - failures = self._handle_error(driver_output) - else: - expected_driver_output = self._expected_driver_output() - failures = self._compare_output(expected_driver_output, driver_output).failures + expected_driver_output = self._expected_driver_output() + actual_failures = self._compare_output(expected_driver_output, driver_output).failures + failures = self._handle_error(driver_output) if self._options.reset_results else actual_failures test_result_writer.write_test_result(self._filesystem, self._port, self._results_directory, self._test_name, driver_output, expected_driver_output, failures) - # FIXME: It the test crashed or timed out, it might be better to avoid - # to write new baselines. - self._update_or_add_new_baselines(driver_output) + self._update_or_add_new_baselines(driver_output, actual_failures) return TestResult(self._test_name, failures, driver_output.test_time, driver_output.has_stderr(), pid=driver_output.pid, crash_site=driver_output.crash_site) _render_tree_dump_pattern = re.compile(r"^layer at \(\d+,\d+\) size \d+x\d+\n") - def _update_or_add_new_baselines(self, driver_output): - self._save_baseline_data(driver_output.text, '.txt') - self._save_baseline_data(driver_output.audio, '.wav') - if self._should_run_pixel_test: - self._save_baseline_data(driver_output.image, '.png') + def _update_or_add_new_baselines(self, driver_output, failures): + """Updates or adds new baselines for the test if necessary.""" + if (test_failures.has_failure_type(test_failures.FailureTimeout, failures) or + test_failures.has_failure_type(test_failures.FailureCrash, failures)): + return + self._save_baseline_data(driver_output.text, '.txt', + test_failures.has_failure_type(test_failures.FailureMissingResult, failures)) + self._save_baseline_data(driver_output.audio, '.wav', + test_failures.has_failure_type(test_failures.FailureMissingAudio, failures)) + self._save_baseline_data(driver_output.image, '.png', + test_failures.has_failure_type(test_failures.FailureMissingImage, failures)) - def _save_baseline_data(self, data, extension): + def _save_baseline_data(self, data, extension, is_missing): if data is None: return port = self._port @@ -218,7 +223,10 @@ fs.remove(output_path) current_expected_path = port.expected_filename(self._test_name, extension) - if fs.exists(current_expected_path) and fs.sha1(current_expected_path) == hashlib.sha1(data).hexdigest(): + if not fs.exists(current_expected_path): + if not is_missing or not self._options.reset_results: + return + elif fs.sha1(current_expected_path) == hashlib.sha1(data).hexdigest(): if self._options.reset_results: _log.info('Not writing new expected result "%s" because it is the same as the current expected result', port.relative_test_filename(output_path))
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py index 0b5cc46..0c8fad1e 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py
@@ -531,7 +531,7 @@ self.assertTrue(is_test_file('', 'foo.html')) self.assertTrue(is_test_file('', 'foo.svg')) self.assertTrue(is_test_file('', 'test-ref-test.html')) - self.assertFalse(is_test_file('inspector', 'devtools.js')) + self.assertTrue(is_test_file('devtools', 'a.js')) self.assertFalse(is_test_file('', 'foo.png')) self.assertFalse(is_test_file('', 'foo-expected.html')) self.assertFalse(is_test_file('', 'foo-expected.svg'))
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py index 07e9c18..8978bf9e 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py
@@ -110,14 +110,14 @@ # # These numbers may need to be updated whenever we add or delete tests. This includes virtual tests. # -TOTAL_TESTS = 129 +TOTAL_TESTS = 135 TOTAL_WONTFIX = 3 TOTAL_SKIPS = 21 + TOTAL_WONTFIX TOTAL_CRASHES = 76 UNEXPECTED_PASSES = 1 -UNEXPECTED_NON_VIRTUAL_FAILURES = 19 -UNEXPECTED_FAILURES = 45 +UNEXPECTED_NON_VIRTUAL_FAILURES = 21 +UNEXPECTED_FAILURES = 49 def unit_test_list(): @@ -176,6 +176,10 @@ actual_checksum='text-image-checksum_fail-checksum') tests.add('failures/unexpected/checksum-with-matching-image.html', actual_checksum='text-image-checksum_fail-checksum') + tests.add('failures/unexpected/image-only.html', + expected_text=None, actual_text='text', + actual_image='image-only_fail-pngtEXtchecksum\x00checksum_fail', + actual_checksum='image-only_fail-checksum') tests.add('failures/unexpected/skip_pass.html') tests.add('failures/unexpected/text.html', actual_text='text_fail-txt') tests.add('failures/unexpected/text_then_crash.html') @@ -196,6 +200,8 @@ tests.add('passes/checksum_in_image.html', expected_image='tEXtchecksum\x00checksum_in_image-checksum') tests.add('passes/skipped/skip.html') + tests.add('failures/unexpected/testharness.html', + actual_text='This is a testharness.js-based test.\nFAIL: bah\nHarness: the test ran to completion.') # Note that here the checksums don't match/ but the images do, so this test passes "unexpectedly". # See https://bugs.webkit.org/show_bug.cgi?id=69444 . @@ -267,6 +273,18 @@ tests.add('passes/virtual_passes/test-virtual-passes.html') tests.add('passes_two/test-virtual-passes.html') + + tests.add('passes/testharness.html', + actual_text='This is a testharness.js-based test.\nPASS: bah\n' + 'Harness: the test ran to completion.', + actual_image=None, + expected_text=None) + tests.add('failures/unexpected/testharness.html', + actual_text='This is a testharness.js-based test.\nFAIL: bah\n' + 'Harness: the test ran to completion.', + actual_image=None, + expected_text=None) + return tests
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py index be13d33..1004ce44 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
@@ -1166,6 +1166,53 @@ 'failures/unexpected/missing_render_tree_dump', expected_extensions=['.txt']) + def test_reset_results_testharness_no_baseline(self): + # Tests that we don't create new result for a testharness test without baselines. + host = MockHost() + details, log_stream, _ = logging_run( + [ + '--reset-results', + 'failures/unexpected/testharness.html', + 'passes/testharness.html' + ], + tests_included=True, host=host) + file_list = host.filesystem.written_files.keys() + self.assertEqual(details.exit_code, 0) + self.assertEqual(len(file_list), 5) + self.assert_baselines(file_list, log_stream, 'failures/unexpected/testharness', []) + self.assert_baselines(file_list, log_stream, 'passes/testharness', []) + + def test_reset_results_testharness_existing_baseline(self): + # Tests that we update existing baseline for a testharness test. + host = MockHost() + host.filesystem.write_text_file( + test.LAYOUT_TEST_DIR + '/failures/unexpected/testharness-expected.txt', 'foo') + details, log_stream, _ = logging_run( + [ + '--reset-results', + 'failures/unexpected/testharness.html' + ], + tests_included=True, host=host) + self.assertEqual(details.exit_code, 0) + file_list = host.filesystem.written_files.keys() + self.assertEqual(len(file_list), 6) + self.assert_baselines(file_list, log_stream, 'failures/unexpected/testharness', ['.txt']) + + def test_reset_results_image_first(self): + # Tests that we don't create new text results for an image first test without text result. + host = MockHost() + details, log_stream, _ = logging_run( + [ + '--reset-results', + '--image-first-tests=failures/unexpected', + 'failures/unexpected/image-only.html', + ], + tests_included=True, host=host) + self.assertEqual(details.exit_code, 0) + file_list = host.filesystem.written_files.keys() + self.assertEqual(len(file_list), 6) + self.assert_baselines(file_list, log_stream, 'failures/unexpected/image-only', ['.png']) + def test_copy_baselines(self): # Test that we update the baselines in the version-specific directories # if the new baseline is different from the fallback baseline.
diff --git a/third_party/libovr/.gitignore b/third_party/libovr/.gitignore new file mode 100644 index 0000000..c9e74aa --- /dev/null +++ b/third_party/libovr/.gitignore
@@ -0,0 +1,3 @@ +src/**/*.cpp +src/**/*.c +src/**/*.h \ No newline at end of file
diff --git a/third_party/libovr/BUILD.gn b/third_party/libovr/BUILD.gn new file mode 100644 index 0000000..bec8d4f1 --- /dev/null +++ b/third_party/libovr/BUILD.gn
@@ -0,0 +1,29 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +config("libovr-config") { + cflags = [ "-Wno-unused-function" ] +} + +static_library("libovr") { + include_dirs = [ "src/Include" ] + sources = [ + "src/Include/Extras/OVR_CAPI_Util.h", + "src/Include/Extras/OVR_Math.h", + "src/Include/Extras/OVR_StereoProjection.h", + "src/Include/OVR_CAPI.h", + "src/Include/OVR_CAPI_D3D.h", + "src/Include/OVR_CAPI_GL.h", + "src/Include/OVR_CAPI_Keys.h", + "src/Include/OVR_CAPI_Vk.h", + "src/Include/OVR_ErrorCode.h", + "src/Include/OVR_Version.h", + "src/OVR_CAPIShim.c", + "src/OVR_CAPI_Prototypes.h", + "src/OVR_CAPI_Util.cpp", + "src/OVR_StereoProjection.cpp", + ] + + configs += [ ":libovr-config" ] +}
diff --git a/third_party/libovr/LICENSE b/third_party/libovr/LICENSE new file mode 100644 index 0000000..59e3737 --- /dev/null +++ b/third_party/libovr/LICENSE
@@ -0,0 +1 @@ +Copyright © 2014-2017 Oculus VR, LLC. All rights reserved. \ No newline at end of file
diff --git a/third_party/libovr/OWNERS b/third_party/libovr/OWNERS new file mode 100644 index 0000000..13a31ee --- /dev/null +++ b/third_party/libovr/OWNERS
@@ -0,0 +1,3 @@ +bajones@chromium.org +billorr@chromium.org +ddorwin@chromium.org
diff --git a/third_party/libovr/README.chromium b/third_party/libovr/README.chromium new file mode 100644 index 0000000..ce73e884 --- /dev/null +++ b/third_party/libovr/README.chromium
@@ -0,0 +1,26 @@ +Name: Oculus SDK for Windows +Short Name: libovr +URL: https://developer.oculus.com/downloads/package/oculus-sdk-for-windows/ +Version: 1.16.0 +License: By exception only +License File: LICENSE +Security Critical: yes +License Android Compatible: no + +Description: +The Oculus Windows API supports VR headsets from Oculus running on Windows. + +Googler update instructions: +third_party\depot_tools\upload_to_google_storage.py path\to\file.h -b + chrome-oculus-sdk +Then, commit the modified sha1. Only Googlers have access to this bucket. Be +sure to get OWNER approval before adding new files. + +Local Modifications: +Only includes headers and a loader shim. +The directory structure of third_party/libovr/src mirrors the LibOVR folder in +the Oculus SDK for Windows. +Oculus-required attribution in LICENSE. +Removed WINCRYPT32API from OVR_CAPIShim.c in order to build with Clang. +Changed OVR_StereoProjection.h to #include "OVR_Math.h" to solve DEP issue. +Changed OVR_CAPI_Util.h to #include "../OVR_CAPI.h" to solve include issue. \ No newline at end of file
diff --git a/third_party/libovr/src/Include/Extras/OVR_CAPI_Util.h.sha1 b/third_party/libovr/src/Include/Extras/OVR_CAPI_Util.h.sha1 new file mode 100644 index 0000000..712fd3e7 --- /dev/null +++ b/third_party/libovr/src/Include/Extras/OVR_CAPI_Util.h.sha1
@@ -0,0 +1 @@ +1b3ba32d6b56915b0fd179b52edff2f9c0c76de6 \ No newline at end of file
diff --git a/third_party/libovr/src/Include/Extras/OVR_Math.h.sha1 b/third_party/libovr/src/Include/Extras/OVR_Math.h.sha1 new file mode 100644 index 0000000..1216e70 --- /dev/null +++ b/third_party/libovr/src/Include/Extras/OVR_Math.h.sha1
@@ -0,0 +1 @@ +10835d00a39faa837834f7841b4bab4b82493dad \ No newline at end of file
diff --git a/third_party/libovr/src/Include/Extras/OVR_StereoProjection.h.sha1 b/third_party/libovr/src/Include/Extras/OVR_StereoProjection.h.sha1 new file mode 100644 index 0000000..1328b6b1 --- /dev/null +++ b/third_party/libovr/src/Include/Extras/OVR_StereoProjection.h.sha1
@@ -0,0 +1 @@ +24d793cea809395c2006894a50a401ba39b21d1e \ No newline at end of file
diff --git a/third_party/libovr/src/Include/OVR_CAPI.h.sha1 b/third_party/libovr/src/Include/OVR_CAPI.h.sha1 new file mode 100644 index 0000000..1c24fb8 --- /dev/null +++ b/third_party/libovr/src/Include/OVR_CAPI.h.sha1
@@ -0,0 +1 @@ +8d53bd779df72eb4195e640ce936fcd992c943c7 \ No newline at end of file
diff --git a/third_party/libovr/src/Include/OVR_CAPI_D3D.h.sha1 b/third_party/libovr/src/Include/OVR_CAPI_D3D.h.sha1 new file mode 100644 index 0000000..a24d9de0 --- /dev/null +++ b/third_party/libovr/src/Include/OVR_CAPI_D3D.h.sha1
@@ -0,0 +1 @@ +a2b38fcd4d618922ba00b58e024b8ee546b2bc14 \ No newline at end of file
diff --git a/third_party/libovr/src/Include/OVR_CAPI_GL.h.sha1 b/third_party/libovr/src/Include/OVR_CAPI_GL.h.sha1 new file mode 100644 index 0000000..b932bfcf --- /dev/null +++ b/third_party/libovr/src/Include/OVR_CAPI_GL.h.sha1
@@ -0,0 +1 @@ +1e0be49c9ba6a622ef33e1623367eb6dfc77977c \ No newline at end of file
diff --git a/third_party/libovr/src/Include/OVR_CAPI_Keys.h.sha1 b/third_party/libovr/src/Include/OVR_CAPI_Keys.h.sha1 new file mode 100644 index 0000000..60c6838 --- /dev/null +++ b/third_party/libovr/src/Include/OVR_CAPI_Keys.h.sha1
@@ -0,0 +1 @@ +120d1d3d1506c1a47a79045d4c279d760e468629 \ No newline at end of file
diff --git a/third_party/libovr/src/Include/OVR_CAPI_Vk.h.sha1 b/third_party/libovr/src/Include/OVR_CAPI_Vk.h.sha1 new file mode 100644 index 0000000..dffc757 --- /dev/null +++ b/third_party/libovr/src/Include/OVR_CAPI_Vk.h.sha1
@@ -0,0 +1 @@ +89dcbfd32c81a0e1df5c321eea50fa30348ba4a2 \ No newline at end of file
diff --git a/third_party/libovr/src/Include/OVR_ErrorCode.h.sha1 b/third_party/libovr/src/Include/OVR_ErrorCode.h.sha1 new file mode 100644 index 0000000..d74224a6 --- /dev/null +++ b/third_party/libovr/src/Include/OVR_ErrorCode.h.sha1
@@ -0,0 +1 @@ +77fc8a13dd9b947a24703eec78639c1c5e862fc3 \ No newline at end of file
diff --git a/third_party/libovr/src/Include/OVR_Version.h.sha1 b/third_party/libovr/src/Include/OVR_Version.h.sha1 new file mode 100644 index 0000000..d7e47e02 --- /dev/null +++ b/third_party/libovr/src/Include/OVR_Version.h.sha1
@@ -0,0 +1 @@ +4eeb533ee42b199f5f5c57409448ad00485b14e1 \ No newline at end of file
diff --git a/third_party/libovr/src/OVR_CAPIShim.c.sha1 b/third_party/libovr/src/OVR_CAPIShim.c.sha1 new file mode 100644 index 0000000..933b472 --- /dev/null +++ b/third_party/libovr/src/OVR_CAPIShim.c.sha1
@@ -0,0 +1 @@ +c8235e8e486a73d85a8e1f3221d74f9f93ce2e7c \ No newline at end of file
diff --git a/third_party/libovr/src/OVR_CAPI_Prototypes.h.sha1 b/third_party/libovr/src/OVR_CAPI_Prototypes.h.sha1 new file mode 100644 index 0000000..7093831 --- /dev/null +++ b/third_party/libovr/src/OVR_CAPI_Prototypes.h.sha1
@@ -0,0 +1 @@ +0588604435704be9a0017f7a4f9d56b9d8560e8a \ No newline at end of file
diff --git a/third_party/libovr/src/OVR_CAPI_Util.cpp.sha1 b/third_party/libovr/src/OVR_CAPI_Util.cpp.sha1 new file mode 100644 index 0000000..6e92d18e --- /dev/null +++ b/third_party/libovr/src/OVR_CAPI_Util.cpp.sha1
@@ -0,0 +1 @@ +5f3e1e83ce37ba0e6c62156b2aee27607015c4ca \ No newline at end of file
diff --git a/third_party/libovr/src/OVR_StereoProjection.cpp.sha1 b/third_party/libovr/src/OVR_StereoProjection.cpp.sha1 new file mode 100644 index 0000000..eafd31e4 --- /dev/null +++ b/third_party/libovr/src/OVR_StereoProjection.cpp.sha1
@@ -0,0 +1 @@ +c245697735368aa7a561e68797fa9304140457b2 \ No newline at end of file
diff --git a/tools/checklicenses/checklicenses.py b/tools/checklicenses/checklicenses.py index 450f1de..8d8b07e 100755 --- a/tools/checklicenses/checklicenses.py +++ b/tools/checklicenses/checklicenses.py
@@ -427,6 +427,11 @@ 'UNKNOWN', ], + # The following files have a special license. + 'third_party/libovr/src': [ + 'UNKNOWN', + ], + # The following files lack license headers, but are trivial. 'third_party/libusb/src/libusb/os/poll_posix.h': [ 'UNKNOWN',
diff --git a/tools/licenses.py b/tools/licenses.py index 1021763..8dc8be89 100755 --- a/tools/licenses.py +++ b/tools/licenses.py
@@ -283,6 +283,7 @@ os.path.join('third_party', 'libXNVCtrl'), os.path.join('third_party', 'libevent'), os.path.join('third_party', 'libjpeg'), + os.path.join('third_party', 'libovr'), os.path.join('third_party', 'libusb'), os.path.join('third_party', 'libxslt'), os.path.join('third_party', 'lss'),
diff --git a/tools/perf/page_sets/media_cases.py b/tools/perf/page_sets/media_cases.py index 6f999a4a..5dae8122 100644 --- a/tools/perf/page_sets/media_cases.py +++ b/tools/perf/page_sets/media_cases.py
@@ -234,10 +234,6 @@ page_set=self, tags=['is_50fps', 'h264', 'aac', 'audio_video']), _BeginningToEndPlayPage( - url=_URL_BASE + 'video.html?src=crowd2160.mp4', - page_set=self, - tags=['is_4k', 'is_50fps', 'h264', 'aac', 'audio_video']), - _BeginningToEndPlayPage( url=_URL_BASE + 'video.html?src=tulip2.mp3&type=audio', page_set=self, tags=['mp3', 'audio_only']),
diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc index 24c0bf2..2cfa8da7 100644 --- a/ui/app_list/views/app_list_main_view.cc +++ b/ui/app_list/views/app_list_main_view.cc
@@ -180,9 +180,4 @@ contents_view_->Back(); } -void AppListMainView::SetSearchResultSelection(bool select) { - if (contents_view_->GetActiveState() == AppListModel::STATE_SEARCH_RESULTS) - contents_view_->search_results_page_view()->SetSelection(select); -} - } // namespace app_list
diff --git a/ui/app_list/views/app_list_main_view.h b/ui/app_list/views/app_list_main_view.h index c4e9bbe..94c852f 100644 --- a/ui/app_list/views/app_list_main_view.h +++ b/ui/app_list/views/app_list_main_view.h
@@ -86,7 +86,6 @@ // Overridden from SearchBoxViewDelegate: void QueryChanged(SearchBoxView* sender) override; void BackButtonPressed() override; - void SetSearchResultSelection(bool select) override; AppListViewDelegate* delegate_; // Owned by parent view (AppListView). AppListModel* model_; // Unowned; ownership is handled by |delegate_|.
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc index d0857584..9aec45d 100644 --- a/ui/app_list/views/app_list_view.cc +++ b/ui/app_list/views/app_list_view.cc
@@ -250,7 +250,6 @@ short_animations_for_testing_(false), is_fullscreen_app_list_enabled_(features::IsFullscreenAppListEnabled()), is_background_blur_enabled_(features::IsBackgroundBlurEnabled()), - is_app_list_focus_enabled_(features::IsAppListFocusEnabled()), display_observer_(this), animation_observer_(new HideViewAnimationObserver()), previous_arrow_key_traversal_enabled_(
diff --git a/ui/app_list/views/app_list_view.h b/ui/app_list/views/app_list_view.h index b210b5c1..9a365217 100644 --- a/ui/app_list/views/app_list_view.h +++ b/ui/app_list/views/app_list_view.h
@@ -373,8 +373,6 @@ const bool is_fullscreen_app_list_enabled_; // Whether the background blur is enabled. const bool is_background_blur_enabled_; - // Whether the app list focus is enabled. - const bool is_app_list_focus_enabled_; // The state of the app list, controlled via SetState(). AppListViewState app_list_state_ = AppListViewState::PEEKING; // An observer that notifies AppListView when the display has changed.
diff --git a/ui/app_list/views/contents_view.cc b/ui/app_list/views/contents_view.cc index 064efac..a52c81a 100644 --- a/ui/app_list/views/contents_view.cc +++ b/ui/app_list/views/contents_view.cc
@@ -233,8 +233,6 @@ int search_page = GetPageIndexForState(AppListModel::STATE_SEARCH_RESULTS); DCHECK_GE(search_page, 0); - search_results_page_view_->ClearSelectedIndex(); - SetActiveStateInternal(show ? search_page : page_before_search_, show, true); } @@ -447,31 +445,6 @@ } } -bool ContentsView::OnKeyPressed(const ui::KeyEvent& event) { - if (features::IsAppListFocusEnabled()) - return false; - // TODO(weidongg/766807) Remove this function when the flag is enabled by - // default. - if (app_list_pages_[GetActivePageIndex()]->OnKeyPressed(event)) - return true; - if (event.key_code() != ui::VKEY_TAB && - !GetSearchBoxView()->IsArrowKey(event)) - return false; - if (is_fullscreen_app_list_enabled_) { - if (event.key_code() == ui::VKEY_TAB) - GetSearchBoxView()->MoveTabFocus(event.IsShiftDown()); - else - GetSearchBoxView()->MoveArrowFocus(event); - return true; - } - if (event.IsShiftDown()) { - GetSearchBoxView()->MoveTabFocus(true); - return true; - } - - return false; -} - const char* ContentsView::GetClassName() const { return "ContentsView"; }
diff --git a/ui/app_list/views/contents_view.h b/ui/app_list/views/contents_view.h index b24858a..d3955b7 100644 --- a/ui/app_list/views/contents_view.h +++ b/ui/app_list/views/contents_view.h
@@ -142,7 +142,6 @@ // Overridden from views::View: gfx::Size CalculatePreferredSize() const override; void Layout() override; - bool OnKeyPressed(const ui::KeyEvent& event) override; const char* GetClassName() const override; // Overridden from PaginationModelObserver:
diff --git a/ui/app_list/views/folder_header_view.cc b/ui/app_list/views/folder_header_view.cc index f8da78d2..43a4bd54 100644 --- a/ui/app_list/views/folder_header_view.cc +++ b/ui/app_list/views/folder_header_view.cc
@@ -42,8 +42,7 @@ ~FolderNameView() override {} void OnFocus() override { - if (features::IsAppListFocusEnabled()) - SelectAll(false); + SelectAll(false); Textfield::OnFocus(); }
diff --git a/ui/app_list/views/search_box_view_delegate.h b/ui/app_list/views/search_box_view_delegate.h index e0e27c5..3de08683 100644 --- a/ui/app_list/views/search_box_view_delegate.h +++ b/ui/app_list/views/search_box_view_delegate.h
@@ -19,9 +19,6 @@ // Invoked when the back button has been pressed. virtual void BackButtonPressed() = 0; - // Selects first item or clears selection from search list. - virtual void SetSearchResultSelection(bool select) = 0; - protected: virtual ~SearchBoxViewDelegate() {} };
diff --git a/ui/app_list/views/search_box_view_unittest.cc b/ui/app_list/views/search_box_view_unittest.cc index 1e0253b..e2c4c23 100644 --- a/ui/app_list/views/search_box_view_unittest.cc +++ b/ui/app_list/views/search_box_view_unittest.cc
@@ -140,8 +140,6 @@ void BackButtonPressed() override {} - void SetSearchResultSelection(bool select) override {} - AppListTestViewDelegate view_delegate_; views::Widget* widget_; AppListView* app_list_view_ = nullptr;
diff --git a/ui/app_list/views/search_result_list_view.cc b/ui/app_list/views/search_result_list_view.cc index b7058add..f78ad7f 100644 --- a/ui/app_list/views/search_result_list_view.cc +++ b/ui/app_list/views/search_result_list_view.cc
@@ -12,7 +12,6 @@ #include "base/message_loop/message_loop.h" #include "base/time/time.h" #include "third_party/skia/include/core/SkColor.h" -#include "ui/app_list/app_list_features.h" #include "ui/app_list/app_list_view_delegate.h" #include "ui/app_list/views/app_list_main_view.h" #include "ui/app_list/views/search_result_view.h" @@ -69,52 +68,6 @@ SetAutoLaunchTimeout(view_delegate_->GetAutoLaunchTimeout()); } -bool SearchResultListView::OnKeyPressed(const ui::KeyEvent& event) { - if (features::IsAppListFocusEnabled()) { - // TODO(weidongg/766807) Remove this function when the flag is enabled by - // default. - return false; - } - if (selected_index() >= 0 && - results_container_->child_at(selected_index())->OnKeyPressed(event)) { - return true; - } - - int selection_index = -1; - const int forward_dir = base::i18n::IsRTL() ? -1 : 1; - switch (event.key_code()) { - case ui::VKEY_TAB: - if (event.IsShiftDown()) - selection_index = selected_index() - 1; - else - selection_index = selected_index() + 1; - break; - case ui::VKEY_UP: - selection_index = selected_index() - 1; - break; - case ui::VKEY_DOWN: - selection_index = selected_index() + 1; - break; - case ui::VKEY_LEFT: - selection_index = selected_index() - forward_dir; - break; - case ui::VKEY_RIGHT: - selection_index = selected_index() + forward_dir; - break; - default: - break; - } - - if (IsValidSelectionIndex(selection_index)) { - SetSelectedIndex(selection_index); - if (auto_launch_animation_) - CancelAutoLaunchTimeout(); - return true; - } - - return false; -} - void SearchResultListView::SetAutoLaunchTimeout( const base::TimeDelta& timeout) { if (timeout > base::TimeDelta()) {
diff --git a/ui/app_list/views/search_result_list_view.h b/ui/app_list/views/search_result_list_view.h index 378ee38..e203dcc 100644 --- a/ui/app_list/views/search_result_list_view.h +++ b/ui/app_list/views/search_result_list_view.h
@@ -48,7 +48,6 @@ void OnSearchResultInstalled(SearchResultView* view); // Overridden from views::View: - bool OnKeyPressed(const ui::KeyEvent& event) override; gfx::Size CalculatePreferredSize() const override; // Overridden from ui::ListModelObserver:
diff --git a/ui/app_list/views/search_result_page_view.cc b/ui/app_list/views/search_result_page_view.cc index 25ce3ab..d1b50d2 100644 --- a/ui/app_list/views/search_result_page_view.cc +++ b/ui/app_list/views/search_result_page_view.cc
@@ -11,7 +11,6 @@ #include "base/memory/ptr_util.h" #include "ui/app_list/app_list_constants.h" -#include "ui/app_list/app_list_features.h" #include "ui/app_list/app_list_util.h" #include "ui/app_list/app_list_view_delegate.h" #include "ui/app_list/views/app_list_main_view.h" @@ -139,10 +138,7 @@ DISALLOW_COPY_AND_ASSIGN(HorizontalSeparator); }; -SearchResultPageView::SearchResultPageView() - : selected_index_(0), - is_app_list_focus_enabled_(features::IsAppListFocusEnabled()), - contents_view_(new views::View) { +SearchResultPageView::SearchResultPageView() : contents_view_(new views::View) { SetPaintToLayer(); layer()->SetFillsBoundsOpaquely(false); contents_view_->SetLayoutManager(std::make_unique<views::BoxLayout>( @@ -172,13 +168,6 @@ SearchResultPageView::~SearchResultPageView() = default; -void SearchResultPageView::SetSelection(bool select) { - if (select) - SetSelectedIndex(0, false); - else - ClearSelectedIndex(); -} - void SearchResultPageView::AddSearchResultContainerView( SearchModel::SearchResults* results_model, SearchResultContainerView* result_container) { @@ -194,84 +183,33 @@ } bool SearchResultPageView::OnKeyPressed(const ui::KeyEvent& event) { - if (is_app_list_focus_enabled_) { - // Let the FocusManager handle Left/Right keys. - if (!CanProcessUpDownKeyTraversal(event)) - return false; - - views::View* next_focusable_view = nullptr; - if (event.key_code() == ui::VKEY_UP) { - next_focusable_view = GetFocusManager()->GetNextFocusableView( - GetFocusManager()->GetFocusedView(), GetWidget(), true, false); - } else { - DCHECK_EQ(event.key_code(), ui::VKEY_DOWN); - next_focusable_view = GetFocusManager()->GetNextFocusableView( - GetFocusManager()->GetFocusedView(), GetWidget(), false, false); - } - - if (next_focusable_view && !Contains(next_focusable_view)) { - // Hitting up key when focus is on first search result or hitting down - // key when focus is on last search result should move focus onto search - // box and select all text. - views::Textfield* search_box = - AppListPage::contents_view()->GetSearchBoxView()->search_box(); - search_box->RequestFocus(); - search_box->SelectAll(false); - return true; - } - - // Return false to let FocusManager to handle default focus move by key - // events. + // Let the FocusManager handle Left/Right keys. + if (!CanProcessUpDownKeyTraversal(event)) return false; + + views::View* next_focusable_view = nullptr; + if (event.key_code() == ui::VKEY_UP) { + next_focusable_view = GetFocusManager()->GetNextFocusableView( + GetFocusManager()->GetFocusedView(), GetWidget(), true, false); + } else { + DCHECK_EQ(event.key_code(), ui::VKEY_DOWN); + next_focusable_view = GetFocusManager()->GetNextFocusableView( + GetFocusManager()->GetFocusedView(), GetWidget(), false, false); } - // TODO(weidongg/766807) Remove everything below when the flag is enabled by - // default. - if (HasSelection() && - result_container_views_.at(selected_index_)->OnKeyPressed(event)) { + + if (next_focusable_view && !Contains(next_focusable_view)) { + // Hitting up key when focus is on first search result or hitting down + // key when focus is on last search result should move focus onto search + // box and select all text. + views::Textfield* search_box = + AppListPage::contents_view()->GetSearchBoxView()->search_box(); + search_box->RequestFocus(); + search_box->SelectAll(false); return true; } - int dir = 0; - bool directional_movement = false; - const int forward_dir = base::i18n::IsRTL() ? -1 : 1; - switch (event.key_code()) { - case ui::VKEY_TAB: - dir = event.IsShiftDown() ? -1 : 1; - break; - case ui::VKEY_UP: - dir = -1; - directional_movement = true; - break; - case ui::VKEY_DOWN: - dir = 1; - directional_movement = true; - break; - case ui::VKEY_LEFT: - dir = -forward_dir; - break; - case ui::VKEY_RIGHT: - dir = forward_dir; - break; - default: - return false; - } - - // Find the next result container with results. - int new_selected = selected_index_; - do { - new_selected += dir; - } while (IsValidSelectionIndex(new_selected) && - result_container_views_[new_selected]->num_results() == 0); - - if (IsValidSelectionIndex(new_selected)) { - SetSelectedIndex(new_selected, directional_movement); - return true; - } - - if (dir == -1) { - // Shift+tab/up/left key could move focus back to search box. - ClearSelectedIndex(); - } + // Return false to let FocusManager to handle default focus move by key + // events. return false; } @@ -283,30 +221,6 @@ return gfx::Size(kWidth, kHeight); } -void SearchResultPageView::ClearSelectedIndex() { - if (HasSelection()) - result_container_views_[selected_index_]->ClearSelectedIndex(); - - selected_index_ = -1; -} - -void SearchResultPageView::SetSelectedIndex(int index, - bool directional_movement) { - bool from_bottom = index < selected_index_; - - // Reset the old selected view's selection. - ClearSelectedIndex(); - - selected_index_ = index; - // Set the new selected view's selection to its first result. - result_container_views_[selected_index_]->OnContainerSelected( - from_bottom, directional_movement); -} - -bool SearchResultPageView::IsValidSelectionIndex(int index) { - return index >= 0 && index < static_cast<int>(result_container_views_.size()); -} - void SearchResultPageView::ReorderSearchResultContainers() { // Sort the result container views by their score. std::sort(result_container_views_.begin(), result_container_views_.end(), @@ -354,63 +268,30 @@ } } - if (is_app_list_focus_enabled_) { - if (result_container_views_.empty()) - return; - // Set the first result (if it exists) selected when search results are - // updated. Note that the focus is not set on the first result to prevent - // frequent focus switch between search box and first result during typing - // query. - SearchResultContainerView* old_first_container_view = - result_container_views_[0]; - ReorderSearchResultContainers(); - - views::View* focused_view = GetFocusManager()->GetFocusedView(); - if (first_result_view_ != focused_view) { - // If the old first result is focused, do not clear the selection. (This - // happens when the user moved the focus before search results are - // updated.) - old_first_container_view->SetFirstResultSelected(false); - } - first_result_view_ = result_container_views_[0]->GetFirstResultView(); - if (!Contains(focused_view)) { - // If one of the search result is focused, do not set the first result - // selected. - result_container_views_[0]->SetFirstResultSelected(true); - } + if (result_container_views_.empty()) return; - } - - SearchResultContainerView* old_selection = - HasSelection() ? result_container_views_[selected_index_] : nullptr; - - // Truncate the currently selected container's selection if necessary. If - // there are no results, the selection will be cleared below. - if (old_selection && old_selection->num_results() > 0 && - old_selection->selected_index() >= old_selection->num_results()) { - old_selection->SetSelectedIndex(old_selection->num_results() - 1); - } - + // Set the first result (if it exists) selected when search results are + // updated. Note that the focus is not set on the first result to prevent + // frequent focus switch between search box and first result during typing + // query. + SearchResultContainerView* old_first_container_view = + result_container_views_[0]; ReorderSearchResultContainers(); - SearchResultContainerView* new_selection = nullptr; - if (HasSelection() && - result_container_views_[selected_index_]->num_results() > 0) { - new_selection = result_container_views_[selected_index_]; + views::View* focused_view = GetFocusManager()->GetFocusedView(); + if (first_result_view_ != focused_view) { + // If the old first result is focused, do not clear the selection. (This + // happens when the user moved the focus before search results are + // updated.) + old_first_container_view->SetFirstResultSelected(false); } - - // If there was no previous selection or the new view at the selection index - // is different from the old one, update the selected view. - if (!HasSelection() || old_selection != new_selection) { - if (old_selection) - old_selection->ClearSelectedIndex(); - - int new_selection_index = new_selection ? selected_index_ : 0; - // Clear the current selection so that the selection always comes in from - // the top. - ClearSelectedIndex(); - SetSelectedIndex(new_selection_index, false); + first_result_view_ = result_container_views_[0]->GetFirstResultView(); + if (!Contains(focused_view)) { + // If one of the search result is focused, do not set the first result + // selected. + result_container_views_[0]->SetFirstResultSelected(true); } + return; } gfx::Rect SearchResultPageView::GetPageBoundsForState( @@ -456,10 +337,6 @@ set_clip_path(path); } -void SearchResultPageView::OnHidden() { - ClearSelectedIndex(); -} - gfx::Rect SearchResultPageView::GetSearchBoxBounds() const { gfx::Rect rect(AppListPage::GetSearchBoxBounds()); @@ -469,12 +346,4 @@ return rect; } -views::View* SearchResultPageView::GetSelectedView() const { - if (!HasSelection()) - return nullptr; - SearchResultContainerView* container = - result_container_views_[selected_index_]; - return container->GetSelectedView(); -} - } // namespace app_list
diff --git a/ui/app_list/views/search_result_page_view.h b/ui/app_list/views/search_result_page_view.h index e6a0e3f..1a66385 100644 --- a/ui/app_list/views/search_result_page_view.h +++ b/ui/app_list/views/search_result_page_view.h
@@ -24,10 +24,6 @@ SearchResultPageView(); ~SearchResultPageView() override; - int selected_index() const { return selected_index_; } - bool HasSelection() const { return selected_index_ > -1; } - void SetSelection(bool select); // Set or unset result selection. - void AddSearchResultContainerView( SearchModel::SearchResults* result_model, SearchResultContainerView* result_container); @@ -46,11 +42,7 @@ void OnAnimationUpdated(double progress, AppListModel::State from_state, AppListModel::State to_state) override; - void OnHidden() override; gfx::Rect GetSearchBoxBounds() const override; - views::View* GetSelectedView() const override; - - void ClearSelectedIndex(); // Overridden from SearchResultContainerView::Delegate : void OnSearchResultContainerResultsChanged() override; @@ -63,11 +55,6 @@ // Separator between SearchResultContainerView. class HorizontalSeparator; - // |directional_movement| is true if the navigation was caused by directional - // controls (eg, arrow keys), as opposed to linear controls (eg, Tab). - void SetSelectedIndex(int index, bool directional_movement); - bool IsValidSelectionIndex(int index); - // Sort the result container views. void ReorderSearchResultContainers(); @@ -77,12 +64,6 @@ std::vector<HorizontalSeparator*> separators_; - // -1 indicates no selection. - int selected_index_; - - // Whether the app list focus is enabled. - const bool is_app_list_focus_enabled_; - // View containing SearchCardView instances. Owned by view hierarchy. views::View* const contents_view_;
diff --git a/ui/app_list/views/search_result_page_view_unittest.cc b/ui/app_list/views/search_result_page_view_unittest.cc index 0fa6bf7..33c8646 100644 --- a/ui/app_list/views/search_result_page_view_unittest.cc +++ b/ui/app_list/views/search_result_page_view_unittest.cc
@@ -55,8 +55,6 @@ const AnswerCardState answer_card_state = GetParam(); test_with_answer_card = answer_card_state != AnswerCardState::ANSWER_CARD_OFF; - test_with_answer_card_result_ = - answer_card_state == AnswerCardState::ANSWER_CARD_ON_WITH_RESULT; } // Setting up the feature set. @@ -99,61 +97,6 @@ return delegate_->GetSearchModel()->results(); } - void SetUpSearchResults( - const std::vector<std::pair<SearchResult::DisplayType, int>>& - result_types) { - SearchModel::SearchResults* results = GetResults(); - results->DeleteAll(); - double relevance = result_types.size(); - for (const auto& data : result_types) { - // Set the relevance of the results in each group in decreasing order (so - // the earlier groups have higher relevance, and therefore appear first). - relevance -= 1.0; - for (int i = 0; i < data.second; ++i) { - std::unique_ptr<TestSearchResult> result = - std::make_unique<TestSearchResult>(); - result->set_display_type(data.first); - result->set_relevance(relevance); - results->Add(std::move(result)); - } - } - - // Adding results will schedule Update(). - RunPendingMessages(); - } - - // Add search results for test on focus movement. - void SetUpFocusTestEnv() { - std::vector<std::pair<SearchResult::DisplayType, int>> result_types; - // 3 tile results, followed by 2 list results. - const int kTileResults = 3; - const int kListResults = 2; - const int kNoneResults = 3; - result_types.push_back( - std::make_pair(SearchResult::DISPLAY_TILE, kTileResults)); - result_types.push_back( - std::make_pair(SearchResult::DISPLAY_LIST, kListResults)); - result_types.push_back( - std::make_pair(SearchResult::DISPLAY_NONE, kNoneResults)); - SetUpSearchResults(result_types); - } - - int GetSelectedIndex() const { return view_->selected_index(); } - - bool KeyPress(ui::KeyboardCode key_code) { return KeyPress(key_code, false); } - - bool KeyPress(ui::KeyboardCode key_code, bool shift_down) { - int flags = ui::EF_NONE; - if (shift_down) - flags |= ui::EF_SHIFT_DOWN; - ui::KeyEvent event(ui::ET_KEY_PRESSED, key_code, flags); - return view_->OnKeyPressed(event); - } - - bool test_with_answer_card_result() const { - return test_with_answer_card_result_; - } - private: AppListView* app_list_view_ = nullptr; // Owned by native widget. SearchResultPageView* view_ = nullptr; // Owned by views hierarchy. @@ -161,7 +104,6 @@ nullptr; // Owned by views hierarchy. SearchResultListView* list_view_ = nullptr; // Owned by views hierarchy. std::unique_ptr<AppListTestViewDelegate> delegate_; - bool test_with_answer_card_result_ = true; base::test::ScopedFeatureList scoped_feature_list_; DISALLOW_COPY_AND_ASSIGN(SearchResultPageViewTest); @@ -176,55 +118,6 @@ AnswerCardState::ANSWER_CARD_ON_WITHOUT_RESULT, AnswerCardState::ANSWER_CARD_ON_WITH_RESULT)); -// TODO(crbug.com/766807): Remove the test once new focus model is stable. -TEST_P(SearchResultPageViewTest, DISABLED_TabMovement) { - SetUpFocusTestEnv(); - EXPECT_EQ(0, GetSelectedIndex()); - EXPECT_EQ(0, tile_list_view()->selected_index()); - - // Navigate to the second tile in the tile group. - EXPECT_TRUE(KeyPress(ui::VKEY_TAB)); - EXPECT_EQ(0, GetSelectedIndex()); - EXPECT_EQ(1, tile_list_view()->selected_index()); - EXPECT_EQ(-1, list_view()->selected_index()); - - // Navigate to the list group. - EXPECT_TRUE(KeyPress(ui::VKEY_TAB)); - EXPECT_EQ(0, GetSelectedIndex()); - EXPECT_EQ(2, tile_list_view()->selected_index()); - EXPECT_TRUE(KeyPress(ui::VKEY_TAB)); - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(-1, tile_list_view()->selected_index()); - EXPECT_EQ(0, list_view()->selected_index()); - - // Navigate to the second result in the list view. - EXPECT_TRUE(KeyPress(ui::VKEY_TAB)); - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(1, list_view()->selected_index()); - - // Attempt to navigate off bottom of list items. - EXPECT_FALSE(KeyPress(ui::VKEY_TAB)); - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(1, list_view()->selected_index()); - - // Navigate back to the tile group (should select the last tile result). - EXPECT_TRUE(KeyPress(ui::VKEY_TAB, true)); - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(0, list_view()->selected_index()); - EXPECT_TRUE(KeyPress(ui::VKEY_TAB, true)); - EXPECT_EQ(0, GetSelectedIndex()); - EXPECT_EQ(2, tile_list_view()->selected_index()); - EXPECT_EQ(-1, list_view()->selected_index()); - - // Navigate off top of list. - EXPECT_TRUE(KeyPress(ui::VKEY_TAB, true)); - EXPECT_TRUE(KeyPress(ui::VKEY_TAB, true)); - EXPECT_FALSE(KeyPress(ui::VKEY_TAB, true)); - EXPECT_EQ(-1, GetSelectedIndex()); - EXPECT_EQ(-1, tile_list_view()->selected_index()); - EXPECT_EQ(-1, list_view()->selected_index()); -} - TEST_P(SearchResultPageViewTest, ResultsSorted) { SearchModel::SearchResults* results = GetResults(); @@ -266,184 +159,5 @@ EXPECT_EQ(tile_list_view(), view()->result_container_views()[1]); } -// TODO(crbug.com/766807): Remove the test once the new focus model is stable. -TEST_P(SearchResultPageViewTest, DISABLED_UpdateWithSelection) { - const int kCardResultNum = test_with_answer_card_result() ? 1 : 0; - { - std::vector<std::pair<SearchResult::DisplayType, int>> result_types; - result_types.push_back(std::make_pair(SearchResult::DISPLAY_TILE, 3)); - result_types.push_back(std::make_pair(SearchResult::DISPLAY_LIST, 2)); - result_types.push_back( - std::make_pair(SearchResult::DISPLAY_CARD, kCardResultNum)); - - SetUpSearchResults(result_types); - } - - EXPECT_EQ(0, GetSelectedIndex()); - EXPECT_EQ(0, tile_list_view()->selected_index()); - EXPECT_EQ(-1, list_view()->selected_index()); - - // Navigate to the second result in the list group. - EXPECT_TRUE(KeyPress(ui::VKEY_DOWN)); - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(-1, tile_list_view()->selected_index()); - EXPECT_EQ(0, list_view()->selected_index()); - - EXPECT_TRUE(KeyPress(ui::VKEY_DOWN)); - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(-1, tile_list_view()->selected_index()); - EXPECT_EQ(1, list_view()->selected_index()); - - { - std::vector<std::pair<SearchResult::DisplayType, int>> result_types; - result_types.push_back(std::make_pair(SearchResult::DISPLAY_TILE, 3)); - result_types.push_back(std::make_pair(SearchResult::DISPLAY_LIST, 3)); - result_types.push_back( - std::make_pair(SearchResult::DISPLAY_CARD, kCardResultNum)); - - SetUpSearchResults(result_types); - } - - // The second list result should still be selected after the update. - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(-1, tile_list_view()->selected_index()); - EXPECT_EQ(1, list_view()->selected_index()); - - { - std::vector<std::pair<SearchResult::DisplayType, int>> result_types; - result_types.push_back(std::make_pair(SearchResult::DISPLAY_TILE, 3)); - result_types.push_back(std::make_pair(SearchResult::DISPLAY_LIST, 1)); - result_types.push_back( - std::make_pair(SearchResult::DISPLAY_CARD, kCardResultNum)); - - SetUpSearchResults(result_types); - } - - // The first list result should be selected after the update as the second - // result has vanished. - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(-1, tile_list_view()->selected_index()); - EXPECT_EQ(0, list_view()->selected_index()); - - { - std::vector<std::pair<SearchResult::DisplayType, int>> result_types; - result_types.push_back(std::make_pair(SearchResult::DISPLAY_LIST, 1)); - result_types.push_back(std::make_pair(SearchResult::DISPLAY_TILE, 3)); - result_types.push_back( - std::make_pair(SearchResult::DISPLAY_CARD, kCardResultNum)); - - SetUpSearchResults(result_types); - } - - // The tile container should be selected because we hold the selected - // container index constant. - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(0, tile_list_view()->selected_index()); - EXPECT_EQ(-1, list_view()->selected_index()); - - { - std::vector<std::pair<SearchResult::DisplayType, int>> result_types; - result_types.push_back(std::make_pair(SearchResult::DISPLAY_LIST, 3)); - result_types.push_back( - std::make_pair(SearchResult::DISPLAY_CARD, kCardResultNum)); - - SetUpSearchResults(result_types); - } - - // The selected container has vanished so we reset the selection to 0. - EXPECT_EQ(0, GetSelectedIndex()); - EXPECT_EQ(-1, tile_list_view()->selected_index()); - EXPECT_EQ(0, list_view()->selected_index()); -} - -using SearchResultPageViewFullscreenTest = SearchResultPageViewTest; - -// TODO(crbug.com/766807): Remove the test once the new focus model is stable. -TEST_F(SearchResultPageViewFullscreenTest, DISABLED_LeftRightMovement) { - SetUpFocusTestEnv(); - EXPECT_EQ(0, GetSelectedIndex()); - EXPECT_EQ(0, tile_list_view()->selected_index()); - EXPECT_EQ(-1, list_view()->selected_index()); - - // Navigate to the second tile in the tile group. - EXPECT_TRUE(KeyPress(ui::VKEY_RIGHT)); - EXPECT_EQ(0, GetSelectedIndex()); - EXPECT_EQ(1, tile_list_view()->selected_index()); - EXPECT_EQ(-1, list_view()->selected_index()); - - // Navigate to the list group. - EXPECT_TRUE(KeyPress(ui::VKEY_RIGHT)); - EXPECT_TRUE(KeyPress(ui::VKEY_RIGHT)); - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(-1, tile_list_view()->selected_index()); - EXPECT_EQ(0, list_view()->selected_index()); - - // Navigate to the second result in the list view. - EXPECT_TRUE(KeyPress(ui::VKEY_RIGHT)); - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(1, list_view()->selected_index()); - - // Attempt to navigate off bottom of list items. - EXPECT_FALSE(KeyPress(ui::VKEY_RIGHT)); - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(1, list_view()->selected_index()); - - // Navigate back to the tile group (should select the last tile result). - EXPECT_TRUE(KeyPress(ui::VKEY_LEFT)); - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(0, list_view()->selected_index()); - EXPECT_TRUE(KeyPress(ui::VKEY_LEFT)); - EXPECT_EQ(0, GetSelectedIndex()); - EXPECT_EQ(2, tile_list_view()->selected_index()); - EXPECT_EQ(-1, list_view()->selected_index()); - - // Navigate off top of list. - EXPECT_TRUE(KeyPress(ui::VKEY_LEFT)); - EXPECT_TRUE(KeyPress(ui::VKEY_LEFT)); - EXPECT_FALSE(KeyPress(ui::VKEY_LEFT)); - EXPECT_EQ(-1, GetSelectedIndex()); - EXPECT_EQ(-1, tile_list_view()->selected_index()); - EXPECT_EQ(-1, list_view()->selected_index()); -} - -// TODO(crbug.com/766807): Remove the test once the new focus model is stable. -TEST_F(SearchResultPageViewFullscreenTest, DISABLED_UpDownMovement) { - SetUpFocusTestEnv(); - EXPECT_EQ(0, GetSelectedIndex()); - EXPECT_EQ(0, tile_list_view()->selected_index()); - EXPECT_EQ(-1, list_view()->selected_index()); - - // Navigate to the first result in the list view. - EXPECT_TRUE(KeyPress(ui::VKEY_DOWN)); - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(-1, tile_list_view()->selected_index()); - EXPECT_EQ(0, list_view()->selected_index()); - - // Navigate to the second result in the list view. - EXPECT_TRUE(KeyPress(ui::VKEY_DOWN)); - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(1, list_view()->selected_index()); - - // Attempt to navigate off bottom of list items. - EXPECT_FALSE(KeyPress(ui::VKEY_DOWN)); - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(1, list_view()->selected_index()); - - // Navigate back to the tile group (should select the first tile result). - EXPECT_TRUE(KeyPress(ui::VKEY_UP)); - EXPECT_EQ(1, GetSelectedIndex()); - EXPECT_EQ(0, list_view()->selected_index()); - EXPECT_TRUE(KeyPress(ui::VKEY_UP)); - EXPECT_EQ(0, GetSelectedIndex()); - EXPECT_EQ(0, tile_list_view()->selected_index()); - EXPECT_EQ(-1, list_view()->selected_index()); - - // Navigate off top of list. - EXPECT_FALSE(KeyPress(ui::VKEY_UP)); - EXPECT_EQ(-1, GetSelectedIndex()); - EXPECT_EQ(-1, tile_list_view()->selected_index()); - EXPECT_EQ(-1, list_view()->selected_index()); -} - } // namespace test } // namespace app_list
diff --git a/ui/app_list/views/search_result_tile_item_list_view.cc b/ui/app_list/views/search_result_tile_item_list_view.cc index b2ed326..5b87124 100644 --- a/ui/app_list/views/search_result_tile_item_list_view.cc +++ b/ui/app_list/views/search_result_tile_item_list_view.cc
@@ -166,90 +166,37 @@ } bool SearchResultTileItemListView::OnKeyPressed(const ui::KeyEvent& event) { - if (features::IsAppListFocusEnabled()) { - // Let the FocusManager handle Left/Right keys. - if (!CanProcessUpDownKeyTraversal(event)) - return false; + // Let the FocusManager handle Left/Right keys. + if (!CanProcessUpDownKeyTraversal(event)) + return false; - views::View* next_focusable_view = nullptr; + views::View* next_focusable_view = nullptr; - // Since search result tile item views have horizontal layout, hitting - // up/down when one of them is focused moves focus to the previous/next - // search result container. - if (event.key_code() == ui::VKEY_UP) { - next_focusable_view = GetFocusManager()->GetNextFocusableView( - tile_views_.front(), GetWidget(), true, false); - if (!search_result_page_view_->Contains(next_focusable_view)) { - // Focus should be moved to search box when it is moved outside search - // result page view. - search_box_->RequestFocus(); - return true; - } - } else { - DCHECK_EQ(event.key_code(), ui::VKEY_DOWN); - next_focusable_view = GetFocusManager()->GetNextFocusableView( - tile_views_.back(), GetWidget(), false, false); - } - - if (next_focusable_view) { - next_focusable_view->RequestFocus(); + // Since search result tile item views have horizontal layout, hitting + // up/down when one of them is focused moves focus to the previous/next + // search result container. + if (event.key_code() == ui::VKEY_UP) { + next_focusable_view = GetFocusManager()->GetNextFocusableView( + tile_views_.front(), GetWidget(), true, false); + if (!search_result_page_view_->Contains(next_focusable_view)) { + // Focus should be moved to search box when it is moved outside search + // result page view. + search_box_->RequestFocus(); return true; } - - // Return false to let FocusManager to handle default focus move by key - // events. - return false; + } else { + DCHECK_EQ(event.key_code(), ui::VKEY_DOWN); + next_focusable_view = GetFocusManager()->GetNextFocusableView( + tile_views_.back(), GetWidget(), false, false); } - // TODO(weidongg/766807) Remove everything below when the flag is enabled by - // default. - int selection_index = selected_index(); - // Also count the separator when Play Store app search feature is enabled. - const int child_index = is_play_store_app_search_enabled_ - ? selection_index * 2 + 1 - : selection_index; - if (selection_index >= 0 && child_at(child_index)->OnKeyPressed(event)) - return true; - int dir = 0; - bool cursor_at_end_of_searchbox = - search_box_->GetCursorPosition() == search_box_->text().length(); - const int forward_dir = base::i18n::IsRTL() ? -1 : 1; - switch (event.key_code()) { - case ui::VKEY_TAB: - if (event.IsShiftDown()) - dir = -1; - else - dir = 1; - break; - case ui::VKEY_LEFT: - // The left key will not capture the key event when the selection is at - // the beginning of the list. This means that the text cursor in the - // search box will be allowed to handle the keypress. This will also - // ignore the keypress if the user has clicked somewhere in the middle of - // the searchbox. In fullscreen app list, the cursor will be moved only - // when search box is selected. - if (cursor_at_end_of_searchbox) - dir = -forward_dir; - break; - case ui::VKEY_RIGHT: - // Only move right if the search box text cursor is at the end of the - // text. In fullscreen app list, the cursor will be moved only when search - // box is selected. - if (cursor_at_end_of_searchbox) - dir = forward_dir; - break; - default: - break; - } - if (dir == 0) - return false; - - selection_index = selection_index + dir; - if (IsValidSelectionIndex(selection_index)) { - SetSelectedIndex(selection_index); + if (next_focusable_view) { + next_focusable_view->RequestFocus(); return true; } + // Return false to let FocusManager to handle default focus move by key + // events. return false; }
diff --git a/ui/app_list/views/search_result_tile_item_list_view_unittest.cc b/ui/app_list/views/search_result_tile_item_list_view_unittest.cc index dc3e039..2065a0c 100644 --- a/ui/app_list/views/search_result_tile_item_list_view_unittest.cc +++ b/ui/app_list/views/search_result_tile_item_list_view_unittest.cc
@@ -114,10 +114,6 @@ int GetResultCount() const { return view_->num_results(); } - int GetSelectedIndex() const { return view_->selected_index(); } - - void ResetSelectedIndex() const { view_->SetSelectedIndex(0); } - bool KeyPress(ui::KeyboardCode key_code) { ui::KeyEvent event(ui::ET_KEY_PRESSED, key_code, ui::EF_NONE); return view_->OnKeyPressed(event); @@ -174,38 +170,12 @@ node_data.GetStringAttribute(ui::AX_ATTR_NAME)); } - if (features::IsAppListFocusEnabled()) { - ResetOpenResultCount(); - for (int i = 0; i < results; ++i) { - ui::KeyEvent event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE); - for (int j = 0; j <= i; ++j) - view()->tile_views_for_test()[i]->OnKeyEvent(&event); - EXPECT_EQ(i + 1, GetOpenResultCount(i)); - } - return; - } - // TODO(crbug.com/766807): Remove the selection test below once the new focus - // model is stable. - - // Tests item indexing by pressing TAB. - for (int i = 1; i < results; ++i) { - EXPECT_TRUE(KeyPress(ui::VKEY_TAB)); - EXPECT_EQ(i, GetSelectedIndex()); - } - - // Extra TAB events won't be handled by the view. - EXPECT_FALSE(KeyPress(ui::VKEY_TAB)); - EXPECT_EQ(results - 1, GetSelectedIndex()); - - // Tests app opening. - ResetSelectedIndex(); ResetOpenResultCount(); - for (int i = 1; i < results; ++i) { - EXPECT_TRUE(KeyPress(ui::VKEY_TAB)); - EXPECT_EQ(i, GetSelectedIndex()); - for (int j = 0; j < i; j++) - EXPECT_TRUE(KeyPress(ui::VKEY_RETURN)); - EXPECT_EQ(i, GetOpenResultCount(i)); + for (int i = 0; i < results; ++i) { + ui::KeyEvent event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE); + for (int j = 0; j <= i; ++j) + view()->tile_views_for_test()[i]->OnKeyEvent(&event); + EXPECT_EQ(i + 1, GetOpenResultCount(i)); } }
diff --git a/ui/base/cursor/cursors_aura.cc b/ui/base/cursor/cursors_aura.cc index d7dadd8b..fbefd76 100644 --- a/ui/base/cursor/cursors_aura.cc +++ b/ui/base/cursor/cursors_aura.cc
@@ -79,7 +79,7 @@ {CursorType::kAlias, IDR_AURA_CURSOR_ALIAS, {8, 6}, {15, 11}}, {CursorType::kCell, IDR_AURA_CURSOR_CELL, {11, 11}, {24, 23}}, {CursorType::kContextMenu, IDR_AURA_CURSOR_CONTEXT_MENU, {4, 4}, {8, 9}}, - {CursorType::kCross, IDR_AURA_CURSOR_CROSSHAIR, {12, 12}, {25, 23}}, + {CursorType::kCross, IDR_AURA_CURSOR_CROSSHAIR, {12, 12}, {24, 24}}, {CursorType::kHelp, IDR_AURA_CURSOR_HELP, {4, 4}, {8, 9}}, {CursorType::kVerticalText, IDR_AURA_CURSOR_XTERM_HORIZ, @@ -161,7 +161,7 @@ IDR_AURA_CURSOR_BIG_CONTEXT_MENU, {11, 11}, {22, 22}}, - {CursorType::kCross, IDR_AURA_CURSOR_BIG_CROSSHAIR, {31, 30}, {62, 60}}, + {CursorType::kCross, IDR_AURA_CURSOR_BIG_CROSSHAIR, {30, 32}, {60, 64}}, {CursorType::kHelp, IDR_AURA_CURSOR_BIG_HELP, {10, 11}, {20, 22}}, {CursorType::kVerticalText, IDR_AURA_CURSOR_BIG_XTERM_HORIZ,
diff --git a/ui/resources/default_100_percent/common/pointers/crosshair.png b/ui/resources/default_100_percent/common/pointers/crosshair.png index 8a06c77..a1c55ab 100644 --- a/ui/resources/default_100_percent/common/pointers/crosshair.png +++ b/ui/resources/default_100_percent/common/pointers/crosshair.png Binary files differ
diff --git a/ui/resources/default_100_percent/common/pointers/crosshair_big.png b/ui/resources/default_100_percent/common/pointers/crosshair_big.png index ea1f5fc..99f8746 100644 --- a/ui/resources/default_100_percent/common/pointers/crosshair_big.png +++ b/ui/resources/default_100_percent/common/pointers/crosshair_big.png Binary files differ
diff --git a/ui/resources/default_200_percent/common/pointers/crosshair.png b/ui/resources/default_200_percent/common/pointers/crosshair.png index 86c649c..8f5dca51 100644 --- a/ui/resources/default_200_percent/common/pointers/crosshair.png +++ b/ui/resources/default_200_percent/common/pointers/crosshair.png Binary files differ