diff --git a/AUTHORS b/AUTHORS index 6703fd7c..5dac9b0 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -316,6 +316,7 @@ Jake Hendy <me@jakehendy.com> Jakob Weigert <jakob.j.w@googlemail.com> Jakub Machacek <xtreit@gmail.com> +James Burton <jb@0.me.uk> James Choi <jchoi42@pha.jhu.edu> James Stanley <james@apphaus.co.uk> James Vega <vega.james@gmail.com>
diff --git a/DEPS b/DEPS index 6bb9bff..2ebfe06 100644 --- a/DEPS +++ b/DEPS
@@ -347,10 +347,6 @@ 'src/third_party/mingw-w64/mingw/bin': Var('chromium_git') + '/native_client/deps/third_party/mingw-w64/mingw/bin.git' + '@' + '3cc8b140b883a9fe4986d12cfd46c16a093d3527', - # Dependencies used by libjpeg-turbo - 'src/third_party/yasm/binaries': - Var('chromium_git') + '/chromium/deps/yasm/binaries.git' + '@' + '52f9b3f4b0aa06da24ef8b123058bb61ee468881', - # Binaries for nacl sdk. 'src/third_party/nacl_sdk_binaries': Var('chromium_git') + '/chromium/deps/nacl_sdk_binaries.git' + '@' + '759dfca03bdc774da7ecbf974f6e2b84f43699a5',
diff --git a/ash/frame/caption_buttons/frame_caption_button.cc b/ash/frame/caption_buttons/frame_caption_button.cc index e3bd36e5..d091e72 100644 --- a/ash/frame/caption_buttons/frame_caption_button.cc +++ b/ash/frame/caption_buttons/frame_caption_button.cc
@@ -124,6 +124,10 @@ CustomButton::OnGestureEvent(event); } +views::PaintInfo::ScaleType FrameCaptionButton::GetPaintScaleType() const { + return views::PaintInfo::ScaleType::kScaleToScaleFactor; +} + void FrameCaptionButton::PaintButtonContents(gfx::Canvas* canvas) { SkAlpha bg_alpha = SK_AlphaTRANSPARENT; if (hover_animation().is_animating())
diff --git a/ash/frame/caption_buttons/frame_caption_button.h b/ash/frame/caption_buttons/frame_caption_button.h index 2d05f6ed..4d369a225 100644 --- a/ash/frame/caption_buttons/frame_caption_button.h +++ b/ash/frame/caption_buttons/frame_caption_button.h
@@ -49,6 +49,7 @@ // views::View overrides: const char* GetClassName() const override; void OnGestureEvent(ui::GestureEvent* event) override; + views::PaintInfo::ScaleType GetPaintScaleType() const override; void set_paint_as_active(bool paint_as_active) { paint_as_active_ = paint_as_active;
diff --git a/ash/shelf/voice_interaction_overlay.cc b/ash/shelf/voice_interaction_overlay.cc index ef03f42..1a4d07e 100644 --- a/ash/shelf/voice_interaction_overlay.cc +++ b/ash/shelf/voice_interaction_overlay.cc
@@ -19,6 +19,7 @@ #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/tray/tray_popup_utils.h" +#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "base/command_line.h" #include "base/memory/ptr_util.h" #include "base/metrics/user_metrics.h" @@ -655,10 +656,14 @@ transform.Scale(scale_factor, scale_factor); icon_layer_->SetTransform(transform); + const bool is_tablet_mode = Shell::Get() + ->tablet_mode_controller() + ->IsTabletModeWindowManagerEnabled(); + const int icon_x_offset = is_tablet_mode ? 0 : kIconOffsetDip; // Setup icon animation. scale_factor = kIconSizeDip / kIconInitSizeDip; transform.MakeIdentity(); - transform.Translate(center.x() - kIconSizeDip / 2 + kIconOffsetDip, + transform.Translate(center.x() - kIconSizeDip / 2 + icon_x_offset, center.y() - kIconSizeDip / 2 - kIconOffsetDip); transform.Scale(scale_factor, scale_factor); @@ -686,7 +691,7 @@ // Setup background animation. scale_factor = kBackgroundSizeDip / kBackgroundInitSizeDip; transform.MakeIdentity(); - transform.Translate(center.x() - kBackgroundSizeDip / 2 + kIconOffsetDip, + transform.Translate(center.x() - kBackgroundSizeDip / 2 + icon_x_offset, center.y() - kBackgroundSizeDip / 2 - kIconOffsetDip); transform.Scale(scale_factor, scale_factor); @@ -769,7 +774,11 @@ // We want to animate from the background's current position into a larger // size. The animation moves the background's center point while morphing from // circle to a rectangle. - float x_offset = center.x() - kBackgroundSizeDip / 2 + kIconOffsetDip; + const bool is_tablet_mode = Shell::Get() + ->tablet_mode_controller() + ->IsTabletModeWindowManagerEnabled(); + const int icon_x_offset = is_tablet_mode ? 0 : kIconOffsetDip; + float x_offset = center.x() - kBackgroundSizeDip / 2 + icon_x_offset; float y_offset = center.y() - kBackgroundSizeDip / 2 - kIconOffsetDip; background_layer_->AnimateToLarge(
diff --git a/ash/shell/shell_delegate_impl.cc b/ash/shell/shell_delegate_impl.cc index 4e83767..7c76c75 100644 --- a/ash/shell/shell_delegate_impl.cc +++ b/ash/shell/shell_delegate_impl.cc
@@ -11,6 +11,8 @@ #include "ash/keyboard/test_keyboard_ui.h" #include "ash/palette_delegate.h" #include "ash/public/cpp/shell_window_ids.h" +#include "ash/root_window_controller.h" +#include "ash/shelf/shelf.h" #include "ash/shell.h" #include "ash/shell/context_menu.h" #include "ash/shell/example_factory.h" @@ -102,7 +104,11 @@ void ShellDelegateImpl::OpenUrlFromArc(const GURL& url) {} -void ShellDelegateImpl::ShelfInit() {} +void ShellDelegateImpl::ShelfInit() { + Shelf* shelf = Shell::GetPrimaryRootWindowController()->shelf(); + shelf->SetAlignment(SHELF_ALIGNMENT_BOTTOM); + shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); +} void ShellDelegateImpl::ShelfShutdown() {}
diff --git a/ash/shell/window_watcher.cc b/ash/shell/window_watcher.cc index 70f38a6..a4ed5b0c 100644 --- a/ash/shell/window_watcher.cc +++ b/ash/shell/window_watcher.cc
@@ -16,11 +16,19 @@ #include "ash/wm/window_util.h" #include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" +#include "third_party/skia/include/core/SkColor.h" #include "ui/aura/window.h" namespace ash { namespace shell { +namespace { + +constexpr int kContainerIds[] = {kShellWindowId_DefaultContainer, + kShellWindowId_PanelContainer}; + +} // namespace + class WindowWatcher::WorkspaceWindowWatcher : public aura::WindowObserver { public: explicit WorkspaceWindowWatcher(WindowWatcher* watcher) : watcher_(watcher) {} @@ -37,27 +45,21 @@ } void RootWindowAdded(aura::Window* root) { - aura::Window* panel_container = - Shell::GetContainer(root, kShellWindowId_PanelContainer); - panel_container->AddObserver(watcher_); - - aura::Window* container = - Shell::GetContainer(root, kShellWindowId_ShelfContainer); - container->AddObserver(this); - for (size_t i = 0; i < container->children().size(); ++i) - container->children()[i]->AddObserver(watcher_); + for (const int container_id : kContainerIds) { + aura::Window* container = root->GetChildById(container_id); + container->AddObserver(watcher_); + for (aura::Window* window : container->children()) + watcher_->OnWindowAdded(window); + } } void RootWindowRemoved(aura::Window* root) { - aura::Window* panel_container = - Shell::GetContainer(root, kShellWindowId_PanelContainer); - panel_container->RemoveObserver(watcher_); - - aura::Window* container = - Shell::GetContainer(root, kShellWindowId_ShelfContainer); - container->RemoveObserver(this); - for (size_t i = 0; i < container->children().size(); ++i) - container->children()[i]->RemoveObserver(watcher_); + for (const int container_id : kContainerIds) { + aura::Window* container = root->GetChildById(container_id); + container->RemoveObserver(watcher_); + for (aura::Window* window : container->children()) + watcher_->OnWillRemoveWindow(window); + } } private: @@ -69,19 +71,13 @@ WindowWatcher::WindowWatcher() { Shell::Get()->AddShellObserver(this); workspace_window_watcher_ = base::MakeUnique<WorkspaceWindowWatcher>(this); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - for (aura::Window::Windows::iterator iter = root_windows.begin(); - iter != root_windows.end(); ++iter) { - workspace_window_watcher_->RootWindowAdded(*iter); - } + for (aura::Window* root : Shell::GetAllRootWindows()) + workspace_window_watcher_->RootWindowAdded(root); } WindowWatcher::~WindowWatcher() { - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - for (aura::Window::Windows::iterator iter = root_windows.begin(); - iter != root_windows.end(); ++iter) { - workspace_window_watcher_->RootWindowRemoved(*iter); - } + for (aura::Window* root : Shell::GetAllRootWindows()) + workspace_window_watcher_->RootWindowRemoved(root); Shell::Get()->RemoveShellObserver(this); } @@ -95,7 +91,6 @@ if (!wm::IsWindowUserPositionable(new_window)) return; - static int image_count = 0; ShelfModel* model = Shell::Get()->shelf_model(); ShelfItem item; item.type = new_window->type() == aura::client::WINDOW_TYPE_PANEL @@ -107,12 +102,10 @@ SkBitmap icon_bitmap; icon_bitmap.allocN32Pixels(16, 16); - icon_bitmap.eraseARGB(255, image_count == 0 ? 255 : 0, - image_count == 1 ? 255 : 0, image_count == 2 ? 255 : 0); - image_count = (image_count + 1) % 3; + constexpr SkColor colors[] = {SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE}; + icon_bitmap.eraseColor(colors[shelf_id % 3]); item.image = gfx::ImageSkia(gfx::ImageSkiaRep(icon_bitmap, 1.0f)); - item.title = new_window->GetTitle(); - + item.title = base::IntToString16(shelf_id); model->Add(item); model->SetShelfItemDelegate(
diff --git a/ash/shell/window_watcher.h b/ash/shell/window_watcher.h index 541d6d7..2b7147b1 100644 --- a/ash/shell/window_watcher.h +++ b/ash/shell/window_watcher.h
@@ -16,10 +16,6 @@ #include "base/macros.h" #include "ui/aura/window_observer.h" -namespace aura { -class Window; -} - namespace ash { namespace shell {
diff --git a/base/process/process_fuchsia.cc b/base/process/process_fuchsia.cc index ec16e28..e48d7af 100644 --- a/base/process/process_fuchsia.cc +++ b/base/process/process_fuchsia.cc
@@ -126,7 +126,7 @@ } bool Process::Terminate(int exit_code, bool wait) const { - // exit_code isn't supportable. + // exit_code isn't supportable. https://crbug.com/753490. mx_status_t status = mx_task_kill(process_.get()); // TODO(scottmg): Put these LOG/CHECK back to DLOG/DCHECK after // https://crbug.com/750756 is diagnosed.
diff --git a/cc/ipc/BUILD.gn b/cc/ipc/BUILD.gn index 3a267f92..e9d087d 100644 --- a/cc/ipc/BUILD.gn +++ b/cc/ipc/BUILD.gn
@@ -53,7 +53,6 @@ "shared_bitmap_allocation_notifier.mojom", "shared_quad_state.mojom", "surface_id.mojom", - "surface_sequence.mojom", "texture_mailbox.mojom", "texture_mailbox_releaser.mojom", "transferable_resource.mojom",
diff --git a/cc/ipc/struct_traits_unittest.cc b/cc/ipc/struct_traits_unittest.cc index 0586f98..9b57eb0 100644 --- a/cc/ipc/struct_traits_unittest.cc +++ b/cc/ipc/struct_traits_unittest.cc
@@ -97,11 +97,6 @@ std::move(callback).Run(s); } - void EchoSurfaceSequence(const viz::SurfaceSequence& s, - EchoSurfaceSequenceCallback callback) override { - std::move(callback).Run(s); - } - void EchoTextureMailbox(const viz::TextureMailbox& t, EchoTextureMailboxCallback callback) override { std::move(callback).Run(t); @@ -874,17 +869,6 @@ EXPECT_EQ(local_surface_id, output.local_surface_id()); } -TEST_F(StructTraitsTest, SurfaceSequence) { - const viz::FrameSinkId frame_sink_id(2016, 1234); - const uint32_t sequence = 0xfbadbeef; - viz::SurfaceSequence input(frame_sink_id, sequence); - mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy(); - viz::SurfaceSequence output; - proxy->EchoSurfaceSequence(input, &output); - EXPECT_EQ(frame_sink_id, output.frame_sink_id); - EXPECT_EQ(sequence, output.sequence); -} - TEST_F(StructTraitsTest, SharedQuadState) { const gfx::Transform quad_to_target_transform(1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f,
diff --git a/cc/ipc/surface_sequence.typemap b/cc/ipc/surface_sequence.typemap deleted file mode 100644 index e05d72e..0000000 --- a/cc/ipc/surface_sequence.typemap +++ /dev/null
@@ -1,11 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = "//cc/ipc/surface_sequence.mojom" -public_headers = [ "//components/viz/common/surfaces/surface_sequence.h" ] -traits_headers = [ "//cc/ipc/surface_sequence_struct_traits.h" ] -deps = [ - "//components/viz/common", -] -type_mappings = [ "cc.mojom.SurfaceSequence=viz::SurfaceSequence" ]
diff --git a/cc/ipc/traits_test_service.mojom b/cc/ipc/traits_test_service.mojom index d38c0d752..0f5f3cca 100644 --- a/cc/ipc/traits_test_service.mojom +++ b/cc/ipc/traits_test_service.mojom
@@ -15,7 +15,6 @@ import "cc/ipc/selection.mojom"; import "cc/ipc/shared_quad_state.mojom"; import "cc/ipc/surface_id.mojom"; -import "cc/ipc/surface_sequence.mojom"; import "cc/ipc/texture_mailbox.mojom"; import "cc/ipc/transferable_resource.mojom"; @@ -57,9 +56,6 @@ EchoSurfaceId(SurfaceId s) => (SurfaceId pass); [Sync] - EchoSurfaceSequence(SurfaceSequence s) => (SurfaceSequence pass); - - [Sync] EchoTextureMailbox(TextureMailbox t) => (TextureMailbox pass);
diff --git a/cc/ipc/typemaps.gni b/cc/ipc/typemaps.gni index f6963c4e..bbbcdc7 100644 --- a/cc/ipc/typemaps.gni +++ b/cc/ipc/typemaps.gni
@@ -15,7 +15,6 @@ "//cc/ipc/selection.typemap", "//cc/ipc/shared_quad_state.typemap", "//cc/ipc/surface_id.typemap", - "//cc/ipc/surface_sequence.typemap", "//cc/ipc/texture_mailbox.typemap", "//cc/ipc/transferable_resource.typemap", ]
diff --git a/cc/quads/draw_polygon.cc b/cc/quads/draw_polygon.cc index 43642fa..98da20ec 100644 --- a/cc/quads/draw_polygon.cc +++ b/cc/quads/draw_polygon.cc
@@ -9,7 +9,6 @@ #include <vector> #include "base/memory/ptr_util.h" -#include "cc/output/bsp_compare_result.h" #include "cc/quads/draw_quad.h" namespace {
diff --git a/cc/quads/draw_polygon.h b/cc/quads/draw_polygon.h index 351d3cb..34625dc 100644 --- a/cc/quads/draw_polygon.h +++ b/cc/quads/draw_polygon.h
@@ -9,7 +9,6 @@ #include "cc/base/math_util.h" #include "cc/cc_export.h" -#include "cc/output/bsp_compare_result.h" #include "ui/gfx/geometry/point3_f.h" #include "ui/gfx/geometry/quad_f.h" #include "ui/gfx/geometry/rect_f.h"
diff --git a/cc/quads/draw_quad.cc b/cc/quads/draw_quad.cc index d5edffeb..76141d0 100644 --- a/cc/quads/draw_quad.cc +++ b/cc/quads/draw_quad.cc
@@ -11,15 +11,6 @@ #include "base/values.h" #include "cc/base/math_util.h" #include "cc/debug/traced_value.h" -#include "cc/quads/debug_border_draw_quad.h" -#include "cc/quads/picture_draw_quad.h" -#include "cc/quads/render_pass_draw_quad.h" -#include "cc/quads/solid_color_draw_quad.h" -#include "cc/quads/stream_video_draw_quad.h" -#include "cc/quads/surface_draw_quad.h" -#include "cc/quads/texture_draw_quad.h" -#include "cc/quads/tile_draw_quad.h" -#include "cc/quads/yuv_video_draw_quad.h" #include "ui/gfx/geometry/quad_f.h" namespace cc {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index 0db0159..a460ba0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -148,6 +148,7 @@ import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetContentController; import org.chromium.chrome.browser.widget.bottomsheet.EmptyBottomSheetObserver; import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager; +import org.chromium.chrome.browser.widget.textbubble.TextBubble; import org.chromium.components.bookmarks.BookmarkId; import org.chromium.content.browser.ContentVideoView; import org.chromium.content.browser.ContentViewCore; @@ -1839,6 +1840,8 @@ @Override public final void onBackPressed() { if (mNativeInitialized) RecordUserAction.record("SystemBack"); + + TextBubble.onBackPressed(); if (VrShellDelegate.onBackPressed()) return; if (mCompositorViewHolder != null) { LayoutManager layoutManager = mCompositorViewHolder.getLayoutManager();
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 2ac057a..257a7a6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -215,6 +215,13 @@ /** The task id of the activity that tabs were merged into. */ private static int sMergedInstanceTaskId; + /** + * Time in ms from when we last backgrounded Chrome until we show the bottom sheet at half. + * Time is 3 hours. + * crbug.com/706258 + */ + private static final long TIME_SINCE_BACKGROUNDED_TO_SHOW_BOTTOM_SHEET_HALF_MS = 10800000L; + private final ActivityStopMetrics mActivityStopMetrics; private final MainIntentBehaviorMetrics mMainIntentMetrics; @@ -656,7 +663,7 @@ super.onNewIntentWithNative(intent); if (isMainIntentFromLauncher(intent)) { if (IntentHandler.getUrlFromIntent(intent) == null) { - maybeLaunchNtpFromMainIntent(intent); + maybeLaunchNtpOrResetBottomSheetFromMainIntent(intent); } logMainIntentBehavior(intent); } @@ -837,9 +844,7 @@ private void logMainIntentBehavior(Intent intent) { assert isMainIntentFromLauncher(intent); long currentTime = System.currentTimeMillis(); - long lastBackgroundedTimeMs = ContextUtils.getAppSharedPreferences().getLong( - LAST_BACKGROUNDED_TIME_MS_PREF, currentTime); - mMainIntentMetrics.onMainIntentWithNative(currentTime - lastBackgroundedTimeMs); + mMainIntentMetrics.onMainIntentWithNative(currentTime - getTimeSinceLastBackgroundedMs()); } /** Access the main intent metrics for test validation. */ @@ -849,16 +854,23 @@ } /** - * Determines if the intent should trigger an NTP and launches it if applicable. + * Determines if the intent should trigger an NTP and launches it if applicable. If Chrome Home + * is enabled, we reset the bottom sheet state to half after some time being backgrounded. * * @param intent The intent to check whether an NTP should be triggered. * @return Whether an NTP was triggered as a result of this intent. */ - private boolean maybeLaunchNtpFromMainIntent(Intent intent) { + private boolean maybeLaunchNtpOrResetBottomSheetFromMainIntent(Intent intent) { assert isMainIntentFromLauncher(intent); if (!mIntentHandler.isIntentUserVisible()) return false; - if (FeatureUtilities.isChromeHomeEnabled()) return false; + + if (FeatureUtilities.isChromeHomeEnabled()) { + BottomSheet bottomSheet = getBottomSheet(); + assert bottomSheet != null; + maybeSetBottomSheetStateToHalfOnStartup(bottomSheet); + return false; + } if (!ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_LAUNCH_AFTER_INACTIVITY)) { return false; @@ -915,6 +927,26 @@ return true; } + private boolean maybeSetBottomSheetStateToHalfOnStartup(BottomSheet bottomSheet) { + if (getTimeSinceLastBackgroundedMs() + >= TIME_SINCE_BACKGROUNDED_TO_SHOW_BOTTOM_SHEET_HALF_MS) { + bottomSheet.getBottomSheetMetrics().recordSheetOpenReason( + BottomSheetMetrics.OPENED_BY_STARTUP); + bottomSheet.setSheetState(BottomSheet.SHEET_STATE_HALF, true); + return true; + } + return false; + } + + /** + * Returns the number of milliseconds since Chrome was last backgrounded. + */ + private long getTimeSinceLastBackgroundedMs() { + long lastBackgroundedTimeMs = + ContextUtils.getAppSharedPreferences().getLong(LAST_BACKGROUNDED_TIME_MS_PREF, -1); + return System.currentTimeMillis() - lastBackgroundedTimeMs; + } + @Override public void initializeState() { // This method goes through 3 steps: @@ -969,7 +1001,7 @@ if (IntentHandler.getUrlFromIntent(intent) == null) { assert !mIntentWithEffect : "ACTION_MAIN should not have triggered any prior action"; - mIntentWithEffect = maybeLaunchNtpFromMainIntent(intent); + mIntentWithEffect = maybeLaunchNtpOrResetBottomSheetFromMainIntent(intent); } logMainIntentBehavior(intent); } @@ -2212,10 +2244,11 @@ Tracker tracker = TrackerFactory.getTrackerForProfile(Profile.getLastUsedProfile()); tracker.notifyEvent(EventConstants.SCREENSHOT_TAKEN_CHROME_IN_FOREGROUND); - maybeShowFeatureEngagementTextBubbleForDownloadPage(tracker); + maybeShowFeatureEngagementTextBubbleForDownloadPageScreenshot(tracker); } - private void maybeShowFeatureEngagementTextBubbleForDownloadPage(final Tracker tracker) { + private void maybeShowFeatureEngagementTextBubbleForDownloadPageScreenshot( + final Tracker tracker) { if (!tracker.shouldTriggerHelpUI(FeatureConstants.DOWNLOAD_PAGE_SCREENSHOT_FEATURE)) return; ViewAnchoredTextBubble textBubble =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java index d0bf423..c5f0e75 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java
@@ -27,11 +27,13 @@ private boolean mImpressionTracked; private int mPerSectionRank = -1; + private boolean mEnabled; public ActionItem(SuggestionsSection section, SuggestionsRanker ranker) { mCategoryInfo = section.getCategoryInfo(); mParentSection = section; mSuggestionsRanker = ranker; + mEnabled = true; setVisibilityInternal( mCategoryInfo.getAdditionalAction() != ContentSuggestionsAdditionalAction.NONE); } @@ -68,6 +70,8 @@ @VisibleForTesting void performAction(SuggestionsUiDelegate uiDelegate) { + if (!mEnabled) return; + uiDelegate.getEventReporter().onMoreButtonClicked(this); switch (mCategoryInfo.getAdditionalAction()) { @@ -90,6 +94,11 @@ } } + /** Used to enable/disable the action of this item. */ + public void setEnabled(boolean enabled) { + mEnabled = enabled; + } + /** ViewHolder associated to {@link ItemViewType#ACTION}. */ public static class ViewHolder extends CardViewHolder implements ContextMenuManager.Delegate { private ActionItem mActionListItem;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java index f7194d2..0e7250bd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java
@@ -471,6 +471,9 @@ /** Fetches additional suggestions only for this section. */ public void fetchSuggestions() { + // We want to disable the action item while we are fetching suggestions in order to + // avoid fetching the same suggestions twice. See crbug.com/739648. + mMoreButton.setEnabled(false); mSuggestionsSource.fetchSuggestions(mCategoryInfo.getCategory(), getDisplayedSuggestionIds(), new Callback<List<SnippetArticle>>() { @Override @@ -479,6 +482,7 @@ mProgressIndicator.setVisible(false); appendSuggestions(additionalSuggestions, /*keepSectionSize=*/false); + mMoreButton.setEnabled(true); } });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetMetrics.java index 9fb1154..714b938 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetMetrics.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetMetrics.java
@@ -23,14 +23,15 @@ * histogram and should therefore be treated as append-only. */ @IntDef({OPENED_BY_SWIPE, OPENED_BY_OMNIBOX_FOCUS, OPENED_BY_NEW_TAB_CREATION, - OPENED_BY_EXPAND_BUTTON}) + OPENED_BY_EXPAND_BUTTON, OPENED_BY_STARTUP}) @Retention(RetentionPolicy.SOURCE) public @interface SheetOpenReason {} public static final int OPENED_BY_SWIPE = 0; public static final int OPENED_BY_OMNIBOX_FOCUS = 1; public static final int OPENED_BY_NEW_TAB_CREATION = 2; public static final int OPENED_BY_EXPAND_BUTTON = 3; - private static final int OPENED_BY_BOUNDARY = 4; + public static final int OPENED_BY_STARTUP = 4; + private static final int OPENED_BY_BOUNDARY = 5; /** The different ways that the bottom sheet can be closed. */ @IntDef({CLOSED_BY_NONE, CLOSED_BY_SWIPE, CLOSED_BY_BACK_PRESS, CLOSED_BY_TAP_SCRIM, @@ -160,6 +161,9 @@ case OPENED_BY_EXPAND_BUTTON: RecordUserAction.record("Android.ChromeHome.OpenedByExpandButton"); break; + case OPENED_BY_STARTUP: + RecordUserAction.record("Android.ChromeHome.OpenedByStartup"); + break; default: assert false; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java index 7473465..cc81dbc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java
@@ -28,6 +28,9 @@ import org.chromium.chrome.browser.util.AccessibilityUtil; import org.chromium.chrome.browser.util.MathUtils; +import java.util.HashSet; +import java.util.Set; + /** * UI component that handles showing a text callout bubble. Positioning this bubble happens through * calls to {@link #setAnchorRect(Rect)}. This should be called at least once before the @@ -40,6 +43,12 @@ */ public static final long NO_TIMEOUT = 0; + /** + * A set of bubbles which are active at this moment. This set can be used to dismiss the + * bubbles on a back press event. + */ + private static final Set<TextBubble> sBubbles = new HashSet<>(); + // Cache Rect objects for querying View and Screen coordinate APIs. private final Rect mCachedPaddingRect = new Rect(); private final Rect mCachedWindowRect = new Rect(); @@ -74,6 +83,8 @@ mHandler.removeCallbacks(mDismissRunnable); for (OnDismissListener listener : mDismissListeners) listener.onDismiss(); + + sBubbles.remove(TextBubble.this); } }; @@ -154,6 +165,8 @@ createContentView(); updateBubbleLayout(); mPopupWindow.showAtLocation(mRootView, Gravity.TOP | Gravity.START, mX, mY); + + sBubbles.add(this); } /** @@ -165,6 +178,16 @@ } /** + * Dismisses the active bubbles if user has pressed the back button. + */ + public static void onBackPressed() { + Set<TextBubble> bubbles = new HashSet<>(sBubbles); + for (TextBubble bubble : bubbles) { + bubble.dismiss(); + } + } + + /** * @param onTouchListener A callback for all touch events being dispatched to the bubble. * @see PopupWindow#setTouchInterceptor(OnTouchListener) */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/WarmupManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/WarmupManagerTest.java index 0eadac17..b055386 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/WarmupManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/WarmupManagerTest.java
@@ -224,7 +224,7 @@ // Cannot use EmbeddedTestServer#createAndStartServer(), as we need to add the // connection listener. - server.initializeNative(mContext); + server.initializeNative(mContext, EmbeddedTestServer.ServerHTTPSSetting.USE_HTTP); server.addDefaultHandlers(""); server.setConnectionListener(new EmbeddedTestServer.ConnectionListener() { @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java index 43621f92..e768942 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java
@@ -18,7 +18,6 @@ import android.view.View; import android.view.WindowManager; import android.widget.ImageButton; -import android.widget.ImageView; import android.widget.TextView; import org.junit.Assert; @@ -31,7 +30,6 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.EnormousTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.base.test.util.ScalableTimeout; @@ -56,6 +54,7 @@ import org.chromium.content.browser.test.util.TouchCommon; import org.chromium.content.browser.test.util.UiUtils; import org.chromium.net.test.EmbeddedTestServer; +import org.chromium.net.test.ServerCertificate; import org.chromium.ui.base.DeviceFormFactor; import java.util.HashMap; @@ -594,20 +593,16 @@ } /** - * Test to verify security-icon "lock or globe" on visiting http and secured Urls. - * @EnormousTest + * Test to verify that the security icon is present when visiting http:// URLs. */ @Test - @FlakyTest(message = "crbug.com/414353") - public void testSecurityIcon() throws InterruptedException { + @MediumTest + public void testSecurityIconOnHTTP() throws InterruptedException { EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer( InstrumentationRegistry.getInstrumentation().getContext()); try { final String testUrl = testServer.getURL("/chrome/test/data/android/omnibox/one.html"); - final String securedExternalUrl = "https://www.google.com"; - ImageView navigationButton = (ImageView) mActivityTestRule.getActivity().findViewById( - R.id.navigation_button); ImageButton securityButton = (ImageButton) mActivityTestRule.getActivity().findViewById( R.id.security_button); @@ -617,20 +612,39 @@ R.id.location_bar); boolean securityIcon = locationBar.isSecurityButtonShown(); Assert.assertFalse("Omnibox should not have a Security icon", securityIcon); - Assert.assertEquals("navigation_button with wrong resource-id", R.id.navigation_button, - navigationButton.getId()); - Assert.assertTrue(navigationButton.isShown()); Assert.assertFalse(securityButton.isShown()); + } finally { + testServer.stopAndDestroyServer(); + } + } - mActivityTestRule.loadUrl(securedExternalUrl); - securityIcon = locationBar.isSecurityButtonShown(); + /** + * Test to verify that the security icon is present when visiting https:// URLs. + */ + @Test + @MediumTest + public void testSecurityIconOnHTTPS() throws InterruptedException { + EmbeddedTestServer httpsTestServer = EmbeddedTestServer.createAndStartHTTPSServer( + InstrumentationRegistry.getInstrumentation().getContext(), + ServerCertificate.CERT_OK); + try { + final String testHttpsUrl = + httpsTestServer.getURL("/chrome/test/data/android/omnibox/one.html"); + + ImageButton securityButton = (ImageButton) mActivityTestRule.getActivity().findViewById( + R.id.security_button); + + mActivityTestRule.loadUrl(testHttpsUrl); + final LocationBarLayout locationBar = + (LocationBarLayout) mActivityTestRule.getActivity().findViewById( + R.id.location_bar); + boolean securityIcon = locationBar.isSecurityButtonShown(); Assert.assertTrue("Omnibox should have a Security icon", securityIcon); Assert.assertEquals("security_button with wrong resource-id", R.id.security_button, securityButton.getId()); Assert.assertTrue(securityButton.isShown()); - Assert.assertFalse(navigationButton.isShown()); } finally { - testServer.stopAndDestroyServer(); + httpsTestServer.stopAndDestroyServer(); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java index 9af1320..d79613c8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java
@@ -77,25 +77,6 @@ mPaymentRequestTestRule.getDismissed().waitForCallback(callCount); mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - // CanMakePayment was queried. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.Usage", - CanMakePaymentUsage.CAN_MAKE_PAYMENT_USED)); - - // The CanMakePayment effect on show should be recorded as being false and shown. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - CanMakePaymentEffectOnShow.DID_SHOW)); - - // There should be a record for an abort when CanMakePayment is false but the PR is shown to - // the user. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.Used.FalseWithShowEffectOnCompletion", - CompletionStatus.USER_ABORTED)); - // Make sure the canMakePayment events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.CAN_MAKE_PAYMENT_FALSE; Assert.assertEquals(1, @@ -135,25 +116,6 @@ mPaymentRequestTestRule.clickCardUnmaskButtonAndWait( DialogInterface.BUTTON_POSITIVE, mPaymentRequestTestRule.getDismissed()); - // CanMakePayment was queried. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.Usage", - CanMakePaymentUsage.CAN_MAKE_PAYMENT_USED)); - - // The CanMakePayment effect on show should be recorded as being false and shown. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - CanMakePaymentEffectOnShow.DID_SHOW)); - - // There should be a record for a completion when CanMakePayment is false but the PR is - // shown to the user. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.Used.FalseWithShowEffectOnCompletion", - CompletionStatus.COMPLETED)); - // Make sure the canMakePayment events were logged correctly. int expectedSample = Event.SHOWN | Event.PAY_CLICKED | Event.RECEIVED_INSTRUMENT_DETAILS | Event.COMPLETED | Event.CAN_MAKE_PAYMENT_FALSE; @@ -183,26 +145,6 @@ mPaymentRequestTestRule.clickNodeAndWait("abort", mPaymentRequestTestRule.getDismissed()); mPaymentRequestTestRule.expectResultContains(new String[] {"Abort"}); - // CanMakePayment was queried. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.Usage", - CanMakePaymentUsage.CAN_MAKE_PAYMENT_USED)); - - // The CanMakePayment effect on show should be recorded as being false and shown. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - CanMakePaymentEffectOnShow.DID_SHOW - | CanMakePaymentEffectOnShow.COULD_MAKE_PAYMENT)); - - // There should be a record for an abort when CanMakePayment is false but the PR is shown to - // the user. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.Used.TrueWithShowEffectOnCompletion", - CompletionStatus.OTHER_ABORTED)); - // Make sure the canMakePayment events were logged correctly. int expectedSample = Event.SHOWN | Event.OTHER_ABORTED | Event.HAD_INITIAL_FORM_OF_PAYMENT | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS | Event.CAN_MAKE_PAYMENT_TRUE; @@ -230,26 +172,6 @@ mPaymentRequestTestRule.clickAndWait( R.id.button_primary, mPaymentRequestTestRule.getDismissed()); - // CanMakePayment was queried. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.Usage", - CanMakePaymentUsage.CAN_MAKE_PAYMENT_USED)); - - // The CanMakePayment effect on show should be recorded as being false and shown. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - CanMakePaymentEffectOnShow.DID_SHOW - | CanMakePaymentEffectOnShow.COULD_MAKE_PAYMENT)); - - // There should be a record for an abort when CanMakePayment is false but the PR is shown to - // the user. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.Used.TrueWithShowEffectOnCompletion", - CompletionStatus.COMPLETED)); - // Make sure the canMakePayment events were logged correctly. int expectedSample = Event.SHOWN | Event.PAY_CLICKED | Event.RECEIVED_INSTRUMENT_DETAILS | Event.COMPLETED | Event.HAD_INITIAL_FORM_OF_PAYMENT @@ -283,19 +205,6 @@ mPaymentRequestTestRule.getDismissed().waitForCallback(callCount); mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - // CanMakePayment was not queried. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.Usage", - CanMakePaymentUsage.CAN_MAKE_PAYMENT_NOT_USED)); - - // There should be a record for an abort when CanMakePayment is not called but the PR is - // shown to the user. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.NotUsed.WithShowEffectOnCompletion", - CompletionStatus.USER_ABORTED)); - // Make sure no canMakePayment events were logged. int expectedSample = Event.SHOWN | Event.USER_ABORTED; Assert.assertEquals(1, @@ -321,19 +230,6 @@ mPaymentRequestTestRule.clickAndWait( R.id.button_primary, mPaymentRequestTestRule.getDismissed()); - // CanMakePayment was not queried. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.Usage", - CanMakePaymentUsage.CAN_MAKE_PAYMENT_NOT_USED)); - - // There should be a record for a completion when CanMakePayment is not called but the PR is - // shown to the user. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.CanMakePayment.NotUsed.WithShowEffectOnCompletion", - CompletionStatus.COMPLETED)); - // Make sure no canMakePayment events were logged. int expectedSample = Event.SHOWN | Event.PAY_CLICKED | Event.RECEIVED_INSTRUMENT_DETAILS | Event.COMPLETED | Event.HAD_INITIAL_FORM_OF_PAYMENT
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java index 2c7c1e28..774b983 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java
@@ -576,18 +576,6 @@ R.id.close_button, mPaymentRequestTestRule.getDismissed()); mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - // Make the metric was logged correctly. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserHadCompleteSuggestionsForEverything.EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - + "EffectOnCompletion")); - // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.HAD_INITIAL_FORM_OF_PAYMENT | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS | Event.REQUEST_SHIPPING; @@ -621,19 +609,6 @@ R.id.close_button, mPaymentRequestTestRule.getDismissed()); mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - // Make the metric was logged correctly. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - + "EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserHadCompleteSuggestionsForEverything." - + "EffectOnCompletion")); - // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.HAD_INITIAL_FORM_OF_PAYMENT | Event.REQUEST_SHIPPING; @@ -667,19 +642,6 @@ R.id.close_button, mPaymentRequestTestRule.getDismissed()); mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - // Make the metric was logged correctly. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - + "EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserHadCompleteSuggestionsForEverything." - + "EffectOnCompletion")); - // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.HAD_INITIAL_FORM_OF_PAYMENT | Event.REQUEST_SHIPPING; @@ -713,19 +675,6 @@ R.id.close_button, mPaymentRequestTestRule.getDismissed()); mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - // Make the metric was logged correctly. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - + "EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserHadCompleteSuggestionsForEverything." - + "EffectOnCompletion")); - // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.REQUEST_SHIPPING; Assert.assertEquals(1, @@ -756,19 +705,6 @@ R.id.close_button, mPaymentRequestTestRule.getDismissed()); mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - // Make the metric was logged correctly. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - + "EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserHadCompleteSuggestionsForEverything." - + "EffectOnCompletion")); - // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.REQUEST_SHIPPING; Assert.assertEquals(1, @@ -799,19 +735,6 @@ R.id.close_button, mPaymentRequestTestRule.getDismissed()); mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - // Make the metric was logged correctly. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - + "EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserHadCompleteSuggestionsForEverything." - + "EffectOnCompletion")); - // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.REQUEST_SHIPPING; Assert.assertEquals(1, @@ -842,18 +765,6 @@ R.id.close_button, mPaymentRequestTestRule.getDismissed()); mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - // Make the metric was logged correctly. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserHadCompleteSuggestionsForEverything.EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - + "EffectOnCompletion")); - // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.HAD_INITIAL_FORM_OF_PAYMENT | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS | Event.REQUEST_SHIPPING; @@ -887,19 +798,6 @@ R.id.close_button, mPaymentRequestTestRule.getDismissed()); mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - // Make the metric was logged correctly. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - + "EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserHadCompleteSuggestionsForEverything." - + "EffectOnCompletion")); - // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.HAD_INITIAL_FORM_OF_PAYMENT | Event.REQUEST_SHIPPING; @@ -934,18 +832,6 @@ R.id.close_button, mPaymentRequestTestRule.getDismissed()); mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - // Make the metric was logged correctly. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserHadCompleteSuggestionsForEverything.EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - + "EffectOnCompletion")); - // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.HAD_INITIAL_FORM_OF_PAYMENT | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS | Event.REQUEST_SHIPPING; @@ -978,18 +864,6 @@ R.id.close_button, mPaymentRequestTestRule.getDismissed()); mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - // Make the metric was logged correctly. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserHadCompleteSuggestionsForEverything.EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - + "EffectOnCompletion")); - // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.HAD_INITIAL_FORM_OF_PAYMENT | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS | Event.REQUEST_SHIPPING; @@ -1025,18 +899,6 @@ R.id.close_button, mPaymentRequestTestRule.getDismissed()); mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - // Make the metric was logged correctly. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserHadCompleteSuggestionsForEverything.EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - + "EffectOnCompletion")); - // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.HAD_INITIAL_FORM_OF_PAYMENT | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS | Event.REQUEST_SHIPPING; @@ -1067,18 +929,6 @@ R.id.close_button, mPaymentRequestTestRule.getDismissed()); mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - // Make sure the metric was logged correctly. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - + "EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserHadCompleteSuggestions.EffectOnCompletion")); - // Make sure the events were logged correctly. int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.REQUEST_SHIPPING; Assert.assertEquals(1,
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_impl.cc b/chrome/browser/chromeos/login/ui/login_display_host_impl.cc index 26656bc1..599ca8d 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_impl.cc +++ b/chrome/browser/chromeos/login/ui/login_display_host_impl.cc
@@ -1168,18 +1168,25 @@ views::Widget::InitParams params( views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); params.bounds = wallpaper_bounds(); - params.show_state = ui::SHOW_STATE_FULLSCREEN; + // Disable fullscreen state for voice interaction OOBE since the shelf should + // be visible. + if (!is_voice_interaction_oobe_) + params.show_state = ui::SHOW_STATE_FULLSCREEN; params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; + + // Put the voice interaction oobe inside AlwaysOnTop container instead of + // LockScreenContainer. + ash::ShellWindowId container = is_voice_interaction_oobe_ + ? ash::kShellWindowId_AlwaysOnTopContainer + : ash::kShellWindowId_LockScreenContainer; // The ash::Shell containers are not available in Mash if (!ash_util::IsRunningInMash()) { params.parent = - ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), - ash::kShellWindowId_LockScreenContainer); + ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), container); } else { using ui::mojom::WindowManager; params.mus_properties[WindowManager::kContainerId_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>( - static_cast<int32_t>(ash::kShellWindowId_LockScreenContainer)); + mojo::ConvertTo<std::vector<uint8_t>>(static_cast<int32_t>(container)); } login_window_ = new views::Widget; params.delegate = login_window_delegate_ = @@ -1191,8 +1198,9 @@ if (login_view_->webui_visible()) OnLoginPromptVisible(); - // Animations are not available in Mash - if (!ash_util::IsRunningInMash()) { + // Animations are not available in Mash. + // For voice interaction OOBE, we do not want the animation here. + if (!ash_util::IsRunningInMash() && !is_voice_interaction_oobe_) { login_window_->SetVisibilityAnimationDuration( base::TimeDelta::FromMilliseconds(kLoginFadeoutTransitionDurationMs)); login_window_->SetVisibilityAnimationTransition( @@ -1295,13 +1303,6 @@ void LoginDisplayHostImpl::StartVoiceInteractionOobe() { is_voice_interaction_oobe_ = true; - - // Lock container can be transparent after lock screen animation. - aura::Window* lock_container = ash::Shell::GetContainer( - ash::Shell::GetPrimaryRootWindow(), - ash::kShellWindowId_LockScreenContainersContainer); - lock_container->layer()->SetOpacity(1.0); - finalize_animation_type_ = ANIMATION_NONE; StartWizard(chromeos::OobeScreen::SCREEN_VOICE_INTERACTION_VALUE_PROP); }
diff --git a/chrome/browser/chromeos/tether/tether_service.cc b/chrome/browser/chromeos/tether/tether_service.cc index 5a95cfd..2135e18a 100644 --- a/chrome/browser/chromeos/tether/tether_service.cc +++ b/chrome/browser/chromeos/tether/tether_service.cc
@@ -26,6 +26,15 @@ #include "device/bluetooth/bluetooth_adapter_factory.h" #include "ui/message_center/message_center.h" +namespace { + +// TODO (hansberry): Experiment with intervals to determine ideal advertising +// interval parameters. See crbug.com/753215. +constexpr int64_t kMinAdvertisingIntervalMilliseconds = 100; +constexpr int64_t kMaxAdvertisingIntervalMilliseconds = 100; + +} // namespace + // static TetherService* TetherService::Get(Profile* profile) { if (IsFeatureFlagEnabled()) @@ -38,6 +47,22 @@ void TetherService::RegisterProfilePrefs(PrefRegistrySimple* registry) { registry->RegisterBooleanPref(prefs::kInstantTetheringAllowed, true); registry->RegisterBooleanPref(prefs::kInstantTetheringEnabled, true); + + // If we initially assume that BLE advertising is not supported, it will + // result in Tether's Settings and Quick Settings sections not being visible + // when the user logs in with Bluetooth disabled (because the TechnologyState + // will be UNAVAILABLE, instead of the desired UNINITIALIZED). + // + // Initially assuming that BLE advertising *is* supported works well for most + // devices, but if a user first logs into a device without BLE advertising + // support and with Bluetooth disabled, Tether will be visible in Settings and + // Quick Settings, but disappear upon enabling Bluetooth. This is an + // acceptable edge case, and likely rare because Bluetooth is enabled by + // default on new logins. Additionally, through this pref, we will record if + // BLE advertising is not supported and remember that for future logins. + registry->RegisterBooleanPref(prefs::kInstantTetheringBleAdvertisingSupported, + true); + chromeos::tether::Initializer::RegisterProfilePrefs(registry); } @@ -55,12 +80,13 @@ chromeos::ManagedNetworkConfigurationHandler* managed_network_configuration_handler, chromeos::NetworkConnect* network_connect, - chromeos::NetworkConnectionHandler* network_connection_handler) { + chromeos::NetworkConnectionHandler* network_connection_handler, + scoped_refptr<device::BluetoothAdapter> adapter) { chromeos::tether::Initializer::Init( cryptauth_service, std::move(notification_presenter), pref_service, token_service, network_state_handler, managed_network_configuration_handler, network_connect, - network_connection_handler); + network_connection_handler, adapter); } void TetherService::InitializerDelegate::ShutdownTether() { @@ -121,7 +147,7 @@ network_state_handler_, chromeos::NetworkHandler::Get()->managed_network_configuration_handler(), chromeos::NetworkConnect::Get(), - chromeos::NetworkHandler::Get()->network_connection_handler()); + chromeos::NetworkHandler::Get()->network_connection_handler(), adapter_); } void TetherService::StopTetherIfNecessary() { @@ -184,7 +210,18 @@ void TetherService::AdapterPoweredChanged(device::BluetoothAdapter* adapter, bool powered) { - UpdateTetherTechnologyState(); + // Once the BLE advertising interval has been set (regardless of if BLE + // advertising is supported), simply update the TechnologyState. + if (has_attempted_to_set_ble_advertising_interval_) { + UpdateTetherTechnologyState(); + return; + } + + // If the BluetoothAdapter was not powered when first fetched (see + // OnBluetoothAdapterFetched()), now attempt to set the BLE advertising + // interval. + if (powered) + SetBleAdvertisingInterval(); } void TetherService::DefaultNetworkChanged( @@ -239,6 +276,9 @@ } void TetherService::UpdateTetherTechnologyState() { + if (!adapter_) + return; + chromeos::NetworkStateHandler::TechnologyState new_tether_technology_state = GetTetherTechnologyState(); @@ -266,8 +306,9 @@ chromeos::NetworkStateHandler::TechnologyState TetherService::GetTetherTechnologyState() { - if (shut_down_ || suspended_ || session_manager_client_->IsScreenLocked() || - !HasSyncedTetherHosts() || IsCellularAvailableButNotEnabled()) { + if (shut_down_ || suspended_ || !GetIsBleAdvertisingSupportedPref() || + session_manager_client_->IsScreenLocked() || !HasSyncedTetherHosts() || + IsCellularAvailableButNotEnabled()) { // If Cellular technology is available, then Tether technology is treated // as a subset of Cellular, and it should only be enabled when Cellular // technology is enabled. @@ -279,8 +320,7 @@ } else if (!IsBluetoothAvailable()) { // TODO (hansberry): When !IsBluetoothAvailable(), this results in a weird // UI state for Settings where the toggle is clickable but immediately - // becomes disabled after enabling it. Possible solution: grey out the - // toggle and tell the user to turn Bluetooth on? + // becomes disabled after enabling it. See crbug.com/753195. return chromeos::NetworkStateHandler::TechnologyState:: TECHNOLOGY_UNINITIALIZED; } else if (!IsEnabledbyPreference()) { @@ -298,14 +338,59 @@ adapter_ = adapter; adapter_->AddObserver(this); + // Update TechnologyState in case Tether is otherwise available but Bluetooth + // is off. UpdateTetherTechnologyState(); + // If |adapter_| is not powered, wait until it is to call + // SetBleAdvertisingInterval(). See AdapterPoweredChanged(). + if (IsBluetoothAvailable()) + SetBleAdvertisingInterval(); + // The user has just logged in; display the "enable Bluetooth" notification if // applicable. if (CanEnableBluetoothNotificationBeShown()) notification_presenter_->NotifyEnableBluetooth(); } +void TetherService::OnBluetoothAdapterAdvertisingIntervalSet() { + has_attempted_to_set_ble_advertising_interval_ = true; + SetIsBleAdvertisingSupportedPref(true); + + UpdateTetherTechnologyState(); +} + +void TetherService::OnBluetoothAdapterAdvertisingIntervalError( + device::BluetoothAdvertisement::ErrorCode status) { + has_attempted_to_set_ble_advertising_interval_ = true; + SetIsBleAdvertisingSupportedPref(false); + + UpdateTetherTechnologyState(); +} + +void TetherService::SetBleAdvertisingInterval() { + DCHECK(IsBluetoothAvailable()); + adapter_->SetAdvertisingInterval( + base::TimeDelta::FromMilliseconds(kMinAdvertisingIntervalMilliseconds), + base::TimeDelta::FromMilliseconds(kMaxAdvertisingIntervalMilliseconds), + base::Bind(&TetherService::OnBluetoothAdapterAdvertisingIntervalSet, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&TetherService::OnBluetoothAdapterAdvertisingIntervalError, + weak_ptr_factory_.GetWeakPtr())); +} + +bool TetherService::GetIsBleAdvertisingSupportedPref() { + return profile_->GetPrefs()->GetBoolean( + prefs::kInstantTetheringBleAdvertisingSupported); +} + +void TetherService::SetIsBleAdvertisingSupportedPref( + bool is_ble_advertising_supported) { + profile_->GetPrefs()->SetBoolean( + prefs::kInstantTetheringBleAdvertisingSupported, + is_ble_advertising_supported); +} + bool TetherService::IsBluetoothAvailable() const { return adapter_.get() && adapter_->IsPresent() && adapter_->IsPowered(); }
diff --git a/chrome/browser/chromeos/tether/tether_service.h b/chrome/browser/chromeos/tether/tether_service.h index 22e40336..4c7d62e 100644 --- a/chrome/browser/chromeos/tether/tether_service.h +++ b/chrome/browser/chromeos/tether/tether_service.h
@@ -78,7 +78,8 @@ chromeos::ManagedNetworkConfigurationHandler* managed_network_configuration_handler, chromeos::NetworkConnect* network_connect, - chromeos::NetworkConnectionHandler* network_connection_handler); + chromeos::NetworkConnectionHandler* network_connection_handler, + scoped_refptr<device::BluetoothAdapter> adapter); virtual void ShutdownTether(); }; @@ -131,6 +132,18 @@ void OnBluetoothAdapterFetched( scoped_refptr<device::BluetoothAdapter> adapter); + void OnBluetoothAdapterAdvertisingIntervalSet(); + void OnBluetoothAdapterAdvertisingIntervalError( + device::BluetoothAdvertisement::ErrorCode status); + + void SetBleAdvertisingInterval(); + + // Whether BLE advertising is supported on this device. This should only + // return true if a call to BluetoothAdapter::SetAdvertisingInterval() during + // TetherService construction succeeds. That method will fail in cases like + // those captured in crbug.com/738222. + bool GetIsBleAdvertisingSupportedPref(); + void SetIsBleAdvertisingSupportedPref(bool is_ble_advertising_supported); bool IsBluetoothAvailable() const; @@ -161,6 +174,8 @@ // was closed). bool suspended_ = false; + bool has_attempted_to_set_ble_advertising_interval_ = false; + Profile* profile_; chromeos::PowerManagerClient* power_manager_client_; chromeos::SessionManagerClient* session_manager_client_;
diff --git a/chrome/browser/chromeos/tether/tether_service_unittest.cc b/chrome/browser/chromeos/tether/tether_service_unittest.cc index 4907316..e63f8bef 100644 --- a/chrome/browser/chromeos/tether/tether_service_unittest.cc +++ b/chrome/browser/chromeos/tether/tether_service_unittest.cc
@@ -67,6 +67,32 @@ std::vector<cryptauth::ExternalDeviceInfo>()); }; +class MockExtendedBluetoothAdapter : public device::MockBluetoothAdapter { + public: + void SetAdvertisingInterval( + const base::TimeDelta& min, + const base::TimeDelta& max, + const base::Closure& callback, + const AdvertisementErrorCallback& error_callback) override { + if (is_ble_advertising_supported_) { + callback.Run(); + } else { + error_callback.Run(device::BluetoothAdvertisement::ErrorCode:: + ERROR_INVALID_ADVERTISEMENT_INTERVAL); + } + } + + void set_is_ble_advertising_supported(bool is_ble_advertising_supported) { + is_ble_advertising_supported_ = is_ble_advertising_supported; + } + + protected: + ~MockExtendedBluetoothAdapter() override {} + + private: + bool is_ble_advertising_supported_ = true; +}; + class TestTetherService : public TetherService { public: TestTetherService(Profile* profile, @@ -109,7 +135,8 @@ chromeos::ManagedNetworkConfigurationHandler* managed_network_configuration_handler, chromeos::NetworkConnect* network_connect, - chromeos::NetworkConnectionHandler* network_connection_handler) override { + chromeos::NetworkConnectionHandler* network_connection_handler, + scoped_refptr<device::BluetoothAdapter> adapter) override { is_tether_running_ = true; } @@ -155,8 +182,8 @@ mock_cryptauth_device_manager_.get()); mock_adapter_ = - make_scoped_refptr(new NiceMock<device::MockBluetoothAdapter>()); - is_adapter_powered_ = true; + make_scoped_refptr(new NiceMock<MockExtendedBluetoothAdapter>()); + SetIsBluetoothPowered(true); ON_CALL(*mock_adapter_, IsPresent()).WillByDefault(Return(true)); ON_CALL(*mock_adapter_, IsPowered()) .WillByDefault(Invoke(this, &TetherServiceTest::IsBluetoothPowered)); @@ -190,6 +217,14 @@ tether_service_->SetNotificationPresenterForTest( base::WrapUnique(fake_notification_presenter_)); + // Ensure that TetherService does not prematurely update its TechnologyState + // before it fetches the BluetoothAdapter. + EXPECT_EQ( + chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, + network_state_handler()->GetTechnologyState( + chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + base::RunLoop().RunUntilIdle(); } @@ -221,6 +256,12 @@ base::RunLoop().RunUntilIdle(); } + void SetIsBluetoothPowered(bool powered) { + is_adapter_powered_ = powered; + for (auto& observer : mock_adapter_->GetObservers()) + observer.AdapterPoweredChanged(mock_adapter_.get(), powered); + } + bool IsBluetoothPowered() { return is_adapter_powered_; } void DisconnectDefaultShillNetworks() { @@ -244,7 +285,7 @@ chromeos::tether::FakeNotificationPresenter* fake_notification_presenter_; std::unique_ptr<cryptauth::FakeCryptAuthService> fake_cryptauth_service_; - scoped_refptr<device::MockBluetoothAdapter> mock_adapter_; + scoped_refptr<MockExtendedBluetoothAdapter> mock_adapter_; bool is_adapter_powered_; std::unique_ptr<TestTetherService> tether_service_; @@ -288,6 +329,93 @@ EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); } +TEST_F(TetherServiceTest, TestBleAdvertisingNotSupported) { + mock_adapter_->set_is_ble_advertising_supported(false); + + CreateTetherService(); + + EXPECT_EQ( + chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, + network_state_handler()->GetTechnologyState( + chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); +} + +TEST_F(TetherServiceTest, + TestBleAdvertisingNotSupported_BluetoothIsInitiallyNotPowered) { + SetIsBluetoothPowered(false); + + mock_adapter_->set_is_ble_advertising_supported(false); + + CreateTetherService(); + + // TetherService has not yet been able to find out that BLE advertising is not + // supported. + EXPECT_EQ( + chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED, + network_state_handler()->GetTechnologyState( + chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + EXPECT_TRUE(profile_->GetPrefs()->GetBoolean( + prefs::kInstantTetheringBleAdvertisingSupported)); + + SetIsBluetoothPowered(true); + + EXPECT_EQ( + chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, + network_state_handler()->GetTechnologyState( + chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + EXPECT_FALSE(profile_->GetPrefs()->GetBoolean( + prefs::kInstantTetheringBleAdvertisingSupported)); +} + +TEST_F( + TetherServiceTest, + TestBleAdvertisingNotSupportedAndRecorded_BluetoothIsInitiallyNotPowered) { + SetIsBluetoothPowered(false); + + mock_adapter_->set_is_ble_advertising_supported(false); + + // Simulate a login after we determined that BLE advertising is not supported. + profile_->GetPrefs()->SetBoolean( + prefs::kInstantTetheringBleAdvertisingSupported, false); + + CreateTetherService(); + + EXPECT_EQ( + chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, + network_state_handler()->GetTechnologyState( + chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + + SetIsBluetoothPowered(true); + + EXPECT_EQ( + chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE, + network_state_handler()->GetTechnologyState( + chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); +} + +TEST_F(TetherServiceTest, TestBleAdvertisingSupportedButIncorrectlyRecorded) { + // Simulate a login after we incorrectly determined that BLE advertising is + // not supported (this is not an expected case, but may have happened if + // BluetoothAdapter::SetAdvertisingInterval() failed for a weird, one-off + // reason). + profile_->GetPrefs()->SetBoolean( + prefs::kInstantTetheringBleAdvertisingSupported, false); + + CreateTetherService(); + + EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, + network_state_handler()->GetTechnologyState( + chromeos::NetworkTypePattern::Tether())); + EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); + EXPECT_TRUE(profile_->GetPrefs()->GetBoolean( + prefs::kInstantTetheringBleAdvertisingSupported)); +} + TEST_F(TetherServiceTest, TestScreenLock) { CreateTetherService(); EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); @@ -348,8 +476,8 @@ EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); } -TEST_F(TetherServiceTest, TestBluetoothIsNotPowered) { - is_adapter_powered_ = false; +TEST_F(TetherServiceTest, TestIsBluetoothPowered) { + SetIsBluetoothPowered(false); CreateTetherService(); @@ -358,6 +486,21 @@ network_state_handler()->GetTechnologyState( chromeos::NetworkTypePattern::Tether())); EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); + + SetIsBluetoothPowered(true); + + EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED, + network_state_handler()->GetTechnologyState( + chromeos::NetworkTypePattern::Tether())); + EXPECT_TRUE(test_initializer_delegate_->is_tether_running()); + + SetIsBluetoothPowered(false); + + EXPECT_EQ( + chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED, + network_state_handler()->GetTechnologyState( + chromeos::NetworkTypePattern::Tether())); + EXPECT_FALSE(test_initializer_delegate_->is_tether_running()); } TEST_F(TetherServiceTest, TestCellularIsUnavailable) { @@ -466,7 +609,7 @@ // state than the user preference. TEST_F(TetherServiceTest, TestEnabledMultipleChanges) { CreateTetherService(); - // CreateTetherService calls RunUntilIdle() so UpdateTetherTechnologyState() + // CreateTetherService calls RunUntilIdle() so UpdateTetherTechnologyState() // may be called multiple times in the initialization process. int updated_technology_state_count = tether_service_->updated_technology_state_count(); @@ -489,7 +632,7 @@ } TEST_F(TetherServiceTest, TestBluetoothNotification) { - is_adapter_powered_ = false; + SetIsBluetoothPowered(false); CreateTetherService(); DisconnectDefaultShillNetworks(); @@ -499,20 +642,16 @@ EXPECT_TRUE( fake_notification_presenter_->is_enable_bluetooth_notification_shown()); - // Now, simulate the adapter being turned off. The notification should no + // Now, simulate the adapter being turned on. The notification should no // longer be visible. - is_adapter_powered_ = true; - tether_service_->AdapterPoweredChanged(mock_adapter_.get(), - true /* powered */); + SetIsBluetoothPowered(true); EXPECT_FALSE( fake_notification_presenter_->is_enable_bluetooth_notification_shown()); - // Now, simulate the adapter being turned back on. The notification should + // Now, simulate the adapter being turned off again. The notification should // still *not* be available. It should only be shown when the service starts // up or when the network has been disconnected. - is_adapter_powered_ = false; - tether_service_->AdapterPoweredChanged(mock_adapter_.get(), - false /* powered */); + SetIsBluetoothPowered(false); EXPECT_FALSE( fake_notification_presenter_->is_enable_bluetooth_notification_shown());
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc index 9088ad5..d718b42b 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc
@@ -16,7 +16,9 @@ DialMediaSinkServiceImpl::DialMediaSinkServiceImpl( const OnSinksDiscoveredCallback& callback, net::URLRequestContextGetter* request_context) - : MediaSinkServiceBase(callback), request_context_(request_context) { + : MediaSinkServiceBase(callback), + observer_(nullptr), + request_context_(request_context) { DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(request_context_); } @@ -61,6 +63,18 @@ return description_service_.get(); } +void DialMediaSinkServiceImpl::SetObserver( + DialMediaSinkServiceObserver* observer) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + observer_ = observer; +} + +void DialMediaSinkServiceImpl::ClearObserver( + DialMediaSinkServiceObserver* observer) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + observer_ = nullptr; +} + void DialMediaSinkServiceImpl::SetDialRegistryForTest( DialRegistry* dial_registry) { DCHECK(!test_dial_registry_); @@ -115,7 +129,10 @@ return; } - current_sinks_.insert(MediaSinkInternal(sink, extra_data)); + MediaSinkInternal dial_sink(sink, extra_data); + current_sinks_.insert(dial_sink); + if (observer_) + observer_->OnDialSinkAdded(dial_sink); // Start fetch timer again if device description comes back after // |finish_timer_| fires.
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h index 2e74c93..ccc764f8b 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h
@@ -18,6 +18,17 @@ class DeviceDescriptionService; class DialRegistry; +// An observer class registered with DialMediaSinkService to receive +// notifications when DIAL sinks are added or removed from DialMediaSinkService +class DialMediaSinkServiceObserver { + public: + virtual ~DialMediaSinkServiceObserver() {} + + // Invoked when |sink| is added to DialMediaSinkServiceImpl instance. + // |sink|: must be a DIAL sink. + virtual void OnDialSinkAdded(const MediaSinkInternal& sink) = 0; +}; + // A service which can be used to start background discovery and resolution of // DIAL devices (Smart TVs, Game Consoles, etc.). // This class is not thread safe. All methods must be called from the IO thread. @@ -28,6 +39,13 @@ net::URLRequestContextGetter* request_context); ~DialMediaSinkServiceImpl() override; + // Does not take ownership of |observer|. Caller should make sure |observer| + // object outlives |this|. + void SetObserver(DialMediaSinkServiceObserver* observer); + + // Sets |observer_| to nullptr. + void ClearObserver(DialMediaSinkServiceObserver* observer); + // MediaSinkService implementation void Start() override; void Stop() override; @@ -78,6 +96,8 @@ // Device data list from current round of discovery. DialRegistry::DeviceList current_devices_; + DialMediaSinkServiceObserver* observer_; + scoped_refptr<net::URLRequestContextGetter> request_context_; DialDeviceCountMetrics metrics_;
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc index c99e490..50dc9598 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc
@@ -109,7 +109,7 @@ media_sink_service_->OnDeviceDescriptionAvailable(device_data, device_description); - EXPECT_EQ(size_t(1), media_sink_service_->current_sinks_.size()); + EXPECT_EQ(1u, media_sink_service_->current_sinks_.size()); } TEST_F(DialMediaSinkServiceImplTest, TestTimer) {
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_proxy.cc b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_proxy.cc index a3362d0..bfc0efe5 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_proxy.cc +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_proxy.cc
@@ -14,7 +14,7 @@ DialMediaSinkServiceProxy::DialMediaSinkServiceProxy( const MediaSinkService::OnSinksDiscoveredCallback& callback, content::BrowserContext* context) - : MediaSinkService(callback) { + : MediaSinkService(callback), observer_(nullptr) { DCHECK_CURRENTLY_ON(BrowserThread::UI); auto* profile = Profile::FromBrowserContext(context); request_context_ = profile->GetRequestContext(); @@ -39,6 +39,18 @@ base::BindOnce(&DialMediaSinkServiceProxy::StopOnIOThread, this)); } +void DialMediaSinkServiceProxy::SetObserver( + DialMediaSinkServiceObserver* observer) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + observer_ = observer; +} + +void DialMediaSinkServiceProxy::ClearObserver( + DialMediaSinkServiceObserver* observer) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + observer_ = nullptr; +} + void DialMediaSinkServiceProxy::SetDialMediaSinkServiceForTest( std::unique_ptr<DialMediaSinkServiceImpl> dial_media_sink_service) { DCHECK(dial_media_sink_service); @@ -54,6 +66,7 @@ base::Bind(&DialMediaSinkServiceProxy::OnSinksDiscoveredOnIOThread, this), request_context_.get()); + dial_media_sink_service_->SetObserver(observer_); } dial_media_sink_service_->Start(); @@ -64,6 +77,7 @@ return; dial_media_sink_service_->Stop(); + dial_media_sink_service_->ClearObserver(observer_); dial_media_sink_service_.reset(); }
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_proxy.h b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_proxy.h index b11bad1..8efeca8 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_proxy.h +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_proxy.h
@@ -25,6 +25,7 @@ namespace media_router { class DialMediaSinkServiceImpl; +class DialMediaSinkServiceObserver; // A wrapper class of DialMediaSinkService handling thread hopping between UI // and IO threads. This class is thread safe. Public APIs should be invoked on @@ -50,6 +51,13 @@ // Start() is cleared. void Stop() override; + // Does not take ownership of |observer|. Caller should make sure |observer| + // object outlives |this|. + void SetObserver(DialMediaSinkServiceObserver* observer); + + // Sets |observer_| to nullptr. + void ClearObserver(DialMediaSinkServiceObserver* observer); + void SetDialMediaSinkServiceForTest( std::unique_ptr<DialMediaSinkServiceImpl> dial_media_sink_service); @@ -75,6 +83,8 @@ private: std::unique_ptr<DialMediaSinkServiceImpl> dial_media_sink_service_; + DialMediaSinkServiceObserver* observer_; + scoped_refptr<net::URLRequestContextGetter> request_context_; DISALLOW_COPY_AND_ASSIGN(DialMediaSinkServiceProxy);
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc index 147a1f8..f350c63 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" +#include "base/strings/string_number_conversions.h" #include "chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h" #include "chrome/browser/media/router/discovery/mdns/dns_sd_delegate.h" #include "chrome/browser/media/router/discovery/mdns/dns_sd_registry.h" @@ -66,6 +67,11 @@ extra_data.ip_address = ip_address; extra_data.port = service.service_host_port.port(); extra_data.model_name = service_data["md"]; + extra_data.capabilities = cast_channel::CastDeviceCapability::NONE; + + unsigned capacities; + if (base::StringToUint(service_data["ca"], &capacities)) + extra_data.capabilities = capacities; cast_sink->set_sink(sink); cast_sink->set_cast_data(extra_data); @@ -175,6 +181,11 @@ std::move(cast_sinks))); } +void CastMediaSinkService::OnDialSinkAdded(const MediaSinkInternal& sink) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + cast_media_sink_service_impl_->OnDialSinkAdded(sink); +} + void CastMediaSinkService::OnSinksDiscoveredOnIOThread( std::vector<MediaSinkInternal> sinks) { // TODO(crbug.com/749305): Migrate the discovery code to use sequences.
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h index 1559dbe..3505b64a 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h
@@ -10,6 +10,7 @@ #include "base/gtest_prod_util.h" #include "base/memory/ref_counted.h" +#include "chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h" #include "chrome/browser/media/router/discovery/mdns/dns_sd_delegate.h" #include "chrome/browser/media/router/discovery/mdns/dns_sd_registry.h" #include "chrome/common/media_router/discovery/media_sink_internal.h" @@ -29,6 +30,7 @@ // Public APIs should be invoked on the UI thread. class CastMediaSinkService : public MediaSinkService, + public DialMediaSinkServiceObserver, public DnsSdRegistry::DnsSdObserver, public base::RefCountedThreadSafe<CastMediaSinkService> { public: @@ -54,7 +56,6 @@ ~CastMediaSinkService() override; private: - friend class base::RefCountedThreadSafe<CastMediaSinkService>; friend class CastMediaSinkServiceTest; @@ -71,6 +72,9 @@ void OnDnsSdEvent(const std::string& service_type, const DnsSdRegistry::DnsSdServiceList& services) override; + // DialMediaSinkServiceObserver implementation + void OnDialSinkAdded(const MediaSinkInternal& sink) override; + // Raw pointer to DnsSdRegistry instance, which is a global leaky singleton // and lives as long as the browser process. DnsSdRegistry* dns_sd_registry_ = nullptr;
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc index 37402d6f..26cf335 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc
@@ -6,10 +6,34 @@ #include "base/memory/ptr_util.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/media/router/discovery/media_sink_service_base.h" #include "chrome/common/media_router/discovery/media_sink_internal.h" +#include "chrome/common/media_router/discovery/media_sink_service.h" +#include "chrome/common/media_router/media_sink.h" #include "components/cast_channel/cast_socket_service.h" #include "components/net_log/chrome_net_log.h" +namespace { + +media_router::MediaSinkInternal CreateCastSinkFromDialSink( + const media_router::MediaSinkInternal& dial_sink) { + const std::string& unique_id = dial_sink.sink().id(); + const std::string& friendly_name = dial_sink.sink().name(); + media_router::MediaSink sink(unique_id, friendly_name, + media_router::SinkIconType::CAST); + + media_router::CastSinkExtraData extra_data; + extra_data.ip_address = dial_sink.dial_data().ip_address; + extra_data.port = media_router::CastMediaSinkServiceImpl::kCastControlPort; + extra_data.model_name = dial_sink.dial_data().model_name; + extra_data.discovered_by_dial = true; + extra_data.capabilities = cast_channel::CastDeviceCapability::NONE; + + return media_router::MediaSinkInternal(sink, extra_data); +} + +} // namespace + namespace media_router { // static @@ -40,6 +64,30 @@ MediaSinkServiceBase::StopTimer(); } +void CastMediaSinkServiceImpl::OnFetchCompleted() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + current_sinks_.clear(); + + // Copy cast sink from mDNS service to |current_sinks_|. + for (const auto& sink_it : current_sinks_by_mdns_) { + DVLOG(2) << "Discovered by mdns [name]: " << sink_it.second.sink().name() + << " [ip_address]: " + << sink_it.second.cast_data().ip_address.ToString(); + current_sinks_.insert(sink_it.second); + } + + // Copy cast sink from DIAL discovery to |current_sinks_|. + for (const auto& sink_it : current_sinks_by_dial_) { + DVLOG(2) << "Discovered by dial [name]: " << sink_it.second.sink().name() + << " [ip_address]: " + << sink_it.second.cast_data().ip_address.ToString(); + if (!base::ContainsKey(current_sinks_by_mdns_, sink_it.first)) + current_sinks_.insert(sink_it.second); + } + + MediaSinkServiceBase::OnFetchCompleted(); +} + void CastMediaSinkServiceImpl::RecordDeviceCounts() { metrics_.RecordDeviceCountsIfNeeded(current_sinks_.size(), current_service_ip_endpoints_.size()); @@ -67,17 +115,8 @@ << " [error_state]: " << cast_channel::ChannelErrorToString(error_state); net::IPEndPoint ip_endpoint = socket.ip_endpoint(); - auto sink_it = std::find_if( - current_sinks_.begin(), current_sinks_.end(), - [&](const MediaSinkInternal& sink) { - return sink.cast_data().ip_address == ip_endpoint.address() && - sink.cast_data().port == ip_endpoint.port(); - }); - - if (sink_it == current_sinks_.end()) - return; - - current_sinks_.erase(sink_it); + current_sinks_by_dial_.erase(ip_endpoint); + current_sinks_by_mdns_.erase(ip_endpoint); MediaSinkServiceBase::RestartTimer(); } @@ -119,8 +158,31 @@ DVLOG(2) << "Ading sink to current_sinks_ [name]: " << updated_sink.sink().name(); - current_sinks_.insert(updated_sink); + net::IPEndPoint ip_endpoint(cast_sink.cast_data().ip_address, + cast_sink.cast_data().port); + // Add or update existing cast sink. + if (updated_sink.cast_data().discovered_by_dial) { + current_sinks_by_dial_[ip_endpoint] = updated_sink; + } else { + current_sinks_by_mdns_[ip_endpoint] = updated_sink; + } MediaSinkServiceBase::RestartTimer(); } +void CastMediaSinkServiceImpl::OnDialSinkAdded(const MediaSinkInternal& sink) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + auto ip_address = sink.dial_data().ip_address; + net::IPEndPoint ip_endpoint(ip_address, kCastControlPort); + + if (base::ContainsKey(current_service_ip_endpoints_, ip_endpoint)) { + DVLOG(2) << "Sink discovered by mDNS, skip adding [name]: " + << sink.sink().name(); + return; + } + + // TODO(crbug.com/753175): Dual discovery should not try to open cast channel + // for non-Cast device. + OpenChannel(ip_endpoint, CreateCastSinkFromDialSink(sink)); +} + } // namespace media_router
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h index 7b905e337..f82ffa94 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h
@@ -42,11 +42,15 @@ void Stop() override; // MediaSinkServiceBase implementation + // Called when the discovery loop timer expires. + void OnFetchCompleted() override; void RecordDeviceCounts() override; // Opens cast channels on the IO thread. virtual void OpenChannels(std::vector<MediaSinkInternal> cast_sinks); + void OnDialSinkAdded(const MediaSinkInternal& sink); + private: friend class CastMediaSinkServiceImplTest; FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, TestOnChannelOpened); @@ -56,6 +60,8 @@ FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, TestMultipleOpenChannels); FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, TestOnChannelError); + FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, TestOnDialSinkAdded); + FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, TestOnFetchCompleted); // CastSocket::Observer implementation. void OnError(const cast_channel::CastSocket& socket, @@ -79,6 +85,14 @@ // Set of mDNS service IP endpoints from current round of discovery. std::set<net::IPEndPoint> current_service_ip_endpoints_; + using MediaSinkInternalMap = std::map<net::IPEndPoint, MediaSinkInternal>; + + // Map of sinks from current round of mDNS discovery keyed by IP address. + MediaSinkInternalMap current_sinks_by_mdns_; + + // Map of sinks from current round of DIAL discovery keyed by IP address. + MediaSinkInternalMap current_sinks_by_dial_; + // Raw pointer of leaky singleton CastSocketService, which manages adding and // removing Cast channels. cast_channel::CastSocketService* const cast_socket_service_;
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc index 078cedf..bb28759 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
@@ -16,8 +16,11 @@ #include "testing/gtest/include/gtest/gtest.h" using ::testing::_; +using ::testing::Invoke; using ::testing::Return; using ::testing::SaveArg; +using ::testing::WithArgs; +using cast_channel::ChannelError; namespace { @@ -45,6 +48,19 @@ return media_router::MediaSinkInternal(sink, extra_data); } +media_router::MediaSinkInternal CreateDialSink(int num) { + std::string friendly_name = base::StringPrintf("friendly name %d", num); + std::string unique_id = base::StringPrintf("id %d", num); + net::IPEndPoint ip_endpoint = CreateIPEndPoint(num); + + media_router::MediaSink sink(unique_id, friendly_name, + media_router::SinkIconType::GENERIC); + media_router::DialSinkExtraData extra_data; + extra_data.ip_address = ip_endpoint.address(); + extra_data.model_name = base::StringPrintf("model name %d", num); + return media_router::MediaSinkInternal(sink, extra_data); +} + } // namespace namespace media_router { @@ -86,8 +102,9 @@ media_sink_service_impl_.OnChannelOpened(cast_sink, &socket); // Verify sink content - EXPECT_EQ(media_sink_service_impl_.current_sinks_, - std::set<MediaSinkInternal>({cast_sink})); + EXPECT_CALL(mock_sink_discovered_cb_, + Run(std::vector<MediaSinkInternal>({cast_sink}))); + media_sink_service_impl_.OnFetchCompleted(); } TEST_F(CastMediaSinkServiceImplTest, TestMultipleOnChannelOpened) { @@ -110,8 +127,10 @@ media_sink_service_impl_.OnChannelOpened(cast_sink2, &socket2); media_sink_service_impl_.OnChannelOpened(cast_sink3, &socket3); - EXPECT_EQ(media_sink_service_impl_.current_sinks_, - std::set<MediaSinkInternal>({cast_sink2, cast_sink3})); + // Verify sink content + EXPECT_CALL(mock_sink_discovered_cb_, + Run(std::vector<MediaSinkInternal>({cast_sink2, cast_sink3}))); + media_sink_service_impl_.OnFetchCompleted(); } TEST_F(CastMediaSinkServiceImplTest, TestTimer) { @@ -187,8 +206,10 @@ media_sink_service_impl_.OnChannelOpened(cast_sink1, &socket1); media_sink_service_impl_.OnChannelOpened(cast_sink3, &socket3); - EXPECT_EQ(media_sink_service_impl_.current_sinks_, - std::set<MediaSinkInternal>({cast_sink1, cast_sink2, cast_sink3})); + EXPECT_CALL(mock_sink_discovered_cb_, + Run(std::vector<MediaSinkInternal>( + {cast_sink1, cast_sink2, cast_sink3}))); + media_sink_service_impl_.OnFetchCompleted(); } TEST_F(CastMediaSinkServiceImplTest, TestOnChannelError) { @@ -200,12 +221,83 @@ media_sink_service_impl_.current_service_ip_endpoints_.insert(ip_endpoint1); media_sink_service_impl_.OnChannelOpened(cast_sink, &socket); - EXPECT_EQ(1u, media_sink_service_impl_.current_sinks_.size()); + EXPECT_EQ(1u, media_sink_service_impl_.current_sinks_by_mdns_.size()); socket.SetIPEndpoint(ip_endpoint1); media_sink_service_impl_.OnError( socket, cast_channel::ChannelError::CHANNEL_NOT_OPEN); - EXPECT_TRUE(media_sink_service_impl_.current_sinks_.empty()); + EXPECT_TRUE(media_sink_service_impl_.current_sinks_by_mdns_.empty()); +} + +TEST_F(CastMediaSinkServiceImplTest, TestOnDialSinkAdded) { + MediaSinkInternal dial_sink1 = CreateDialSink(1); + MediaSinkInternal dial_sink2 = CreateDialSink(2); + net::IPEndPoint ip_endpoint1(dial_sink1.dial_data().ip_address, + CastMediaSinkServiceImpl::kCastControlPort); + net::IPEndPoint ip_endpoint2(dial_sink2.dial_data().ip_address, + CastMediaSinkServiceImpl::kCastControlPort); + + cast_channel::MockCastSocket socket1; + cast_channel::MockCastSocket socket2; + socket1.set_id(1); + socket2.set_id(2); + + // Channel 1, 2 opened. + EXPECT_CALL(*mock_cast_socket_service_, + OpenSocketInternal(ip_endpoint1, _, _, _)) + .WillOnce(DoAll( + WithArgs<2>(Invoke( + [&](const base::Callback<void(cast_channel::CastSocket * socket)>& + callback) { std::move(callback).Run(&socket1); })), + Return(1))); + EXPECT_CALL(*mock_cast_socket_service_, + OpenSocketInternal(ip_endpoint2, _, _, _)) + .WillOnce(DoAll( + WithArgs<2>(Invoke( + [&](const base::Callback<void(cast_channel::CastSocket * socket)>& + callback) { std::move(callback).Run(&socket2); })), + Return(2))); + + // Invoke CastSocketService::OpenSocket on the IO thread. + media_sink_service_impl_.OnDialSinkAdded(dial_sink1); + base::RunLoop().RunUntilIdle(); + + // Invoke CastSocketService::OpenSocket on the IO thread. + media_sink_service_impl_.OnDialSinkAdded(dial_sink2); + base::RunLoop().RunUntilIdle(); + // Verify sink content. + EXPECT_EQ(2u, media_sink_service_impl_.current_sinks_by_dial_.size()); +} + +TEST_F(CastMediaSinkServiceImplTest, TestOnFetchCompleted) { + std::vector<MediaSinkInternal> sinks; + EXPECT_CALL(mock_sink_discovered_cb_, Run(_)).WillOnce(SaveArg<0>(&sinks)); + + auto cast_sink1 = CreateCastSink(1); + auto cast_sink2 = CreateCastSink(2); + auto cast_sink3 = CreateCastSink(3); + net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1); + net::IPEndPoint ip_endpoint2 = CreateIPEndPoint(2); + net::IPEndPoint ip_endpoint3 = CreateIPEndPoint(3); + + // Cast sink 1, 2 from mDNS discovery + media_sink_service_impl_.current_sinks_by_mdns_[ip_endpoint1] = cast_sink1; + media_sink_service_impl_.current_sinks_by_mdns_[ip_endpoint2] = cast_sink2; + // Cast sink 2, 3 from dial discovery + auto extra_data = cast_sink2.cast_data(); + extra_data.discovered_by_dial = true; + extra_data.model_name += " dial"; + + media_sink_service_impl_.current_sinks_by_dial_[ip_endpoint2] = cast_sink2; + media_sink_service_impl_.current_sinks_by_dial_[ip_endpoint3] = cast_sink3; + + // Callback returns Cast sink 1, 2, 3 + media_sink_service_impl_.OnFetchCompleted(); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(base::ContainsValue(sinks, cast_sink1)); + EXPECT_TRUE(base::ContainsValue(sinks, cast_sink2)); + EXPECT_TRUE(base::ContainsValue(sinks, cast_sink3)); } } // namespace media_router
diff --git a/chrome/browser/media/router/discovery/media_sink_service_base.h b/chrome/browser/media/router/discovery/media_sink_service_base.h index 4821895..a2cc4717 100644 --- a/chrome/browser/media/router/discovery/media_sink_service_base.h +++ b/chrome/browser/media/router/discovery/media_sink_service_base.h
@@ -24,7 +24,7 @@ void SetTimerForTest(std::unique_ptr<base::Timer> timer); // Called when |finish_timer_| expires. - void OnFetchCompleted(); + virtual void OnFetchCompleted(); // Helper function to start |finish_timer_|. Create a new timer if none // exists.
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc index 6cc4568..ad801f3 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc +++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
@@ -72,8 +72,11 @@ MediaRouterMojoImpl::~MediaRouterMojoImpl() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (dial_media_sink_service_proxy_) + if (dial_media_sink_service_proxy_) { dial_media_sink_service_proxy_->Stop(); + dial_media_sink_service_proxy_->ClearObserver( + cast_media_sink_service_.get()); + } if (cast_media_sink_service_) cast_media_sink_service_->Stop(); } @@ -808,16 +811,6 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DVLOG_WITH_INSTANCE(1) << "StartDiscovery"; - if (media_router::DialLocalDiscoveryEnabled()) { - if (!dial_media_sink_service_proxy_) { - dial_media_sink_service_proxy_ = new DialMediaSinkServiceProxy( - base::Bind(&MediaRouterMojoImpl::ProvideSinks, - weak_factory_.GetWeakPtr(), "dial"), - context_); - } - dial_media_sink_service_proxy_->Start(); - } - if (media_router::CastDiscoveryEnabled()) { if (!cast_media_sink_service_) { cast_media_sink_service_ = new CastMediaSinkService( @@ -827,6 +820,18 @@ } cast_media_sink_service_->Start(); } + + if (media_router::DialLocalDiscoveryEnabled()) { + if (!dial_media_sink_service_proxy_) { + dial_media_sink_service_proxy_ = new DialMediaSinkServiceProxy( + base::Bind(&MediaRouterMojoImpl::ProvideSinks, + weak_factory_.GetWeakPtr(), "dial"), + context_); + dial_media_sink_service_proxy_->SetObserver( + cast_media_sink_service_.get()); + } + dial_media_sink_service_proxy_->Start(); + } } void MediaRouterMojoImpl::UpdateMediaSinks(
diff --git a/chrome/browser/prefs/chrome_command_line_pref_store.cc b/chrome/browser/prefs/chrome_command_line_pref_store.cc index 8ca6bbc..204ad21 100644 --- a/chrome/browser/prefs/chrome_command_line_pref_store.cc +++ b/chrome/browser/prefs/chrome_command_line_pref_store.cc
@@ -76,6 +76,8 @@ prefs::kEnableTouchpadThreeFingerClick, true}, {switches::kEnableUnifiedDesktop, prefs::kUnifiedDesktopEnabledByDefault, true}, + {chromeos::switches::kEnableCastReceiver, prefs::kCastReceiverEnabled, + true}, #endif {switches::kUnsafePacUrl, prefs::kPacHttpsUrlStrippingEnabled, false}, {switches::kEnableLocalSyncBackend,
diff --git a/chrome/browser/resources/pdf/browser_api.js b/chrome/browser/resources/pdf/browser_api.js index 37622de..34da975c 100644 --- a/chrome/browser/resources/pdf/browser_api.js +++ b/chrome/browser/resources/pdf/browser_api.js
@@ -103,9 +103,9 @@ setZoom(zoom) { if (this.zoomBehavior_ != BrowserApi.ZoomBehavior.MANAGE) return Promise.reject(new Error('Viewer does not manage browser zoom.')); - return new Promise(function(resolve, reject) { + return new Promise((resolve, reject) => { chrome.tabs.setZoom(this.streamInfo_.tabId, zoom, resolve); - }.bind(this)); + }); } /** @@ -142,13 +142,13 @@ this.zoomBehavior_ == BrowserApi.ZoomBehavior.PROPAGATE_PARENT)) return; - chrome.tabs.onZoomChange.addListener(function(info) { + chrome.tabs.onZoomChange.addListener(info => { var zoomChangeInfo = /** @type {{tabId: number, newZoomFactor: number}} */ (info); if (zoomChangeInfo.tabId != this.streamInfo_.tabId) return; listener(zoomChangeInfo.newZoomFactor); - }.bind(this)); + }); } }
diff --git a/chrome/browser/resources/pdf/elements/viewer-page-indicator/viewer-page-indicator.js b/chrome/browser/resources/pdf/elements/viewer-page-indicator/viewer-page-indicator.js index 96f7f3d..48631d8 100644 --- a/chrome/browser/resources/pdf/elements/viewer-page-indicator/viewer-page-indicator.js +++ b/chrome/browser/resources/pdf/elements/viewer-page-indicator/viewer-page-indicator.js
@@ -47,10 +47,10 @@ this.style.opacity = 1; clearTimeout(this.timerId); - this.timerId = setTimeout(function() { + this.timerId = setTimeout(() => { this.style.opacity = 0; this.timerId = undefined; - }.bind(this), displayTime); + }, displayTime); }, pageLabelsChanged: function() {
diff --git a/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js b/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js index 53e9acc5..f1751dd 100644 --- a/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js +++ b/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js
@@ -93,11 +93,11 @@ */ playAnimation_: function(isEntry) { this.animation_ = isEntry ? this.animateEntry_() : this.animateExit_(); - this.animation_.onfinish = function() { + this.animation_.onfinish = () => { this.animation_ = null; if (!this.dropdownOpen) this.$.dropdown.style.display = 'none'; - }.bind(this); + }; }, animateEntry_: function() {
diff --git a/chrome/browser/resources/pdf/pdf.js b/chrome/browser/resources/pdf/pdf.js index 632ee2b..ffc2a490 100644 --- a/chrome/browser/resources/pdf/pdf.js +++ b/chrome/browser/resources/pdf/pdf.js
@@ -123,9 +123,9 @@ this.errorScreen_ = $('error-screen'); // Can only reload if we are in a normal tab. if (chrome.tabs && this.browserApi_.getStreamInfo().tabId != -1) { - this.errorScreen_.reloadFn = function() { + this.errorScreen_.reloadFn = () => { chrome.tabs.reload(this.browserApi_.getStreamInfo().tabId); - }.bind(this); + }; } // Create the viewport. @@ -216,16 +216,16 @@ this.toolbar_.docTitle = getFilenameFromURL(this.originalUrl_); } - document.body.addEventListener('change-page', function(e) { + document.body.addEventListener('change-page', e => { this.viewport_.goToPage(e.detail.page); - }.bind(this)); + }); - document.body.addEventListener('navigate', function(e) { + document.body.addEventListener('navigate', e => { var disposition = e.detail.newtab ? Navigator.WindowOpenDisposition.NEW_BACKGROUND_TAB : Navigator.WindowOpenDisposition.CURRENT_TAB; this.navigator_.navigate(e.detail.uri, disposition); - }.bind(this)); + }); this.toolbarManager_ = new ToolbarManager(window, this.toolbar_, this.zoomToolbar_); @@ -274,7 +274,7 @@ this.toolbarManager_.hideToolbarsAfterTimeout(e); - var pageUpHandler = function() { + var pageUpHandler = () => { // Go to the previous page if we are fit-to-page. if (this.viewport_.fittingType == Viewport.FittingType.FIT_TO_PAGE) { this.viewport_.goToPage(this.viewport_.getMostVisiblePage() - 1); @@ -284,8 +284,8 @@ position.y -= this.viewport.size.height; this.viewport.position = position; } - }.bind(this); - var pageDownHandler = function() { + }; + var pageDownHandler = () => { // Go to the next page if we are fit-to-page. if (this.viewport_.fittingType == Viewport.FittingType.FIT_TO_PAGE) { this.viewport_.goToPage(this.viewport_.getMostVisiblePage() + 1); @@ -295,7 +295,7 @@ position.y += this.viewport.size.height; this.viewport.position = position; } - }.bind(this); + }; switch (e.keyCode) { case 9: // Tab key. @@ -718,10 +718,10 @@ // Throttle number of pinch events to one per frame. if (!this.sentPinchEvent_) { this.sentPinchEvent_ = true; - window.requestAnimationFrame(function() { + window.requestAnimationFrame(() => { this.sentPinchEvent_ = false; this.viewport_.pinchZoom(e); - }.bind(this)); + }); } }, @@ -733,9 +733,9 @@ onPinchEnd_: function(e) { // Using rAF for pinch end prevents pinch updates scheduled by rAF getting // sent after the pinch end. - window.requestAnimationFrame(function() { + window.requestAnimationFrame(() => { this.viewport_.pinchZoomEnd(e); - }.bind(this)); + }); }, /**
diff --git a/chrome/browser/resources/pdf/pdf_scripting_api.js b/chrome/browser/resources/pdf/pdf_scripting_api.js index fd5e2e15..a133b52 100644 --- a/chrome/browser/resources/pdf/pdf_scripting_api.js +++ b/chrome/browser/resources/pdf/pdf_scripting_api.js
@@ -53,7 +53,7 @@ this.pendingScriptingMessages_ = []; this.setPlugin(plugin); - window.addEventListener('message', function(event) { + window.addEventListener('message', event => { if (event.origin != 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai' && event.origin != 'chrome://print') { console.error( @@ -95,7 +95,7 @@ this.keyEventCallback_(DeserializeKeyEvent(event.data.keyEvent)); break; } - }.bind(this), false); + }, false); } PDFScriptingAPI.prototype = {
diff --git a/chrome/browser/resources/pdf/toolbar_manager.js b/chrome/browser/resources/pdf/toolbar_manager.js index 958b9ee..6fa82bf9 100644 --- a/chrome/browser/resources/pdf/toolbar_manager.js +++ b/chrome/browser/resources/pdf/toolbar_manager.js
@@ -233,9 +233,9 @@ return; this.toolbar_.hide(); this.sideToolbarAllowedOnly_ = true; - this.sideToolbarAllowedOnlyTimer_ = this.window_.setTimeout(function() { + this.sideToolbarAllowedOnlyTimer_ = this.window_.setTimeout(() => { this.sideToolbarAllowedOnlyTimer_ = null; - }.bind(this), FORCE_HIDE_TIMEOUT); + }, FORCE_HIDE_TIMEOUT); }, /**
diff --git a/chrome/browser/resources/pdf/viewport.js b/chrome/browser/resources/pdf/viewport.js index 54f166b..358922c 100644 --- a/chrome/browser/resources/pdf/viewport.js +++ b/chrome/browser/resources/pdf/viewport.js
@@ -397,10 +397,10 @@ newZoom = Math.max( Viewport.ZOOM_FACTOR_RANGE.min, Math.min(newZoom, Viewport.ZOOM_FACTOR_RANGE.max)); - this.mightZoom_(function() { + this.mightZoom_(() => { this.setZoomInternal_(newZoom); this.updateViewport_(); - }.bind(this)); + }); }, /** @@ -409,7 +409,7 @@ * @param {number} oldBrowserZoom the previous value of the browser zoom. */ updateZoomFromBrowserChange: function(oldBrowserZoom) { - this.mightZoom_(function() { + this.mightZoom_(() => { // Record the scroll position (relative to the top-left of the window). var oldZoom = oldBrowserZoom * this.internalZoom_; var currentScrollPos = { @@ -423,7 +423,7 @@ y: currentScrollPos.y * this.zoom }; this.updateViewport_(); - }.bind(this)); + }); }, /** @@ -565,7 +565,7 @@ * Zoom the viewport so that the page-width consumes the entire viewport. */ fitToWidth: function() { - this.mightZoom_(function() { + this.mightZoom_(() => { this.fittingType_ = Viewport.FittingType.FIT_TO_WIDTH; if (!this.documentDimensions_) return; @@ -575,7 +575,7 @@ this.computeFittingZoom_(this.documentDimensions_, true)); var page = this.getMostVisiblePage(); this.updateViewport_(); - }.bind(this)); + }); }, /** @@ -586,7 +586,7 @@ * should remain at the current scroll position. */ fitToPageInternal_: function(scrollToTopOfPage) { - this.mightZoom_(function() { + this.mightZoom_(() => { this.fittingType_ = Viewport.FittingType.FIT_TO_PAGE; if (!this.documentDimensions_) return; @@ -601,7 +601,7 @@ this.position = {x: 0, y: this.pageDimensions_[page].y * this.zoom}; } this.updateViewport_(); - }.bind(this)); + }); }, /** @@ -616,7 +616,7 @@ * Zoom out to the next predefined zoom level. */ zoomOut: function() { - this.mightZoom_(function() { + this.mightZoom_(() => { this.fittingType_ = Viewport.FittingType.NONE; var nextZoom = Viewport.ZOOM_FACTORS[0]; for (var i = 0; i < Viewport.ZOOM_FACTORS.length; i++) { @@ -625,14 +625,14 @@ } this.setZoomInternal_(nextZoom); this.updateViewport_(); - }.bind(this)); + }); }, /** * Zoom in to the next predefined zoom level. */ zoomIn: function() { - this.mightZoom_(function() { + this.mightZoom_(() => { this.fittingType_ = Viewport.FittingType.NONE; var nextZoom = Viewport.ZOOM_FACTORS[Viewport.ZOOM_FACTORS.length - 1]; for (var i = Viewport.ZOOM_FACTORS.length - 1; i >= 0; i--) { @@ -641,7 +641,7 @@ } this.setZoomInternal_(nextZoom); this.updateViewport_(); - }.bind(this)); + }); }, /** @@ -649,7 +649,7 @@ * @param {!Object} e The pinch event. */ pinchZoom: function(e) { - this.mightZoom_(function() { + this.mightZoom_(() => { this.pinchPhase_ = e.direction == 'out' ? Viewport.PinchPhase.PINCH_UPDATE_ZOOM_OUT : Viewport.PinchPhase.PINCH_UPDATE_ZOOM_IN; @@ -684,7 +684,7 @@ this.setPinchZoomInternal_(scaleDelta, frameToPluginCoordinate(e.center)); this.updateViewport_(); this.prevScale_ = e.startScaleRatio; - }.bind(this)); + }); }, pinchZoomStart: function(e) { @@ -701,14 +701,14 @@ }, pinchZoomEnd: function(e) { - this.mightZoom_(function() { + this.mightZoom_(() => { this.pinchPhase_ = Viewport.PinchPhase.PINCH_END; var scaleDelta = e.startScaleRatio / this.prevScale_; this.pinchCenter_ = e.center; this.setPinchZoomInternal_(scaleDelta, frameToPluginCoordinate(e.center)); this.updateViewport_(); - }.bind(this)); + }); this.pinchPhase_ = Viewport.PinchPhase.PINCH_NONE; this.pinchPanVector_ = null; @@ -721,7 +721,7 @@ * @param {number} page the index of the page to go to. zero-based. */ goToPage: function(page) { - this.mightZoom_(function() { + this.mightZoom_(() => { if (this.pageDimensions_.length === 0) return; if (page < 0) @@ -740,7 +740,7 @@ y: dimensions.y * this.zoom - toolbarOffset }; this.updateViewport_(); - }.bind(this)); + }); }, /** @@ -748,7 +748,7 @@ * @param {Object} documentDimensions the dimensions of the document */ setDocumentDimensions: function(documentDimensions) { - this.mightZoom_(function() { + this.mightZoom_(() => { var initialDimensions = !this.documentDimensions_; this.documentDimensions_ = documentDimensions; this.pageDimensions_ = this.documentDimensions_.pageDimensions; @@ -760,7 +760,7 @@ } this.contentSizeChanged_(); this.resize_(); - }.bind(this)); + }); }, /**
diff --git a/chrome/browser/resources/pdf/zoom_manager.js b/chrome/browser/resources/pdf/zoom_manager.js index eec9115..3ca81814 100644 --- a/chrome/browser/resources/pdf/zoom_manager.js +++ b/chrome/browser/resources/pdf/zoom_manager.js
@@ -145,16 +145,15 @@ if (this.floatingPointEquals(this.browserZoom_, zoom)) return; - this.changingBrowserZoom_ = - this.setBrowserZoomFunction_(zoom).then(function() { - this.browserZoom_ = zoom; - this.changingBrowserZoom_ = null; + this.changingBrowserZoom_ = this.setBrowserZoomFunction_(zoom).then(() => { + this.browserZoom_ = zoom; + this.changingBrowserZoom_ = null; - // The extension's zoom level may have changed while the browser zoom - // change was in progress. We call back into onPdfZoomChange to ensure - // the browser zoom is up to date. - this.onPdfZoomChange(); - }.bind(this)); + // The extension's zoom level may have changed while the browser zoom + // change was in progress. We call back into onPdfZoomChange to ensure + // the browser zoom is up to date. + this.onPdfZoomChange(); + }); } /**
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_browsertest_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_browsertest_win.cc index 66e682b5..93c73e9 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_browsertest_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_browsertest_win.cc
@@ -23,6 +23,7 @@ namespace { using ::testing::_; +using ::testing::InvokeWithoutArgs; using ::testing::StrictMock; using ::testing::Return; @@ -80,14 +81,18 @@ // Disabled due to flaky failures: https://crbug.com/753632 IN_PROC_BROWSER_TEST_F(ChromeCleanerPromptUserTest, - DISABLED_OnInfectedBrowserNotAvailable) { + OnInfectedBrowserNotAvailable) { browser()->window()->Minimize(); base::RunLoop().RunUntilIdle(); dialog_controller_->OnInfected(std::set<base::FilePath>()); + base::RunLoop run_loop; // We only set the expectation here because we want to make sure that the // prompt is shown only when the window is restored. - EXPECT_CALL(mock_delegate_, ShowChromeCleanerPrompt(_, _, _)).Times(1); + EXPECT_CALL(mock_delegate_, ShowChromeCleanerPrompt(_, _, _)).WillOnce( + InvokeWithoutArgs([&run_loop]() { + run_loop.QuitClosure().Run(); + })); browser()->window()->Restore(); base::RunLoop().RunUntilIdle(); @@ -102,12 +107,17 @@ base::RunLoop().RunUntilIdle(); dialog_controller_->OnInfected(std::set<base::FilePath>()); + base::RunLoop run_loop; + // We only set the expectation here because we want to make sure that the // prompt is shown only when the window is restored. - EXPECT_CALL(mock_delegate_, ShowChromeCleanerPrompt(_, _, _)).Times(1); + EXPECT_CALL(mock_delegate_, ShowChromeCleanerPrompt(_, _, _)).WillOnce( + InvokeWithoutArgs([&run_loop]() { + run_loop.QuitClosure().Run(); + })); CreateBrowser(ProfileManager::GetActiveUserProfile()); - base::RunLoop().RunUntilIdle(); + run_loop.Run(); } } // namespace
diff --git a/chrome/browser/ui/ash/app_list/app_list_service_ash.cc b/chrome/browser/ui/ash/app_list/app_list_service_ash.cc index 6b3e7ff..2eaaee6 100644 --- a/chrome/browser/ui/ash/app_list/app_list_service_ash.cc +++ b/chrome/browser/ui/ash/app_list/app_list_service_ash.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/ash/session_util.h" +#include "ui/app_list/app_list_features.h" #include "ui/app_list/app_list_switches.h" #include "ui/app_list/presenter/app_list_presenter_delegate_factory.h" #include "ui/app_list/presenter/app_list_presenter_impl.h" @@ -161,6 +162,8 @@ void AppListServiceAsh::ShowForAppInstall(Profile* profile, const std::string& extension_id, bool start_discovery_tracking) { + if (app_list::features::IsFullscreenAppListEnabled()) + return; ShowAndSwitchToState(app_list::AppListModel::STATE_APPS); AppListServiceImpl::ShowForAppInstall(profile, extension_id, start_discovery_tracking);
diff --git a/chrome/browser/ui/views/payments/payment_request_can_make_payment_metrics_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_can_make_payment_metrics_browsertest.cc index 6996ab9..8870cd8 100644 --- a/chrome/browser/ui/views/payments/payment_request_can_make_payment_metrics_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_request_can_make_payment_metrics_browsertest.cc
@@ -58,22 +58,26 @@ // Complete the Payment Request. PayWithCreditCardAndWait(base::ASCIIToUTF16("123")); - // Make sure the metrics are logged correctly. - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW | - JourneyLogger::CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT, - 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.TrueWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_COMPLETED, 1); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); } @@ -102,22 +106,26 @@ content::ExecuteScript(GetActiveWebContents(), click_buy_button_js)); WaitForObservedEvent(); - // Make sure the metrics are logged correctly. - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW | - JourneyLogger::CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT, - 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.TrueWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED, 1); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); } @@ -140,22 +148,26 @@ // Simulate that the user cancels the Payment Request. ClickOnCancel(); - // Make sure the metrics are logged correctly. - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW | - JourneyLogger::CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT, - 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.TrueWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); } @@ -192,20 +204,26 @@ // Complete the Payment Request. PayWithCreditCardAndWait(base::ASCIIToUTF16("123")); - // Make sure the metrics are logged correctly. - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW, 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.FalseWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_COMPLETED, 1); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); } @@ -231,20 +249,26 @@ content::ExecuteScript(GetActiveWebContents(), click_buy_button_js)); WaitForObservedEvent(); - // Make sure the metrics are logged correctly. - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW, 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.FalseWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED, 1); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); } @@ -264,20 +288,26 @@ // Simulate that the user cancels the Payment Request. ClickOnCancel(); - // Make sure the metrics are logged correctly. - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW, 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.FalseWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); } @@ -298,17 +328,26 @@ // Navigate away to trigger the log. NavigateTo("/payment_request_email_test.html"); - // Make sure the metrics are logged correctly. - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT, 1); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); ASSERT_EQ(1U, buckets.size()); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); } @@ -326,18 +365,26 @@ // Navigate away to trigger the log. NavigateTo("/payment_request_email_test.html"); - // Make sure the metrics are logged correctly. - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_COULD_NOT_MAKE_PAYMENT_AND_DID_NOT_SHOW, - 1); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); ASSERT_EQ(1U, buckets.size()); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); } @@ -359,18 +406,26 @@ // Complete the Payment Request. PayWithCreditCardAndWait(base::ASCIIToUTF16("123")); - // Make sure the metrics are logged correctly. - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_NOT_USED, - 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.NotUsed.WithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_COMPLETED, 1); - // Make sure that no canMakePayment events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); } @@ -398,18 +453,26 @@ content::ExecuteScript(GetActiveWebContents(), click_buy_button_js)); WaitForObservedEvent(); - // Make sure the metrics are logged correctly. - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_NOT_USED, - 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.NotUsed.WithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED, 1); - // Make sure that no canMakePayment events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); } @@ -431,18 +494,26 @@ // Simulate that the user cancels the Payment Request. ClickOnCancel(); - // Make sure the metrics are logged correctly. - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_NOT_USED, - 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.NotUsed.WithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); - // Make sure that no canMakePayment events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_TRUE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); } @@ -464,15 +535,26 @@ NavigateTo("/payment_request_email_test.html"); WaitForObservedEvent(); - // Make sure that a navigation is logged as a user abort. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.FalseWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); } @@ -496,15 +578,26 @@ ui_test_utils::NavigateToURL(browser(), other_origin_url); WaitForObservedEvent(); - // Make sure that a navigation is logged as a user abort. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.FalseWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); } @@ -525,15 +618,26 @@ chrome::CloseTab(browser()); WaitForObservedEvent(); - // Make sure that a tab closing is logged as a user abort. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.FalseWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); } @@ -554,15 +658,26 @@ chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); WaitForObservedEvent(); - // Make sure that a reload is logged as a user abort. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.FalseWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_PAY_CLICKED); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_RECEIVED_INSTRUMENT_DETAILS); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); }
diff --git a/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc index 7b94664..309af6cb 100644 --- a/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc
@@ -70,6 +70,8 @@ EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); } IN_PROC_BROWSER_TEST_F(PaymentRequestCompletionStatusMetricsTest, @@ -112,6 +114,8 @@ EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); } IN_PROC_BROWSER_TEST_F(PaymentRequestCompletionStatusMetricsTest, @@ -156,6 +160,8 @@ EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); } IN_PROC_BROWSER_TEST_F(PaymentRequestCompletionStatusMetricsTest, @@ -201,6 +207,8 @@ EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); } IN_PROC_BROWSER_TEST_F(PaymentRequestCompletionStatusMetricsTest, @@ -240,6 +248,8 @@ EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); } IN_PROC_BROWSER_TEST_F(PaymentRequestCompletionStatusMetricsTest, @@ -279,6 +289,8 @@ EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); } IN_PROC_BROWSER_TEST_F(PaymentRequestCompletionStatusMetricsTest, @@ -320,6 +332,8 @@ EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); } IN_PROC_BROWSER_TEST_F(PaymentRequestCompletionStatusMetricsTest, @@ -361,6 +375,8 @@ EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); } class PaymentRequestInitiatedCompletionStatusMetricsTest @@ -384,6 +400,13 @@ // No abort reason should be logged. histogram_tester.ExpectTotalCount("PaymentRequest.CheckoutFunnel.Aborted", 0); + + // There is one sample, because the request was initiated. + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples("PaymentRequest.Events"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_EQ(JourneyLogger::EVENT_INITIATED | JourneyLogger::EVENT_USER_ABORTED, + buckets[0].min); } } // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc index 1a8f9dc..fa54754 100644 --- a/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc
@@ -635,14 +635,6 @@ histogram_tester.ExpectTotalCount("PaymentRequest.NumberOfSelectionEdits", 0); histogram_tester.ExpectTotalCount("PaymentRequest.NumberOfSuggestionsShown", 0); - histogram_tester.ExpectTotalCount( - "PaymentRequest.UserHadSuggestionsForEverything", 0); - histogram_tester.ExpectTotalCount( - "PaymentRequest.UserDidNotHaveSuggestionsForEverything", 0); - histogram_tester.ExpectTotalCount( - "PaymentRequest.UserHadInitialFormOfPayment", 0); - histogram_tester.ExpectTotalCount( - "PaymentRequest.UserHadSuggestionsForEverything", 0); } class PaymentRequestCompleteSuggestionsForEverythingTest @@ -672,16 +664,6 @@ // Navigate away to abort the Payment Request and trigger the logs. NavigateTo("/payment_request_email_test.html"); - // The fact that the user had a form of payment on file should be recorded. - histogram_tester.ExpectUniqueSample( - "PaymentRequest.UserHadCompleteSuggestionsForEverything." - "EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); - histogram_tester.ExpectTotalCount( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - "EffectOnCompletion", - 0); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); @@ -719,16 +701,6 @@ // Navigate away to abort the Payment Request and trigger the logs. NavigateTo("/payment_request_email_test.html"); - // The fact that the user had no form of payment on file should be recorded. - histogram_tester.ExpectUniqueSample( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - "EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); - histogram_tester.ExpectTotalCount( - "PaymentRequest.UserHadCompleteSuggestionsForEverything." - "EffectOnCompletion", - 0); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); @@ -772,16 +744,6 @@ // Navigate away to abort the Payment Request and trigger the logs. NavigateTo("/payment_request_email_test.html"); - // The fact that the user had no form of payment on file should be recorded. - histogram_tester.ExpectUniqueSample( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - "EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); - histogram_tester.ExpectTotalCount( - "PaymentRequest.UserHadCompleteSuggestionsForEverything." - "EffectOnCompletion", - 0); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events");
diff --git a/chrome/common/media_router/discovery/media_sink_internal.cc b/chrome/common/media_router/discovery/media_sink_internal.cc index f78ca1a..66071dd 100644 --- a/chrome/common/media_router/discovery/media_sink_internal.cc +++ b/chrome/common/media_router/discovery/media_sink_internal.cc
@@ -177,7 +177,8 @@ bool CastSinkExtraData::operator==(const CastSinkExtraData& other) const { return ip_address == other.ip_address && port == other.port && model_name == other.model_name && capabilities == other.capabilities && - cast_channel_id == other.cast_channel_id; + cast_channel_id == other.cast_channel_id && + discovered_by_dial == other.discovered_by_dial; } } // namespace media_router
diff --git a/chrome/common/media_router/discovery/media_sink_internal.h b/chrome/common/media_router/discovery/media_sink_internal.h index 7babd960..83fcea8 100644 --- a/chrome/common/media_router/discovery/media_sink_internal.h +++ b/chrome/common/media_router/discovery/media_sink_internal.h
@@ -49,6 +49,9 @@ // browser reconnects to a device. int cast_channel_id = 0; + // True if Cast channel is opened from DIAL sink. + bool discovered_by_dial = false; + CastSinkExtraData(); CastSinkExtraData(const CastSinkExtraData& other); ~CastSinkExtraData();
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 7427f13c..b521f46 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -996,6 +996,10 @@ // Boolean pref indicating whether a user has enabled Tether. const char kInstantTetheringEnabled[] = "tether.enabled"; +// Boolean pref indicating whether this device supports BLE advertising. +const char kInstantTetheringBleAdvertisingSupported[] = + "tether.ble_advertising_supported"; + // Boolean pref indicating whether someone can cast to the device. const char kCastReceiverEnabled[] = "cast_receiver.enabled";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 2e5464a7..f9e7d8a1 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -332,6 +332,7 @@ extern const char kEnableQuickUnlockFingerprint[]; extern const char kInstantTetheringAllowed[]; extern const char kInstantTetheringEnabled[]; +extern const char kInstantTetheringBleAdvertisingSupported[]; extern const char kCastReceiverEnabled[]; extern const char kCastReceiverName[]; #endif // defined(OS_CHROMEOS)
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index 37dfef2..b1d2ffa4 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc
@@ -250,6 +250,9 @@ // Enables ARC OptIn flow in OOBE. const char kEnableArcOOBEOptIn[] = "enable-arc-oobe-optin"; +// Enables the Cast Receiver. +const char kEnableCastReceiver[] = "enable-cast-receiver"; + // Enables native ChromeVox support for Arc. const char kEnableChromeVoxArcSupport[] = "enable-chromevox-arc-support";
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index 0e84ffe..701cfe4 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h
@@ -80,6 +80,7 @@ CHROMEOS_EXPORT extern const char kEnableAndroidWallpapersApp[]; CHROMEOS_EXPORT extern const char kEnableArc[]; CHROMEOS_EXPORT extern const char kEnableArcOOBEOptIn[]; +CHROMEOS_EXPORT extern const char kEnableCastReceiver[]; CHROMEOS_EXPORT extern const char kEnableChromeVoxArcSupport[]; CHROMEOS_EXPORT extern const char kEnableConsumerKiosk[]; CHROMEOS_EXPORT extern const char kEnableDataSaverPrompt[];
diff --git a/chromeos/components/tether/initializer.cc b/chromeos/components/tether/initializer.cc index 6eb75e3..1eb416e 100644 --- a/chromeos/components/tether/initializer.cc +++ b/chromeos/components/tether/initializer.cc
@@ -39,22 +39,11 @@ #include "components/cryptauth/remote_beacon_seed_fetcher.h" #include "components/prefs/pref_service.h" #include "components/proximity_auth/logging/logging.h" -#include "device/bluetooth/bluetooth_adapter.h" -#include "device/bluetooth/bluetooth_adapter_factory.h" namespace chromeos { namespace tether { -namespace { - -// TODO (hansberry): Experiment with intervals to determine ideal advertising -// interval parameters. -constexpr int64_t kMinAdvertisingIntervalMilliseconds = 100; -constexpr int64_t kMaxAdvertisingIntervalMilliseconds = 100; - -} // namespace - // static Initializer* Initializer::instance_ = nullptr; @@ -67,13 +56,8 @@ NetworkStateHandler* network_state_handler, ManagedNetworkConfigurationHandler* managed_network_configuration_handler, NetworkConnect* network_connect, - NetworkConnectionHandler* network_connection_handler) { - if (!device::BluetoothAdapterFactory::IsBluetoothSupported()) { - PA_LOG(WARNING) << "Bluetooth is not supported on this device; cannot " - << "initialize Tether feature."; - return; - } - + NetworkConnectionHandler* network_connection_handler, + scoped_refptr<device::BluetoothAdapter> adapter) { if (instance_) { // The Tether feature has already been initialized. No need to do anything. return; @@ -84,7 +68,7 @@ new Initializer(cryptauth_service, std::move(notification_presenter), pref_service, token_service, network_state_handler, managed_network_configuration_handler, network_connect, - network_connection_handler); + network_connection_handler, adapter); } // static @@ -112,7 +96,8 @@ NetworkStateHandler* network_state_handler, ManagedNetworkConfigurationHandler* managed_network_configuration_handler, NetworkConnect* network_connect, - NetworkConnectionHandler* network_connection_handler) + NetworkConnectionHandler* network_connection_handler, + scoped_refptr<device::BluetoothAdapter> adapter) : cryptauth_service_(cryptauth_service), notification_presenter_(notification_presenter), pref_service_(pref_service), @@ -122,6 +107,7 @@ managed_network_configuration_handler), network_connect_(network_connect), network_connection_handler_(network_connection_handler), + adapter_(adapter), weak_ptr_factory_(this) { if (!token_service_->RefreshTokenIsAvailable( cryptauth_service_->GetAccountId())) { @@ -132,7 +118,7 @@ } PA_LOG(INFO) << "Refresh token is available; initializing tether feature."; - FetchBluetoothAdapter(); + CreateComponent(); } Initializer::~Initializer() { @@ -140,11 +126,6 @@ network_state_handler_->set_tether_sort_delegate(nullptr); } -void Initializer::FetchBluetoothAdapter() { - device::BluetoothAdapterFactory::GetAdapter(base::Bind( - &Initializer::OnBluetoothAdapterFetched, weak_ptr_factory_.GetWeakPtr())); -} - void Initializer::OnRefreshTokensLoaded() { if (!token_service_->RefreshTokenIsAvailable( cryptauth_service_->GetAccountId())) { @@ -156,25 +137,10 @@ PA_LOG(INFO) << "Refresh token has loaded; initializing tether feature."; token_service_->RemoveObserver(this); - FetchBluetoothAdapter(); + CreateComponent(); } -void Initializer::OnBluetoothAdapterFetched( - scoped_refptr<device::BluetoothAdapter> adapter) { - PA_LOG(INFO) << "Successfully fetched Bluetooth adapter. Setting advertising " - << "interval."; - - adapter->SetAdvertisingInterval( - base::TimeDelta::FromMilliseconds(kMinAdvertisingIntervalMilliseconds), - base::TimeDelta::FromMilliseconds(kMaxAdvertisingIntervalMilliseconds), - base::Bind(&Initializer::OnBluetoothAdapterAdvertisingIntervalSet, - weak_ptr_factory_.GetWeakPtr(), adapter), - base::Bind(&Initializer::OnBluetoothAdapterAdvertisingIntervalError, - weak_ptr_factory_.GetWeakPtr())); -} - -void Initializer::OnBluetoothAdapterAdvertisingIntervalSet( - scoped_refptr<device::BluetoothAdapter> adapter) { +void Initializer::CreateComponent() { PA_LOG(INFO) << "Successfully set Bluetooth advertisement interval. " << "Initializing tether feature."; @@ -186,7 +152,7 @@ base::MakeUnique<cryptauth::RemoteBeaconSeedFetcher>( cryptauth_service_->GetCryptAuthDeviceManager()); ble_connection_manager_ = base::MakeUnique<BleConnectionManager>( - cryptauth_service_, adapter, local_device_data_provider_.get(), + cryptauth_service_, adapter_, local_device_data_provider_.get(), remote_beacon_seed_fetcher_.get(), cryptauth::BluetoothThrottlerImpl::GetInstance()); tether_host_response_recorder_ = @@ -269,12 +235,6 @@ host_scan_scheduler_->ScheduleScan(); } -void Initializer::OnBluetoothAdapterAdvertisingIntervalError( - device::BluetoothAdvertisement::ErrorCode status) { - PA_LOG(ERROR) << "Failed to set Bluetooth advertisement interval; " - << "cannot use tether feature. Error code: " << status; -} - } // namespace tether } // namespace chromeos
diff --git a/chromeos/components/tether/initializer.h b/chromeos/components/tether/initializer.h index 004e69f2..c58993c 100644 --- a/chromeos/components/tether/initializer.h +++ b/chromeos/components/tether/initializer.h
@@ -71,7 +71,8 @@ NetworkStateHandler* network_state_handler, ManagedNetworkConfigurationHandler* managed_network_configuration_handler, NetworkConnect* network_connect, - NetworkConnectionHandler* network_connection_handler); + NetworkConnectionHandler* network_connection_handler, + scoped_refptr<device::BluetoothAdapter> adapter); // Shuts down the tether feature, destroying all internal classes. This should // be called before the dependencies passed to Init() are destroyed. @@ -92,19 +93,14 @@ NetworkStateHandler* network_state_handler, ManagedNetworkConfigurationHandler* managed_network_configuration_handler, NetworkConnect* network_connect, - NetworkConnectionHandler* network_connection_handler); + NetworkConnectionHandler* network_connection_handler, + scoped_refptr<device::BluetoothAdapter> adapter); ~Initializer() override; // OAuth2TokenService::Observer: void OnRefreshTokensLoaded() override; - void FetchBluetoothAdapter(); - void OnBluetoothAdapterFetched( - scoped_refptr<device::BluetoothAdapter> adapter); - void OnBluetoothAdapterAdvertisingIntervalSet( - scoped_refptr<device::BluetoothAdapter> adapter); - void OnBluetoothAdapterAdvertisingIntervalError( - device::BluetoothAdvertisement::ErrorCode status); + void CreateComponent(); void OnPreCrashStateRestored(); cryptauth::CryptAuthService* cryptauth_service_; @@ -115,6 +111,7 @@ ManagedNetworkConfigurationHandler* managed_network_configuration_handler_; NetworkConnect* network_connect_; NetworkConnectionHandler* network_connection_handler_; + scoped_refptr<device::BluetoothAdapter> adapter_; // Declare new objects in the order that they will be created during // initialization to ensure that they are destroyed in the correct order. This
diff --git a/chromeos/components/tether/initializer_unittest.cc b/chromeos/components/tether/initializer_unittest.cc index 3608c25d..ae8266bb6 100644 --- a/chromeos/components/tether/initializer_unittest.cc +++ b/chromeos/components/tether/initializer_unittest.cc
@@ -151,8 +151,7 @@ Initializer* initializer = new Initializer( cryptauth_service, notification_presenter, pref_service, token_service, network_state_handler, managed_network_configuration_handler, - network_connect, network_connection_handler); - initializer->OnBluetoothAdapterAdvertisingIntervalSet(adapter); + network_connect, network_connection_handler, adapter); delete initializer; }
diff --git a/components/metrics/net/network_metrics_provider.cc b/components/metrics/net/network_metrics_provider.cc index b6d92f8..c8fe163 100644 --- a/components/metrics/net/network_metrics_provider.cc +++ b/components/metrics/net/network_metrics_provider.cc
@@ -449,6 +449,15 @@ return; } + if (min_effective_connection_type_ == + net::EFFECTIVE_CONNECTION_TYPE_OFFLINE && + max_effective_connection_type_ == + net::EFFECTIVE_CONNECTION_TYPE_OFFLINE) { + min_effective_connection_type_ = type; + max_effective_connection_type_ = type; + return; + } + min_effective_connection_type_ = std::min(min_effective_connection_type_, effective_connection_type_); max_effective_connection_type_ = @@ -457,6 +466,9 @@ DCHECK_EQ( min_effective_connection_type_ == net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN, max_effective_connection_type_ == net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN); + DCHECK_EQ( + min_effective_connection_type_ == net::EFFECTIVE_CONNECTION_TYPE_OFFLINE, + max_effective_connection_type_ == net::EFFECTIVE_CONNECTION_TYPE_OFFLINE); } } // namespace metrics
diff --git a/components/metrics/net/network_metrics_provider.h b/components/metrics/net/network_metrics_provider.h index 0b23d70..0e732f2 100644 --- a/components/metrics/net/network_metrics_provider.h +++ b/components/metrics/net/network_metrics_provider.h
@@ -65,6 +65,8 @@ FRIEND_TEST_ALL_PREFIXES(NetworkMetricsProviderTest, EffectiveConnectionType); FRIEND_TEST_ALL_PREFIXES(NetworkMetricsProviderTest, ECTAmbiguousOnConnectionTypeChange); + FRIEND_TEST_ALL_PREFIXES(NetworkMetricsProviderTest, + ECTNotAmbiguousOnOffline); // Listens to the changes in the effective conection type. class EffectiveConnectionTypeObserver;
diff --git a/components/metrics/net/network_metrics_provider_unittest.cc b/components/metrics/net/network_metrics_provider_unittest.cc index 469a409..f9670b4 100644 --- a/components/metrics/net/network_metrics_provider_unittest.cc +++ b/components/metrics/net/network_metrics_provider_unittest.cc
@@ -97,7 +97,6 @@ // Running a request would cause the effective connection type to be computed // as 2G, and observers to be notified. estimator.RunOneRequest(); - base::RunLoop().RunUntilIdle(); EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G, network_metrics_provider.effective_connection_type_); EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G, @@ -117,7 +116,6 @@ // Running a request would cause the effective connection type to be computed // as SLOW_2G, and observers to be notified. estimator.RunOneRequest(); - base::RunLoop().RunUntilIdle(); EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G, network_metrics_provider.effective_connection_type_); EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G, @@ -166,7 +164,6 @@ // Running a request would cause the effective connection type to be computed // as 2G, and observers to be notified. estimator.RunOneRequest(); - base::RunLoop().RunUntilIdle(); EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G, network_metrics_provider.effective_connection_type_); EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G, @@ -193,4 +190,47 @@ system_profile.network().max_effective_connection_type()); } +// Verifies that the effective connection type is not set to UNKNOWN when the +// connection type is OFFLINE. +TEST_F(NetworkMetricsProviderTest, ECTNotAmbiguousOnOffline) { + for (net::EffectiveConnectionType force_ect : + {net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN, + net::EFFECTIVE_CONNECTION_TYPE_OFFLINE}) { + std::unique_ptr<net::NetworkQualityEstimatorParams> params = + base::MakeUnique<net::NetworkQualityEstimatorParams>( + std::map<std::string, std::string>()); + net::NetworkQualityEstimatorParams* params_ptr = params.get(); + net::TestNetworkQualityEstimator estimator(std::move(params)); + + std::unique_ptr<NetworkMetricsProvider::NetworkQualityEstimatorProvider> + estimator_provider(base::WrapUnique( + new TestNetworkQualityEstimatorProvider(&estimator))); + SystemProfileProto system_profile; + NetworkMetricsProvider network_metrics_provider( + std::move(estimator_provider)); + + params_ptr->SetForcedEffectiveConnectionType( + net::EFFECTIVE_CONNECTION_TYPE_2G); + estimator.RunOneRequest(); + + params_ptr->SetForcedEffectiveConnectionType(force_ect); + estimator.RunOneRequest(); + network_metrics_provider.ProvideSystemProfileMetrics(&system_profile); + EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_2G, + system_profile.network().min_effective_connection_type()); + EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_2G, + system_profile.network().max_effective_connection_type()); + + params_ptr->SetForcedEffectiveConnectionType( + net::EFFECTIVE_CONNECTION_TYPE_4G); + estimator.RunOneRequest(); + + network_metrics_provider.ProvideSystemProfileMetrics(&system_profile); + EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_4G, + system_profile.network().min_effective_connection_type()); + EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_4G, + system_profile.network().max_effective_connection_type()); + } +} + } // namespace metrics \ No newline at end of file
diff --git a/components/metrics/proto/ukm/report.proto b/components/metrics/proto/ukm/report.proto index 8627d5d..bca7902 100644 --- a/components/metrics/proto/ukm/report.proto +++ b/components/metrics/proto/ukm/report.proto
@@ -25,6 +25,10 @@ // that is incremented each time the user relaunches Chrome. optional int32 session_id = 5; + // The report id for this record. Report ids increase sequentially from + // one within a session. + optional int32 report_id = 6; + // Information about the user's browser and system configuration. optional metrics.SystemProfileProto system_profile = 2;
diff --git a/components/payments/core/journey_logger.cc b/components/payments/core/journey_logger.cc index f57b008..14c89929 100644 --- a/components/payments/core/journey_logger.cc +++ b/components/payments/core/journey_logger.cc
@@ -101,6 +101,10 @@ } void JourneyLogger::SetCanMakePaymentValue(bool value) { + // Do not log the outcome of canMakePayment in incognito mode. + if (is_incognito_) + return; + SetEventOccurred(value ? EVENT_CAN_MAKE_PAYMENT_TRUE : EVENT_CAN_MAKE_PAYMENT_FALSE); } @@ -160,7 +164,6 @@ DCHECK(!has_recorded_); has_recorded_ = true; - RecordCanMakePaymentStats(completion_status); RecordUrlKeyedMetrics(completion_status); RecordEventsMetric(completion_status); @@ -179,16 +182,8 @@ void JourneyLogger::RecordSectionSpecificStats( CompletionStatus completion_status) { - // Record whether the user had suggestions for each requested information. - bool user_had_all_requested_information = true; - - // Record whether the user had at least one complete suggestion for each - // requested section. - bool user_had_complete_suggestions_ = true; - for (int i = 0; i < NUMBER_OF_SECTIONS; ++i) { std::string name_suffix = GetHistogramNameSuffix(i, completion_status); - // Only log the metrics for a section if it was requested by the merchant. if (sections_[i].is_requested_) { base::UmaHistogramCustomCounts( @@ -207,93 +202,8 @@ "PaymentRequest.NumberOfSuggestionsShown." + name_suffix, std::min(sections_[i].number_suggestions_shown_, MAX_EXPECTED_SAMPLE), MIN_EXPECTED_SAMPLE, MAX_EXPECTED_SAMPLE, NUMBER_BUCKETS); - - if (sections_[i].number_suggestions_shown_ == 0) { - user_had_all_requested_information = false; - user_had_complete_suggestions_ = false; - } else if (!sections_[i].has_complete_suggestion_) { - user_had_complete_suggestions_ = false; - } } } - - // Record metrics about completion based on whether the user had suggestions - // for each requested information. - if (user_had_all_requested_information) { - base::UmaHistogramEnumeration( - "PaymentRequest.UserHadSuggestionsForEverything." - "EffectOnCompletion", - completion_status, COMPLETION_STATUS_MAX); - } else { - base::UmaHistogramEnumeration( - "PaymentRequest.UserDidNotHaveSuggestionsForEverything." - "EffectOnCompletion", - completion_status, COMPLETION_STATUS_MAX); - } - - // Record metrics about completion based on whether the user had complete - // suggestions for each requested information. - if (user_had_complete_suggestions_) { - base::UmaHistogramEnumeration( - "PaymentRequest.UserHadCompleteSuggestionsForEverything." - "EffectOnCompletion", - completion_status, COMPLETION_STATUS_MAX); - } else { - base::UmaHistogramEnumeration( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - "EffectOnCompletion", - completion_status, COMPLETION_STATUS_MAX); - } -} - -void JourneyLogger::RecordCanMakePaymentStats( - CompletionStatus completion_status) { - // CanMakePayment always returns true in incognito mode. Don't log the - // metrics. - if (is_incognito_) - return; - - // Record CanMakePayment usage. - UMA_HISTOGRAM_ENUMERATION("PaymentRequest.CanMakePayment.Usage", - WasCanMakePaymentUsed() ? CAN_MAKE_PAYMENT_USED - : CAN_MAKE_PAYMENT_NOT_USED, - CAN_MAKE_PAYMENT_USE_MAX); - - RecordCanMakePaymentEffectOnShow(); - RecordCanMakePaymentEffectOnCompletion(completion_status); -} - -void JourneyLogger::RecordCanMakePaymentEffectOnShow() { - if (!WasCanMakePaymentUsed()) - return; - - int effect_on_trigger = 0; - if (WasPaymentRequestTriggered()) - effect_on_trigger |= CMP_EFFECT_ON_SHOW_DID_SHOW; - if (CouldMakePayment()) - effect_on_trigger |= CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT; - - UMA_HISTOGRAM_ENUMERATION("PaymentRequest.CanMakePayment.Used.EffectOnShow", - static_cast<CmpEffectOnShow>(effect_on_trigger), - CMP_EFFECT_ON_SHOW_MAX); -} - -void JourneyLogger::RecordCanMakePaymentEffectOnCompletion( - CompletionStatus completion_status) { - if (!WasPaymentRequestTriggered()) - return; - - std::string histogram_name = "PaymentRequest.CanMakePayment."; - if (!WasCanMakePaymentUsed()) { - histogram_name += "NotUsed.WithShowEffectOnCompletion"; - } else if (CouldMakePayment()) { - histogram_name += "Used.TrueWithShowEffectOnCompletion"; - } else { - histogram_name += "Used.FalseWithShowEffectOnCompletion"; - } - - base::UmaHistogramEnumeration(histogram_name, completion_status, - COMPLETION_STATUS_MAX); } void JourneyLogger::RecordEventsMetric(CompletionStatus completion_status) { @@ -349,15 +259,6 @@ builder->AddMetric(internal::kUKMEventsMetricName, events_); } -bool JourneyLogger::WasCanMakePaymentUsed() { - return (events_ & EVENT_CAN_MAKE_PAYMENT_FALSE) > 0 || - (events_ & EVENT_CAN_MAKE_PAYMENT_TRUE) > 0; -} - -bool JourneyLogger::CouldMakePayment() { - return (events_ & EVENT_CAN_MAKE_PAYMENT_TRUE) > 0; -} - bool JourneyLogger::WasPaymentRequestTriggered() { return (events_ & EVENT_SHOWN) > 0 || (events_ & EVENT_SKIPPED_SHOW) > 0; }
diff --git a/components/payments/core/journey_logger.h b/components/payments/core/journey_logger.h index f7665b1..6b8104a 100644 --- a/components/payments/core/journey_logger.h +++ b/components/payments/core/journey_logger.h
@@ -43,15 +43,6 @@ SECTION_MAX, }; - // For the CanMakePayment histograms. - // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.payments - // GENERATED_JAVA_CLASS_NAME_OVERRIDE: CanMakePaymentUsage - enum CanMakePaymentUsage { - CAN_MAKE_PAYMENT_USED = 0, - CAN_MAKE_PAYMENT_NOT_USED = 1, - CAN_MAKE_PAYMENT_USE_MAX, - }; - // The payment method that was used by the user to complete the transaction. // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.payments // GENERATED_JAVA_CLASS_NAME_OVERRIDE: SelectedPaymentMethod @@ -62,17 +53,6 @@ SELECTED_PAYMENT_METHOD_MAX = 3, }; - // Used to mesure the impact of the CanMakePayment return value on whether the - // Payment Request is shown to the user. - // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.payments - // GENERATED_JAVA_CLASS_NAME_OVERRIDE: CanMakePaymentEffectOnShow - enum CmpEffectOnShow { - CMP_EFFECT_ON_SHOW_COULD_NOT_MAKE_PAYMENT_AND_DID_NOT_SHOW = 0, - CMP_EFFECT_ON_SHOW_DID_SHOW = 1 << 0, - CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT = 1 << 1, - CMP_EFFECT_ON_SHOW_MAX = 4, - }; - // Used to log different parameters' effect on whether the transaction was // completed. // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.payments @@ -226,19 +206,6 @@ // merchant. void RecordSectionSpecificStats(CompletionStatus completion_status); - // Records the metrics related the the CanMakePayment method unless in - // incognito mode. - void RecordCanMakePaymentStats(CompletionStatus completion_status); - - // Records CanMakePayment's return value effect on whether the Payment Request - // was shown or not. - void RecordCanMakePaymentEffectOnShow(); - - // Records the completion status depending on the the usage and return value - // of the CanMakePaymentMethod. - void RecordCanMakePaymentEffectOnCompletion( - CompletionStatus completion_status); - // Records the metric about the different events that happened during the // Payment Request. void RecordEventsMetric(CompletionStatus completion_status); @@ -246,12 +213,6 @@ // Records the Payment Request Url Keyed Metrics. void RecordUrlKeyedMetrics(CompletionStatus completion_status); - // Returns whether canMakePayment was used. - bool WasCanMakePaymentUsed(); - - // Returns whether the answer to canMakePayment was true or false; - bool CouldMakePayment(); - // Returns whether this Payment Request was triggered (shown or skipped show). bool WasPaymentRequestTriggered();
diff --git a/components/payments/core/journey_logger_unittest.cc b/components/payments/core/journey_logger_unittest.cc index c7124dc..acb1e4ab 100644 --- a/components/payments/core/journey_logger_unittest.cc +++ b/components/payments/core/journey_logger_unittest.cc
@@ -27,15 +27,13 @@ logger.SetCompleted(); - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_NOT_USED, - 1); - - // There should be no completion stats since PR was not shown to the user - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix( - "PaymentRequest.CanMakePayment.NotUsed.WithShowEffectOnCompletion"), - testing::ContainerEq(base::HistogramTester::CountsMap())); + // Make sure the correct events were logged. + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples("PaymentRequest.Events"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); } // Tests the canMakePayment stats for the case where the merchant does not use @@ -46,26 +44,20 @@ JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""), /*ukm_recorder=*/nullptr); - // Expect no log for CanMakePayment. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix("PaymentRequest.CanMakePayment"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // The merchant does not query CanMakePayment, show the PaymentRequest and the // user aborts it. logger.SetEventOccurred(JourneyLogger::EVENT_SHOWN); logger.SetRequestedInformation(true, false, false, false); logger.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER); - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_NOT_USED, - 1); - - // There should be a record for an abort when CanMakePayment is not used but - // the PR is shown to the user. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.NotUsed.WithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); + // Make sure the correct events were logged. + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples("PaymentRequest.Events"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); } // Tests the canMakePayment stats for the case where the merchant does not use @@ -76,26 +68,20 @@ JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""), /*ukm_recorder=*/nullptr); - // Expect no log for CanMakePayment. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix("PaymentRequest.CanMakePayment"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // The merchant does not query CanMakePayment, show the PaymentRequest and // there is an abort not initiated by the user. logger.SetEventOccurred(JourneyLogger::EVENT_SHOWN); logger.SetRequestedInformation(true, false, false, false); logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER); - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_NOT_USED, - 1); - - // There should be a record for an abort when CanMakePayment is not used but - // the PR is shown to the user. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.NotUsed.WithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED, 1); + // Make sure the correct events were logged. + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples("PaymentRequest.Events"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); } // Tests the canMakePayment stats for the case where the merchant does not use @@ -106,26 +92,20 @@ JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""), /*ukm_recorder=*/nullptr); - // Expect no log for CanMakePayment. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix("PaymentRequest.CanMakePayment"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // The merchant does not query CanMakePayment, show the PaymentRequest and the // user completes it. logger.SetEventOccurred(JourneyLogger::EVENT_SHOWN); logger.SetRequestedInformation(true, false, false, false); logger.SetCompleted(); - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_NOT_USED, - 1); - - // There should be a record for an abort when CanMakePayment is not used but - // the PR is shown to the user. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.NotUsed.WithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_COMPLETED, 1); + // Make sure the correct events were logged. + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples("PaymentRequest.Events"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); } // Tests the canMakePayment stats for the case where the merchant uses it, @@ -136,30 +116,18 @@ JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""), /*ukm_recorder=*/nullptr); - // Expect no log for CanMakePayment. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix("PaymentRequest.CanMakePayment"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // The user cannot make payment and the PaymentRequest is not shown. logger.SetCanMakePaymentValue(false); logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER); - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - - // The CanMakePayment effect on show should be recorded as being false and not - // shown. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_COULD_NOT_MAKE_PAYMENT_AND_DID_NOT_SHOW, - 1); - - // There should be no completion stats since PR was not shown to the user. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix( - "PaymentRequest.CanMakePayment.NotUsed.WithShowEffectOnCompletion"), - testing::ContainerEq(base::HistogramTester::CountsMap())); + // Make sure the correct events were logged. + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples("PaymentRequest.Events"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); } // Tests the canMakePayment stats for the case where the merchant uses it, @@ -170,29 +138,18 @@ JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""), /*ukm_recorder=*/nullptr); - // Expect no log for CanMakePayment. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix("PaymentRequest.CanMakePayment"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // The user can make payment and the PaymentRequest is not shown. logger.SetCanMakePaymentValue(true); logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER); - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - - // The CanMakePayment effect on show should be recorded as being true and not - // shown. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT, 1); - - // There should be no completion stats since PR was not shown to the user. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix( - "PaymentRequest.CanMakePayment.NotUsed.WithShowEffectOnCompletion"), - testing::ContainerEq(base::HistogramTester::CountsMap())); + // Make sure the correct events were logged. + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples("PaymentRequest.Events"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); } // Tests the canMakePayment stats for the case where the merchant uses it, @@ -203,11 +160,6 @@ JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""), /*ukm_recorder=*/nullptr); - // Expect no log for CanMakePayment. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix("PaymentRequest.CanMakePayment"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // The user cannot make payment, the Payment Request is shown but is aborted // by the user. logger.SetEventOccurred(JourneyLogger::EVENT_SHOWN); @@ -215,19 +167,14 @@ logger.SetCanMakePaymentValue(false); logger.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER); - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - - // The CanMakePayment effect on show should be recorded as being false and - // shown. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW, 1); - // There should be a record for an abort when CanMakePayment is false but the - // PR is shown to the user. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.FalseWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); + // Make sure the correct events were logged. + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples("PaymentRequest.Events"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); } // Tests the canMakePayment stats for the case where the merchant uses it, @@ -238,30 +185,20 @@ JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""), /*ukm_recorder=*/nullptr); - // Expect no log for CanMakePayment. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix("PaymentRequest.CanMakePayment"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // The user cannot make payment, the Payment Request is shown but is aborted. logger.SetEventOccurred(JourneyLogger::EVENT_SHOWN); logger.SetRequestedInformation(true, false, false, false); logger.SetCanMakePaymentValue(false); logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER); - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - - // The CanMakePayment effect on show should be recorded as being false and - // shown. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW, 1); - // There should be a record for an abort when CanMakePayment is false but the - // PR is shown to the user. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.FalseWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED, 1); + // Make sure the correct events were logged. + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples("PaymentRequest.Events"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); } // Tests the canMakePayment stats for the case where the merchant uses it, @@ -272,11 +209,6 @@ JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""), /*ukm_recorder=*/nullptr); - // Expect no log for CanMakePayment. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix("PaymentRequest.CanMakePayment"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // The user cannot make payment, the payment request is shown and is // completed. logger.SetEventOccurred(JourneyLogger::EVENT_SHOWN); @@ -284,20 +216,14 @@ logger.SetCanMakePaymentValue(false); logger.SetCompleted(); - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - - // The CanMakePayment effect on show should be recorded as being false and - // shown. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW, 1); - - // There should be a record for an completion when CanMakePayment is false but - // the PR is shown to the user. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.FalseWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_COMPLETED, 1); + // Make sure the correct events were logged. + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples("PaymentRequest.Events"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); } // Tests the canMakePayment stats for the case where the merchant uses it, @@ -308,11 +234,6 @@ JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""), /*ukm_recorder=*/nullptr); - // Expect no log for CanMakePayment. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix("PaymentRequest.CanMakePayment"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // The user can make payment, the Payment Request is shown and aborted by the // user. logger.SetEventOccurred(JourneyLogger::EVENT_SHOWN); @@ -320,21 +241,14 @@ logger.SetCanMakePaymentValue(true); logger.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER); - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - - // The CanMakePayment effect on show should be recorded as being true and not - // shown. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW | - JourneyLogger::CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT, - 1); - // There should be a record for an abort when CanMakePayment is true and the - // PR is shown to the user. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.TrueWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); + // Make sure the correct events were logged. + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples("PaymentRequest.Events"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); } // Tests the canMakePayment stats for the case where the merchant uses it, @@ -345,32 +259,21 @@ JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""), /*ukm_recorder=*/nullptr); - // Expect no log for CanMakePayment. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix("PaymentRequest.CanMakePayment"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - - // The user can make a payment, the request is shown but the user aborts. + // The user can make a payment, the request is shown but the transaction is + // aborted. logger.SetEventOccurred(JourneyLogger::EVENT_SHOWN); logger.SetRequestedInformation(true, false, false, false); logger.SetCanMakePaymentValue(true); logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER); - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - - // The CanMakePayment effect on show should be recorded as being true and not - // shown. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW | - JourneyLogger::CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT, - 1); - // There should be a record for an abort when CanMakePayment is true and the - // PR is shown to the user. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.TrueWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED, 1); + // Make sure the correct events were logged. + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples("PaymentRequest.Events"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); } // Tests the canMakePayment stats for the case where the merchant uses it, @@ -381,11 +284,6 @@ JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""), /*ukm_recorder=*/nullptr); - // Expect no log for CanMakePayment. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix("PaymentRequest.CanMakePayment"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // The user can make a payment, the request is shown and the user completes // the checkout. logger.SetEventOccurred(JourneyLogger::EVENT_SHOWN); @@ -393,21 +291,14 @@ logger.SetCanMakePaymentValue(true); logger.SetCompleted(); - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - - // The CanMakePayment effect on show should be recorded as being true and not - // shown. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.EffectOnShow", - JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW | - JourneyLogger::CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT, - 1); - // There should be a record for a completion when CanMakePayment is true and - // the PR is shown to the user. - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.TrueWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_COMPLETED, 1); + // Make sure the correct events were logged. + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples("PaymentRequest.Events"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); } // Tests the canMakePayment metrics are not logged if the Payment Request was @@ -418,11 +309,6 @@ JourneyLogger logger(/*is_incognito=*/true, /*url=*/GURL(""), /*ukm_recorder=*/nullptr); - // Expect no log for CanMakePayment. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix("PaymentRequest.CanMakePayment"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // The user can make a payment, the request is shown and the user completes // the checkout. logger.SetEventOccurred(JourneyLogger::EVENT_SHOWN); @@ -430,10 +316,14 @@ logger.SetCanMakePaymentValue(true); logger.SetCompleted(); - // Expect no log for CanMakePayment. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix("PaymentRequest.CanMakePayment"), - testing::ContainerEq(base::HistogramTester::CountsMap())); + // Make sure the correct events were logged. + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples("PaymentRequest.Events"); + ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); } // Tests that the completion status metrics based on whether the user had @@ -459,17 +349,6 @@ // Simulate that the user completes the checkout. logger.SetCompleted(); - // Make sure that the expected metric was logged. - histogram_tester.ExpectBucketCount( - "PaymentRequest.UserHadSuggestionsForEverything.EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_COMPLETED, 1); - - // Make sure the opposite metric was not logged. - EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix( - "PaymentRequest.UserDidNotHaveSuggestionsForEverything." - "EffectOnCompletion"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); @@ -510,17 +389,6 @@ // Simulate that the user aborts the checkout. logger.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER); - // Make sure the expected metric was logged. - histogram_tester.ExpectBucketCount( - "PaymentRequest.UserHadSuggestionsForEverything.EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); - - // Make sure the opposite metric was not logged. - EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix( - "PaymentRequest.UserDidNotHaveSuggestionsForEverything." - "EffectOnCompletion"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); @@ -561,17 +429,6 @@ // Simulate that the checkout is aborted. logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER); - // Make sure the expected metric was logged. - histogram_tester.ExpectBucketCount( - "PaymentRequest.UserHadSuggestionsForEverything.EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED, 1); - - // Make sure that the opposite metric was not logged. - EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix( - "PaymentRequest.UserDidNotHaveSuggestionsForEverything." - "EffectOnCompletion"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); @@ -613,17 +470,6 @@ // Simulate that the user completes the checkout. logger.SetCompleted(); - // Make sure the expected metric was logged. - histogram_tester.ExpectBucketCount( - "PaymentRequest.UserHadSuggestionsForEverything.EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_COMPLETED, 1); - - // Make sure the opposite metric was not logged. - EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix( - "PaymentRequest.UserDidNotHaveSuggestionsForEverything." - "EffectOnCompletion"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); @@ -664,18 +510,6 @@ // Simulate that the user completes the checkout. logger.SetCompleted(); - // Make sure the expected metrics was logged. - histogram_tester.ExpectBucketCount( - "PaymentRequest.UserDidNotHaveSuggestionsForEverything." - "EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_COMPLETED, 1); - - // Make sure the opposite metrics was not logged. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix( - "PaymentRequest.UserHadSuggestionsForEverything.EffectOnCompletion"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); @@ -716,18 +550,6 @@ // Simulate that the user aborts the checkout. logger.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER); - // Make sure the metric was logged. - histogram_tester.ExpectBucketCount( - "PaymentRequest.UserDidNotHaveSuggestionsForEverything." - "EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); - - // Make sure the opposite metric was not logged. - EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix( - "PaymentRequest.UserHadSuggestionsForEverything." - "EffectOnCompletion"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); @@ -768,18 +590,6 @@ // Simulate that the the checkout is aborted. logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER); - // Make sure the expected metric was logged. - histogram_tester.ExpectBucketCount( - "PaymentRequest.UserDidNotHaveSuggestionsForEverything." - "EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED, 1); - - // Make sure the opposite metric was not logged. - EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix( - "PaymentRequest.UserHadSuggestionsForEverything." - "EffectOnCompletion"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); @@ -821,18 +631,6 @@ // Simulate that the user aborts the checkout. logger.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER); - // Make sure the expected metric was logged. - histogram_tester.ExpectBucketCount( - "PaymentRequest.UserDidNotHaveSuggestionsForEverything." - "EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); - - // Make sure the opposite metric was not logged. - EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix( - "PaymentRequest.UserHadSuggestionsForEverything." - "EffectOnCompletion"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); @@ -875,18 +673,6 @@ // Simulate that the the checkout is aborted. logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER); - // Make sure the expected metric was logged. - histogram_tester.ExpectBucketCount( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - "EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED, 1); - - // Makes sure the opposite metric was not logged. - EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix( - "PaymentRequest.UserHadCompleteSuggestionsForEverything." - "EffectOnCompletion"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); @@ -931,18 +717,6 @@ // Simulate that the the checkout is aborted. logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER); - // Make sure that the expected metric was logged. - histogram_tester.ExpectBucketCount( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - "EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED, 1); - - // Make sure that the opposite metric was not logged. - EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix( - "PaymentRequest.UserHadCompleteSuggestionsForEverything." - "EffectOnCompletion"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); @@ -987,19 +761,6 @@ // Simulate that the the checkout is aborted. logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER); - // Make sure that the expected metric was logged. - histogram_tester.ExpectBucketCount( - "PaymentRequest.UserHadCompleteSuggestionsForEverything." - "EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED, 1); - - // Make sure that the opposite metric was not logged. - EXPECT_THAT( - histogram_tester.GetTotalCountsForPrefix( - "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." - "EffectOnCompletion"), - testing::ContainerEq(base::HistogramTester::CountsMap())); - // Make sure the correct events were logged. std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples("PaymentRequest.Events"); @@ -1047,27 +808,40 @@ logger1.SetCompleted(); logger2.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER); - // Make sure the appropriate metrics were logged for logger1. - histogram_tester.ExpectBucketCount( - "PaymentRequest.UserHadSuggestionsForEverything.EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_COMPLETED, 1); - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_USED, 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.Used.TrueWithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_COMPLETED, 1); - - // Make sure the appropriate metrics were logged for logger2. - histogram_tester.ExpectBucketCount( - "PaymentRequest.UserDidNotHaveSuggestionsForEverything." - "EffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); - histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage", - JourneyLogger::CAN_MAKE_PAYMENT_NOT_USED, - 1); - histogram_tester.ExpectBucketCount( - "PaymentRequest.CanMakePayment.NotUsed.WithShowEffectOnCompletion", - JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); + // Make sure the correct events were logged. + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples("PaymentRequest.Events"); + ASSERT_EQ(2U, buckets.size()); + // logger2 + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_FALSE(buckets[0].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); + EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); + // logger1 + EXPECT_TRUE(buckets[1].min & JourneyLogger::EVENT_SHOWN); + EXPECT_FALSE(buckets[1].min & + JourneyLogger::EVENT_HAD_NECESSARY_COMPLETE_SUGGESTIONS); + EXPECT_TRUE(buckets[1].min & + JourneyLogger::EVENT_HAD_INITIAL_FORM_OF_PAYMENT); + EXPECT_FALSE(buckets[1].min & JourneyLogger::EVENT_OTHER_ABORTED); + EXPECT_TRUE(buckets[1].min & JourneyLogger::EVENT_COMPLETED); + EXPECT_FALSE(buckets[1].min & JourneyLogger::EVENT_USER_ABORTED); + EXPECT_TRUE(buckets[1].min & JourneyLogger::EVENT_REQUEST_SHIPPING); + EXPECT_FALSE(buckets[1].min & JourneyLogger::EVENT_REQUEST_PAYER_NAME); + EXPECT_FALSE(buckets[1].min & JourneyLogger::EVENT_REQUEST_PAYER_PHONE); + EXPECT_TRUE(buckets[1].min & JourneyLogger::EVENT_REQUEST_PAYER_EMAIL); + EXPECT_TRUE(buckets[1].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_TRUE); + EXPECT_FALSE(buckets[1].min & JourneyLogger::EVENT_CAN_MAKE_PAYMENT_FALSE); } // Tests that the Payment Request UKMs are logged correctly when the user aborts
diff --git a/components/ukm/ukm_service.cc b/components/ukm/ukm_service.cc index 7ca995bb..8a2a2e4 100644 --- a/components/ukm/ukm_service.cc +++ b/components/ukm/ukm_service.cc
@@ -34,12 +34,6 @@ // initialization work. constexpr int kInitializationDelaySeconds = 5; -// True if we should record session ids in the UKM Report proto. -bool ShouldRecordSessionId() { - return base::GetFieldTrialParamByFeatureAsBool(kUkmFeature, "RecordSessionId", - false); -} - // Generates a new client id and stores it in prefs. uint64_t GenerateClientId(PrefService* pref_service) { uint64_t client_id = 0; @@ -73,6 +67,7 @@ : pref_service_(pref_service), client_id_(0), session_id_(0), + report_count_(0), client_(client), reporting_service_(client, pref_service), initialize_started_(false), @@ -192,6 +187,7 @@ void UkmService::ResetClientId() { client_id_ = GenerateClientId(pref_service_); session_id_ = LoadSessionId(pref_service_); + report_count_ = 0; } void UkmService::RegisterMetricsProvider( @@ -211,6 +207,7 @@ DVLOG(1) << "UkmService::StartInitTask"; client_id_ = LoadOrGenerateClientId(pref_service_); session_id_ = LoadSessionId(pref_service_); + report_count_ = 0; metrics_providers_.AsyncInit(base::Bind(&UkmService::FinishedInitTask, self_ptr_factory_.GetWeakPtr())); @@ -242,8 +239,8 @@ Report report; report.set_client_id(client_id_); - if (ShouldRecordSessionId()) - report.set_session_id(session_id_); + report.set_session_id(session_id_); + report.set_report_id(++report_count_); StoreRecordingsInReport(&report);
diff --git a/components/ukm/ukm_service.h b/components/ukm/ukm_service.h index c7e18cf..22b7ef5 100644 --- a/components/ukm/ukm_service.h +++ b/components/ukm/ukm_service.h
@@ -116,6 +116,9 @@ // The UKM session id stored in prefs. int32_t session_id_; + // The number of reports generated this session. + int32_t report_count_; + // Used to interact with the embedder. Weak pointer; must outlive |this| // instance. metrics::MetricsServiceClient* const client_;
diff --git a/components/ukm/ukm_service_unittest.cc b/components/ukm/ukm_service_unittest.cc index 4059680e..75b383ab 100644 --- a/components/ukm/ukm_service_unittest.cc +++ b/components/ukm/ukm_service_unittest.cc
@@ -209,7 +209,7 @@ Report proto_report = GetPersistedReport(); EXPECT_EQ(1, proto_report.sources_size()); - EXPECT_FALSE(proto_report.has_session_id()); + EXPECT_TRUE(proto_report.has_session_id()); const Source& proto_source = proto_report.sources(0); EXPECT_EQ(id, proto_source.id()); @@ -428,30 +428,24 @@ } TEST_F(UkmServiceTest, RecordSessionId) { - for (bool should_record_session_id : {true, false}) { - base::FieldTrialList field_trial_list(nullptr /* entropy_provider */); - ScopedUkmFeatureParams params( - base::FeatureList::OVERRIDE_ENABLE_FEATURE, - {{"RecordSessionId", should_record_session_id ? "true" : "false"}}); + ClearPrefs(); + UkmService service(&prefs_, &client_); + TestRecordingHelper recorder(&service); + EXPECT_EQ(0, GetPersistedLogCount()); + service.Initialize(); + task_runner_->RunUntilIdle(); + service.EnableRecording(); + service.EnableReporting(); - ClearPrefs(); - UkmService service(&prefs_, &client_); - TestRecordingHelper recorder(&service); - EXPECT_EQ(0, GetPersistedLogCount()); - service.Initialize(); - task_runner_->RunUntilIdle(); - service.EnableRecording(); - service.EnableReporting(); + auto id = UkmRecorder::GetNewSourceID(); + recorder.UpdateSourceURL(id, GURL("https://google.com/foobar")); - auto id = UkmRecorder::GetNewSourceID(); - recorder.UpdateSourceURL(id, GURL("https://google.com/foobar")); + service.Flush(); + EXPECT_EQ(1, GetPersistedLogCount()); - service.Flush(); - EXPECT_EQ(1, GetPersistedLogCount()); - - auto proto_report = GetPersistedReport(); - EXPECT_EQ(should_record_session_id, proto_report.has_session_id()); - } + auto proto_report = GetPersistedReport(); + EXPECT_TRUE(proto_report.has_session_id()); + EXPECT_EQ(1, proto_report.report_id()); } TEST_F(UkmServiceTest, SourceSize) {
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index d094ec1f9..4055636 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -89,11 +89,13 @@ using blink::WebSelection; using blink::WebSize; using blink::WebBrowserControlsState; +using blink::WebLayerTreeView; namespace content { namespace { -using ReportTimeCallback = base::Callback<void(bool, double)>; +using ReportTimeCallback = + base::Callback<void(WebLayerTreeView::SwapResult, double)>; double MonotonicallyIncreasingTime() { return static_cast<double>(base::TimeTicks::Now().ToInternalValue()) / @@ -131,12 +133,30 @@ void ReportTimeSwapPromise::DidSwap() { task_runner_->PostTask( FROM_HERE, - base::BindOnce(callback_, true, MonotonicallyIncreasingTime())); + base::BindOnce(callback_, WebLayerTreeView::SwapResult::kDidSwap, + MonotonicallyIncreasingTime())); } cc::SwapPromise::DidNotSwapAction ReportTimeSwapPromise::DidNotSwap( cc::SwapPromise::DidNotSwapReason reason) { - task_runner_->PostTask(FROM_HERE, base::BindOnce(callback_, false, 0)); + WebLayerTreeView::SwapResult result; + switch (reason) { + case cc::SwapPromise::DidNotSwapReason::SWAP_FAILS: + result = WebLayerTreeView::SwapResult::kDidNotSwapSwapFails; + break; + case cc::SwapPromise::DidNotSwapReason::COMMIT_FAILS: + result = WebLayerTreeView::SwapResult::kDidNotSwapCommitFails; + break; + case cc::SwapPromise::DidNotSwapReason::COMMIT_NO_UPDATE: + result = WebLayerTreeView::SwapResult::kDidNotSwapCommitNoUpdate; + break; + case cc::SwapPromise::DidNotSwapReason::ACTIVATION_FAILS: + result = WebLayerTreeView::SwapResult::kDidNotSwapActivationFails; + break; + } + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(callback_, result, MonotonicallyIncreasingTime())); return cc::SwapPromise::DidNotSwapAction::BREAK_PROMISE; } @@ -724,6 +744,11 @@ return layer_tree_host_->SendMessageToMicroBenchmark(id, std::move(value)); } +void RenderWidgetCompositor::SetViewportSize( + const gfx::Size& device_viewport_size) { + layer_tree_host_->SetViewportSize(device_viewport_size); +} + viz::FrameSinkId RenderWidgetCompositor::GetFrameSinkId() { return frame_sink_id_; } @@ -741,11 +766,6 @@ return animation_host_.get(); } -void RenderWidgetCompositor::SetViewportSize( - const WebSize& device_viewport_size) { - layer_tree_host_->SetViewportSize(device_viewport_size); -} - WebSize RenderWidgetCompositor::GetViewportSize() const { return layer_tree_host_->device_viewport_size(); }
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h index 083ef48c..cfaa25e 100644 --- a/content/renderer/gpu/render_widget_compositor.h +++ b/content/renderer/gpu/render_widget_compositor.h
@@ -54,7 +54,8 @@ : NON_EXPORTED_BASE(public blink::WebLayerTreeView), NON_EXPORTED_BASE(public cc::LayerTreeHostClient), NON_EXPORTED_BASE(public cc::LayerTreeHostSingleThreadClient) { - using ReportTimeCallback = base::Callback<void(bool, double)>; + using ReportTimeCallback = + base::Callback<void(blink::WebLayerTreeView::SwapResult, double)>; public: // Attempt to construct and initialize a compositor instance for the widget @@ -118,13 +119,13 @@ void SetIsForOopif(bool is_for_oopif); void SetContentSourceId(uint32_t source_id); void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id); + void SetViewportSize(const gfx::Size& device_viewport_size); // WebLayerTreeView implementation. viz::FrameSinkId GetFrameSinkId() override; void SetRootLayer(const blink::WebLayer& layer) override; void ClearRootLayer() override; cc::AnimationHost* CompositorAnimationHost() override; - void SetViewportSize(const blink::WebSize& device_viewport_size) override; blink::WebSize GetViewportSize() const override; virtual blink::WebFloatPoint adjustEventPointForPinchZoom( const blink::WebFloatPoint& point) const;
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index c60e8fc..a68560c 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -482,10 +482,6 @@ self.Fail('deqp/functional/gles3/framebufferblit/conversion_33.html', ['mac', ('nvidia', 0xfe9)], bug=654187) - # When this fails on this configuration, it fails multiple times in a row. - self.Fail('deqp/functional/gles3/shaderoperator/common_functions.html', - ['mac', 'nvidia'], bug=702336) - # Mac AMD # TODO(kbr): uncomment the following two exepectations after test # has been made more robust. @@ -493,8 +489,6 @@ # ['mac', 'amd'], bug=735483) # self.Fail('conformance2/rendering/texture-switch-performance.html', # ['mac', 'amd'], bug=735483) - self.Fail('deqp/functional/gles3/shaderoperator/common_functions.html', - ['mac', 'amd'], bug=702336) self.Fail('deqp/functional/gles3/transformfeedback/' + 'array_interleaved_lines.html', ['mac', 'amd'], bug=483282) @@ -588,8 +582,6 @@ ['mac', 'amd'], bug=642822) # Mac Intel - self.Flaky('deqp/functional/gles3/shaderoperator/common_functions.html', - ['mac', 'intel'], bug=702336) self.Fail('conformance2/rendering/framebuffer-texture-level1.html', ['mac', 'intel'], bug=680278) self.Fail('conformance2/textures/misc/angle-stuck-depth-textures.html',
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py index 1fc4fbc..241255a 100644 --- a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py +++ b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
@@ -206,7 +206,7 @@ def _CheckTestCompletion(self): self.tab.action_runner.WaitForJavaScriptCondition( - 'webglTestHarness._finished', timeout=300) + 'webglTestHarness._finished', timeout=self._GetTestTimeout()) if not self._DidWebGLTestSucceed(self.tab): self.fail(self._WebGLTestMessages(self.tab)) @@ -221,7 +221,7 @@ def _RunExtensionCoverageTest(self, test_path, *args): self._NavigateTo(test_path, self._GetExtensionHarnessScript()) self.tab.action_runner.WaitForJavaScriptCondition( - 'window._loaded', timeout=300) + 'window._loaded', timeout=self._GetTestTimeout()) extension_list = args[0] webgl_version = args[1] context_type = "webgl2" if webgl_version == 2 else "webgl" @@ -237,7 +237,7 @@ def _RunExtensionTest(self, test_path, *args): self._NavigateTo(test_path, self._GetExtensionHarnessScript()) self.tab.action_runner.WaitForJavaScriptCondition( - 'window._loaded', timeout=300) + 'window._loaded', timeout=self._GetTestTimeout()) extension = args[0] webgl_version = args[1] context_type = "webgl2" if webgl_version == 2 else "webgl" @@ -246,6 +246,13 @@ extension=extension, context_type=context_type) self._CheckTestCompletion() + def _GetTestTimeout(self): + timeout = 300 + if self._is_asan: + # Asan runs much slower and needs a longer timeout + timeout *= 2 + return timeout + @classmethod def SetupWebGLBrowserArgs(cls, browser_args): # --test-type=gpu is used only to suppress the "Google API Keys are missing"
diff --git a/extensions/shell/browser/shell_browser_main_parts.cc b/extensions/shell/browser/shell_browser_main_parts.cc index 17c2162f..d50b690 100644 --- a/extensions/shell/browser/shell_browser_main_parts.cc +++ b/extensions/shell/browser/shell_browser_main_parts.cc
@@ -250,6 +250,9 @@ } void ShellBrowserMainParts::PostMainMessageLoopRun() { + // Close apps before shutting down browser context and extensions system. + desktop_controller_->CloseAppWindows(); + // NOTE: Please destroy objects in the reverse order of their creation. browser_main_delegate_->Shutdown(); content::ShellDevToolsManagerDelegate::StopHttpHandler();
diff --git a/gpu/command_buffer/common/constants.h b/gpu/command_buffer/common/constants.h index 40fe3d57..23267992 100644 --- a/gpu/command_buffer/common/constants.h +++ b/gpu/command_buffer/common/constants.h
@@ -75,7 +75,7 @@ const size_t kDefaultMaxProgramCacheMemoryBytes = 6 * 1024 * 1024; #else const size_t kDefaultMaxProgramCacheMemoryBytes = 2 * 1024 * 1024; -const size_t kLowEndMaxProgramCacheMemoryBytes = 512 * 1024; +const size_t kLowEndMaxProgramCacheMemoryBytes = 128 * 1024; #endif // Namespace used to separate various command buffer types.
diff --git a/infra/config/cq.cfg b/infra/config/cq.cfg index 54c4888..2627a222 100644 --- a/infra/config/cq.cfg +++ b/infra/config/cq.cfg
@@ -95,7 +95,9 @@ builders { name: "win_chromium_compile_dbg_ng" } builders { name: "win_chromium_rel_ng" } builders { name: "win_chromium_x64_rel_ng" } - builders { name: "win_clang" } + # https://crbug.com/753184 temporarily disable this builder to + # shed load (?) + # builders { name: "win_clang" } } }
diff --git a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm index ddf777ee3..403fecd5 100644 --- a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm +++ b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
@@ -442,7 +442,9 @@ - (CollectionViewItem*)accountItemDetailWithError { CollectionViewAccountItem* accountItemDetail = [[CollectionViewAccountItem alloc] initWithType:ItemTypeAccountDetail]; - accountItemDetail.image = [UIImage imageNamed:@"default_avatar"]; + // TODO(crbug.com/754032): ios_default_avatar image is from a downstream iOS + // internal repository. It should be used through a provider API instead. + accountItemDetail.image = [UIImage imageNamed:@"ios_default_avatar"]; accountItemDetail.text = @"Account User Name"; accountItemDetail.detailText = @"Syncing to AccountUserNameAccount@example.com"; @@ -455,7 +457,9 @@ - (CollectionViewItem*)accountItemCheckMark { CollectionViewAccountItem* accountItemCheckMark = [[CollectionViewAccountItem alloc] initWithType:ItemTypeAccountCheckMark]; - accountItemCheckMark.image = [UIImage imageNamed:@"default_avatar"]; + // TODO(crbug.com/754032): ios_default_avatar image is from a downstream iOS + // internal repository. It should be used through a provider API instead. + accountItemCheckMark.image = [UIImage imageNamed:@"ios_default_avatar"]; accountItemCheckMark.text = @"Lorem ipsum dolor sit amet, consectetur " @"adipiscing elit, sed do eiusmod tempor " @"incididunt ut labore et dolore magna aliqua.";
diff --git a/net/android/BUILD.gn b/net/android/BUILD.gn index 3ad3410..e297c9a 100644 --- a/net/android/BUILD.gn +++ b/net/android/BUILD.gn
@@ -87,6 +87,10 @@ "//base:base_java", "//base:base_java_test_support", ] + + data_deps = [ + "//net:test_support", + ] } source_set("java_test_native_support") { @@ -173,6 +177,7 @@ java_cpp_enum("net_java_test_support_enums_srcjar") { sources = [ + "../test/embedded_test_server/embedded_test_server.h", "../test/url_request/url_request_failed_job.h", ] }
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json index afb0a1e..94de2728 100644 --- a/net/http/transport_security_state_static.json +++ b/net/http/transport_security_state_static.json
@@ -223,15 +223,13 @@ "static_spki_hashes": [ "LetsEncryptAuthorityPrimary_X1_X3", "LetsEncryptAuthorityBackup_X2_X4", - "VeriSignClass3_G4", - "VeriSignClass3_G5", - "VeriSignUniversal", "DigiCertGlobalRoot", "DigiCertEVRoot", "DigiCertAssuredIDRoot", - "COMODOCertificationAuthority", "AddTrustExternalCARoot", - "BaltimoreCyberTrustRoot" + "BaltimoreCyberTrustRoot", + "COMODORSACertificationAuthority", + "COMODOECCCertificationAuthority" ], "report_uri": "https://log.ncsccs.com/report/hpkp" } @@ -33314,7 +33312,6 @@ { "name": "crypto.is", "include_subdomains": true, "mode": "force-https", "expect_ct": true, "expect_ct_report_uri": "https://clients3.google.com/ct_upload" }, { "name": "ritter.vg", "expect_ct": true, "expect_ct_report_uri": "https://clients3.google.com/ct_upload", "expect_staple": true, "expect_staple_report_uri": "https://asac.casa/expectstaple.jsp" }, { "name": "tails.boum.org", "include_subdomains": true, "mode": "force-https" }, - { "name": "0.me.uk", "include_subdomains": true, "mode": "force-https", "pins": "ncsccs" }, { "name": "ncsccs.com", "include_subdomains": true, "mode": "force-https", "pins": "ncsccs" }, { "name": "themathematician.uk", "include_subdomains": true, "mode": "force-https", "pins": "ncsccs" }, { "name": "baas-becking.biology.utah.edu", "include_subdomains": true, "mode": "force-https" }, @@ -33363,15 +33360,6 @@ "expect_ct_report_uri": "https://tobiassachs.report-uri.io/r/default/ct/reportOnly" }, { - "name": "secretintelligence.0.me.uk", - "mode": "force-https", "include_subdomains": true, - "pins": "ncsccs", - "expect_staple": true, "include_subdomains_for_expect_staple": true, - "expect_staple_report_uri": "https://log.ncsccs.com/report/expectocsp", - "expect_ct": true, - "expect_ct_report_uri": "https://log.ncsccs.com/report/expectct" - }, - { "name": "cloudflare.com", "mode": "force-https", "include_subdomains": false, "expect_staple": true, @@ -33395,6 +33383,14 @@ "expect_staple": true, "include_subdomains_for_expect_staple": true, "expect_staple_report_uri": "https://weeblr.report-uri.io/r/default/staple/reportOnly" }, + { + "name": "0.me.uk", + "mode": "force-https", "include_subdomains": true, "pins": "ncsccs", + "expect_staple": true, "include_subdomains_for_expect_staple": true, + "expect_staple_report_uri": "https://log.ncsccs.com/report/expectstaple", + "expect_ct": true, + "expect_ct_report_uri": "https://log.ncsccs.com/report/expectct" + }, // END OF MANUAL ENTRIES // TODO(lgarron): hstspreload.org can't scan IPv6-only sites due to Google
diff --git a/net/http/transport_security_state_static.pins b/net/http/transport_security_state_static.pins index 52ccb69..2ea4f0b8 100644 --- a/net/http/transport_security_state_static.pins +++ b/net/http/transport_security_state_static.pins
@@ -1550,4 +1550,60 @@ 0fxQ8ANAe4hZ7Q7drNJ3gjTcBpUC2JD5Leo31Rpg0Gcg19hCC0Wvgmje3WYkN5Ap lBlGGSW4gNfL1IYoakRwJiNiqZ+Gb7+6kHDSVneFeO/qJakXzlByjAA6quPbYzSf +AZxAeKCINT+b72x ------END CERTIFICATE----- \ No newline at end of file +-----END CERTIFICATE----- + +# https://support.comodo.com/index.php?/Knowledgebase/Article/View/969/108/root-comodo-rsa-certification-authority-sha-2 +COMODORSACertificationAuthority +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- + +# https://bugzilla.mozilla.org/show_bug.cgi?id=421946 +COMODOECCCertificationAuthority +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE-----
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc index 6e39d433..3528b40e 100644 --- a/net/nqe/network_quality_estimator.cc +++ b/net/nqe/network_quality_estimator.cc
@@ -353,7 +353,7 @@ base::TimeTicks now = tick_clock_->NowTicks(); last_main_frame_request_ = now; - MaybeComputeEffectiveConnectionType(); + ComputeEffectiveConnectionType(); effective_connection_type_at_last_main_frame_ = effective_connection_type_; estimated_quality_at_last_main_frame_ = network_quality_; @@ -377,6 +377,8 @@ weak_ptr_factory_.GetWeakPtr(), measuring_delay), measuring_delay); } + } else { + MaybeComputeEffectiveConnectionType(); } throughput_analyzer_->NotifyStartTransaction(request); }
diff --git a/net/nqe/network_quality_estimator_test_util.cc b/net/nqe/network_quality_estimator_test_util.cc index 17af4235..ff39d6f 100644 --- a/net/nqe/network_quality_estimator_test_util.cc +++ b/net/nqe/network_quality_estimator_test_util.cc
@@ -87,6 +87,27 @@ EXPECT_TRUE(embedded_test_server_.Start()); } +TestNetworkQualityEstimator::TestNetworkQualityEstimator( + std::unique_ptr<NetworkQualityEstimatorParams> params) + : TestNetworkQualityEstimator(std::move(params), + base::MakeUnique<BoundTestNetLog>()) {} + +TestNetworkQualityEstimator::TestNetworkQualityEstimator( + std::unique_ptr<NetworkQualityEstimatorParams> params, + std::unique_ptr<BoundTestNetLog> net_log) + : NetworkQualityEstimator(std::unique_ptr<ExternalEstimateProvider>(), + std::move(params), + net_log->bound().net_log()), + current_network_type_(NetworkChangeNotifier::CONNECTION_UNKNOWN), + accuracy_recording_intervals_set_(false), + rand_double_(0.0), + embedded_test_server_(base::FilePath(kTestFilePath)), + suppress_notifications_for_testing_(false), + net_log_(std::move(net_log)) { + // Set up the embedded test server. + EXPECT_TRUE(embedded_test_server_.Start()); +} + TestNetworkQualityEstimator::~TestNetworkQualityEstimator() {} void TestNetworkQualityEstimator::RunOneRequest() {
diff --git a/net/nqe/network_quality_estimator_test_util.h b/net/nqe/network_quality_estimator_test_util.h index b536718..34a4e0e 100644 --- a/net/nqe/network_quality_estimator_test_util.h +++ b/net/nqe/network_quality_estimator_test_util.h
@@ -60,6 +60,9 @@ bool suppress_notifications_for_testing, std::unique_ptr<BoundTestNetLog> net_log); + explicit TestNetworkQualityEstimator( + std::unique_ptr<NetworkQualityEstimatorParams> params); + ~TestNetworkQualityEstimator() override; // Runs one URL request to completion. @@ -233,6 +236,10 @@ explicit LocalHttpTestServer(const base::FilePath& document_root); }; + TestNetworkQualityEstimator( + std::unique_ptr<NetworkQualityEstimatorParams> params, + std::unique_ptr<BoundTestNetLog> net_log); + // NetworkQualityEstimator implementation that returns the overridden // network // id (instead of invoking platform APIs).
diff --git a/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java b/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java index d0a8ae3f..153760e 100644 --- a/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java +++ b/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java
@@ -17,6 +17,8 @@ import org.chromium.base.Log; import org.chromium.base.ThreadUtils; +import org.chromium.net.X509Util; +import org.chromium.net.test.util.CertTestUtil; import java.io.File; @@ -61,6 +63,12 @@ private Context mContext; private final Object mImplMonitor = new Object(); + // Whether the server should use HTTP or HTTPS. + public enum ServerHTTPSSetting { + USE_HTTP, + USE_HTTPS, + } + /** * Exception class raised on failure in the EmbeddedTestServer. */ @@ -125,8 +133,10 @@ * * @param context The context to use to bind the service. This will also be used to unbind * the service at server destruction time. + * @param httpsSetting Whether the server should use HTTPS. */ - public void initializeNative(Context context) throws InterruptedException { + public void initializeNative(Context context, ServerHTTPSSetting httpsSetting) + throws InterruptedException { mContext = context; Intent intent = new Intent(EMBEDDED_TEST_SERVER_SERVICE); @@ -144,7 +154,7 @@ Log.i(TAG, "EmbeddedTestServer service connected."); boolean initialized = false; try { - initialized = mImpl.initializeNative(); + initialized = mImpl.initializeNative(httpsSetting == ServerHTTPSSetting.USE_HTTPS); } catch (RemoteException e) { Log.e(TAG, "Failed to initialize native server.", e); initialized = false; @@ -153,6 +163,16 @@ if (!initialized) { throw new EmbeddedTestServerFailure("Failed to initialize native server."); } + + if (httpsSetting == ServerHTTPSSetting.USE_HTTPS) { + try { + String rootCertPemPath = mImpl.getRootCertPemPath(); + X509Util.addTestRootCertificate(CertTestUtil.pemToDer(rootCertPemPath)); + } catch (Exception e) { + throw new EmbeddedTestServerFailure( + "Failed to install root certificate from native server.", e); + } + } } } @@ -194,6 +214,22 @@ } } + /** Configure the server to use a particular type of SSL certificate. + * + * @param serverCertificate The type of certificate the server should use. + */ + public void setSSLConfig(int serverCertificate) { + try { + synchronized (mImplMonitor) { + checkServiceLocked(); + mImpl.setSSLConfig(serverCertificate); + } + } catch (RemoteException e) { + throw new EmbeddedTestServerFailure( + "Failed to set server certificate: " + e.toString()); + } + } + /** Serve files from the provided directory. * * @param directory The directory from which files should be served. @@ -309,6 +345,25 @@ return initializeAndStartServer(server, context); } + /** Create and initialize an HTTPS server with the default handlers. + * + * This handles native object initialization, server configuration, and server initialization. + * On returning, the server is ready for use. + * + * @param context The context in which the server will run. + * @param serverCertificate The certificate option that the server will use. + * @return The created server. + */ + public static EmbeddedTestServer createAndStartHTTPSServer( + Context context, int serverCertificate) throws InterruptedException { + Assert.assertNotEquals("EmbeddedTestServer should not be created on UiThread, " + + "the instantiation will hang forever waiting for tasks" + + " to post to UI thread", + Looper.getMainLooper(), Looper.myLooper()); + EmbeddedTestServer server = new EmbeddedTestServer(); + return initializeAndStartHTTPSServer(server, context, serverCertificate); + } + /** Initialize a server with the default handlers. * * This handles native object initialization, server configuration, and server initialization. @@ -320,7 +375,7 @@ */ public static <T extends EmbeddedTestServer> T initializeAndStartServer( T server, Context context) throws InterruptedException { - server.initializeNative(context); + server.initializeNative(context, ServerHTTPSSetting.USE_HTTP); server.addDefaultHandlers(""); if (!server.start()) { throw new EmbeddedTestServerFailure("Failed to start serving using default handlers."); @@ -328,6 +383,28 @@ return server; } + /** Initialize a server with the default handlers that uses HTTPS with the given certificate + * option. + * + * This handles native object initialization, server configuration, and server initialization. + * On returning, the server is ready for use. + * + * @param server The server instance that will be initialized. + * @param context The context in which the server will run. + * @param serverCertificate The certificate option that the server will use. + * @return The created server. + */ + public static <T extends EmbeddedTestServer> T initializeAndStartHTTPSServer( + T server, Context context, int serverCertificate) throws InterruptedException { + server.initializeNative(context, ServerHTTPSSetting.USE_HTTPS); + server.addDefaultHandlers(""); + server.setSSLConfig(serverCertificate); + if (!server.start()) { + throw new EmbeddedTestServerFailure("Failed to start serving using default handlers."); + } + return server; + } + /** Get the full URL for the given relative URL. * * @param relativeUrl The relative URL for which a full URL will be obtained.
diff --git a/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServerImpl.java b/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServerImpl.java index 6455fb2..cbe092d 100644 --- a/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServerImpl.java +++ b/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServerImpl.java
@@ -61,10 +61,11 @@ /** Initialize the native EmbeddedTestServer object. * + * @param https True if the server should use HTTPS, and false otherwise. * @return Whether the native object was successfully initialized. */ @Override - public boolean initializeNative() { + public boolean initializeNative(final boolean https) { // This is necessary as EmbeddedTestServerImpl is in a different process than the tests // using it, so it needs to initialize its own application context. ContextUtils.initApplicationContext(mContext.getApplicationContext()); @@ -82,7 +83,9 @@ runOnHandlerThread(new Callable<Void>() { @Override public Void call() { - if (mNativeEmbeddedTestServer == 0) nativeInit(UrlUtils.getIsolatedTestRoot()); + if (mNativeEmbeddedTestServer == 0) { + nativeInit(UrlUtils.getIsolatedTestRoot(), https); + } assert mNativeEmbeddedTestServer != 0; return null; } @@ -107,6 +110,20 @@ }); } + /** Returns the path to a PEM file containing the server's root certificate. + * + * @return The path to a PEM file containing the server's root certificate. + */ + @Override + public String getRootCertPemPath() { + return runOnHandlerThread(new Callable<String>() { + @Override + public String call() { + return nativeGetRootCertPemPath(mNativeEmbeddedTestServer); + } + }); + } + /** Add the default handlers and serve files from the provided directory relative to the * external storage directory. * @@ -124,6 +141,21 @@ }); } + /** Configure the server to use a particular type of SSL certificate. + * + * @param serverCertificate The type of certificate the server should use. + */ + @Override + public void setSSLConfig(final int serverCertificate) { + runOnHandlerThread(new Callable<Void>() { + @Override + public Void call() { + nativeSetSSLConfig(mNativeEmbeddedTestServer, serverCertificate); + return null; + } + }); + } + /** Register multiple request handlers. * Handlers must be registered before starting the server. * @@ -263,12 +295,15 @@ mNativeEmbeddedTestServer = 0; } - private native void nativeInit(String testDataDir); + private native void nativeInit(String testDataDir, boolean https); private native void nativeDestroy(long nativeEmbeddedTestServerAndroid); private native boolean nativeStart(long nativeEmbeddedTestServerAndroid); + private native String nativeGetRootCertPemPath(long nativeEmbeddedTestServerAndroid); private native boolean nativeShutdownAndWaitUntilComplete(long nativeEmbeddedTestServerAndroid); private native void nativeAddDefaultHandlers( long nativeEmbeddedTestServerAndroid, String directoryPath); + private native void nativeSetSSLConfig( + long nativeEmbeddedTestServerAndroid, int serverCertificate); private native void nativeRegisterRequestHandler( long nativeEmbeddedTestServerAndroid, long handler); private native String nativeGetURL(long nativeEmbeddedTestServerAndroid, String relativeUrl);
diff --git a/net/test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerImpl.aidl b/net/test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerImpl.aidl index 707c3f7a..7a6e2031 100644 --- a/net/test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerImpl.aidl +++ b/net/test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerImpl.aidl
@@ -9,7 +9,7 @@ interface IEmbeddedTestServerImpl { /** Initialize the native object. */ - boolean initializeNative(); + boolean initializeNative(boolean https); /** Start the server. * @@ -17,6 +17,12 @@ */ boolean start(); + /** Get the path of the server's root certificate. + * + * @return The pathname of a PEM file containing the server's root certificate. + */ + String getRootCertPemPath(); + /** Add the default handlers and serve files from the provided directory relative to the * external storage directory. * @@ -25,6 +31,12 @@ */ void addDefaultHandlers(String directoryPath); + /** Configure the server to use a particular type of SSL certificate. + * + * @param serverCertificate The type of certificate the server should use. + */ + void setSSLConfig(int serverCertificate); + /** Serve files from the provided directory. * * @param directoryPath The path of the directory from which files should be served.
diff --git a/net/test/embedded_test_server/android/embedded_test_server_android.cc b/net/test/embedded_test_server/android/embedded_test_server_android.cc index 7c82de5..a9c38cb 100644 --- a/net/test/embedded_test_server/android/embedded_test_server_android.cc +++ b/net/test/embedded_test_server/android/embedded_test_server_android.cc
@@ -39,8 +39,12 @@ EmbeddedTestServerAndroid::EmbeddedTestServerAndroid( JNIEnv* env, - const JavaRef<jobject>& jobj) - : weak_java_server_(env, jobj), test_server_(), connection_listener_(this) { + const JavaRef<jobject>& jobj, + jboolean jhttps) + : weak_java_server_(env, jobj), + test_server_(jhttps ? EmbeddedTestServer::TYPE_HTTPS + : EmbeddedTestServer::TYPE_HTTP), + connection_listener_(this) { test_server_.SetConnectionListener(&connection_listener_); Java_EmbeddedTestServerImpl_setNativePtr(env, jobj, reinterpret_cast<intptr_t>(this)); @@ -56,6 +60,13 @@ return test_server_.Start(); } +ScopedJavaLocalRef<jstring> EmbeddedTestServerAndroid::GetRootCertPemPath( + JNIEnv* env, + const JavaParamRef<jobject>& jobj) const { + return base::android::ConvertUTF8ToJavaString( + env, test_server_.GetRootCertPemPath().value()); +} + jboolean EmbeddedTestServerAndroid::ShutdownAndWaitUntilComplete( JNIEnv* env, const JavaParamRef<jobject>& jobj) { @@ -80,6 +91,13 @@ test_server_.AddDefaultHandlers(directory); } +void EmbeddedTestServerAndroid::SetSSLConfig(JNIEnv* jenv, + const JavaParamRef<jobject>& jobj, + jint jserver_certificate) { + test_server_.SetSSLConfig( + static_cast<EmbeddedTestServer::ServerCertificate>(jserver_certificate)); +} + typedef std::unique_ptr<HttpResponse> (*HandleRequestPtr)( const HttpRequest& request); @@ -119,12 +137,13 @@ static void Init(JNIEnv* env, const JavaParamRef<jobject>& jobj, - const JavaParamRef<jstring>& jtest_data_dir) { + const JavaParamRef<jstring>& jtest_data_dir, + jboolean jhttps) { TRACE_EVENT0("native", "EmbeddedTestServerAndroid::Init"); base::FilePath test_data_dir( base::android::ConvertJavaStringToUTF8(env, jtest_data_dir)); base::InitAndroidTestPaths(test_data_dir); - new EmbeddedTestServerAndroid(env, jobj); + new EmbeddedTestServerAndroid(env, jobj, jhttps); } // static
diff --git a/net/test/embedded_test_server/android/embedded_test_server_android.h b/net/test/embedded_test_server/android/embedded_test_server_android.h index bc993c9..ea679940 100644 --- a/net/test/embedded_test_server/android/embedded_test_server_android.h +++ b/net/test/embedded_test_server/android/embedded_test_server_android.h
@@ -22,13 +22,18 @@ class EmbeddedTestServerAndroid { public: EmbeddedTestServerAndroid(JNIEnv* env, - const base::android::JavaRef<jobject>& obj); + const base::android::JavaRef<jobject>& obj, + jboolean jhttps); ~EmbeddedTestServerAndroid(); void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); jboolean Start(JNIEnv* env, const base::android::JavaParamRef<jobject>& jobj); + base::android::ScopedJavaLocalRef<jstring> GetRootCertPemPath( + JNIEnv* jenv, + const base::android::JavaParamRef<jobject>& jobj) const; + jboolean ShutdownAndWaitUntilComplete( JNIEnv* env, const base::android::JavaParamRef<jobject>& jobj); @@ -43,6 +48,10 @@ const base::android::JavaParamRef<jobject>& jobj, const base::android::JavaParamRef<jstring>& jdirectory_path); + void SetSSLConfig(JNIEnv* jenv, + const base::android::JavaParamRef<jobject>& jobj, + jint jserver_certificate); + void RegisterRequestHandler(JNIEnv* jenv, const base::android::JavaParamRef<jobject>& jobj, jlong handler);
diff --git a/net/test/embedded_test_server/embedded_test_server.cc b/net/test/embedded_test_server/embedded_test_server.cc index 83112a2..78e182f8 100644 --- a/net/test/embedded_test_server/embedded_test_server.cc +++ b/net/test/embedded_test_server/embedded_test_server.cc
@@ -53,12 +53,13 @@ weak_factory_(this) { DCHECK(thread_checker_.CalledOnValidThread()); - if (is_using_ssl_) { - base::ThreadRestrictions::ScopedAllowIO allow_io_for_importing_test_cert; - TestRootCerts* root_certs = TestRootCerts::GetInstance(); - base::FilePath certs_dir(GetTestCertsDirectory()); - root_certs->AddFromFile(certs_dir.AppendASCII("root_ca_cert.pem")); - } + if (!is_using_ssl_) + return; + base::ThreadRestrictions::ScopedAllowIO allow_io_for_importing_test_cert; + TestRootCerts* root_certs = TestRootCerts::GetInstance(); + bool added_root_certs = root_certs->AddFromFile(GetRootCertPemPath()); + DCHECK(added_root_certs) + << "Failed to install root cert from EmbeddedTestServer"; } EmbeddedTestServer::~EmbeddedTestServer() { @@ -184,6 +185,11 @@ &EmbeddedTestServer::ShutdownOnIOThread, base::Unretained(this))); } +// static +base::FilePath EmbeddedTestServer::GetRootCertPemPath() { + return GetTestCertsDirectory().AppendASCII("root_ca_cert.pem"); +} + void EmbeddedTestServer::ShutdownOnIOThread() { DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); weak_factory_.InvalidateWeakPtrs();
diff --git a/net/test/embedded_test_server/embedded_test_server.h b/net/test/embedded_test_server/embedded_test_server.h index f2a9307..dbcf508 100644 --- a/net/test/embedded_test_server/embedded_test_server.h +++ b/net/test/embedded_test_server/embedded_test_server.h
@@ -92,6 +92,8 @@ TYPE_HTTPS, }; + // A Java counterpart will be generated for this enum. + // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net.test enum ServerCertificate { CERT_OK, @@ -151,6 +153,8 @@ return listen_socket_.get() != NULL; } + static base::FilePath GetRootCertPemPath(); + HostPortPair host_port_pair() const { return HostPortPair::FromURL(base_url_); }
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index 3652fd2d..96a5b12 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -639,6 +639,10 @@ return false; } +bool IsLinkArea(PDFiumPage::Area area) { + return area == PDFiumPage::WEBLINK_AREA || area == PDFiumPage::DOCLINK_AREA; +} + } // namespace bool InitializeSDK() { @@ -1738,28 +1742,50 @@ } bool PDFiumEngine::OnMouseDown(const pp::MouseInputEvent& event) { - if (event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_RIGHT) { - if (selection_.empty()) - return false; - std::vector<pp::Rect> selection_rect_vector; - GetAllScreenRectsUnion(&selection_, GetVisibleRect().point(), - &selection_rect_vector); - pp::Point point = event.GetPosition(); - for (const auto& rect : selection_rect_vector) { - if (rect.Contains(point.x(), point.y())) - return false; - } - SelectionChangeInvalidator selection_invalidator(this); - selection_.clear(); - return true; + if (event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT) + return OnLeftMouseDown(event); + if (event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_MIDDLE) + return OnMiddleMouseDown(event); + if (event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_RIGHT) + return OnRightMouseDown(event); + return false; +} + +void PDFiumEngine::OnSingleClick(int page_index, int char_index) { + SetSelecting(true); + selection_.push_back(PDFiumRange(pages_[page_index].get(), char_index, 0)); +} + +void PDFiumEngine::OnMultipleClick(int click_count, + int page_index, + int char_index) { + // It would be more efficient if the SDK could support finding a space, but + // now it doesn't. + int start_index = char_index; + do { + base::char16 cur = pages_[page_index]->GetCharAtIndex(start_index); + // For double click, we want to select one word so we look for whitespace + // boundaries. For triple click, we want the whole line. + if (cur == '\n' || (click_count == 2 && (cur == ' ' || cur == '\t'))) + break; + } while (--start_index >= 0); + if (start_index) + start_index++; + + int end_index = char_index; + int total = pages_[page_index]->GetCharCount(); + while (end_index++ <= total) { + base::char16 cur = pages_[page_index]->GetCharAtIndex(end_index); + if (cur == '\n' || (click_count == 2 && (cur == ' ' || cur == '\t'))) + break; } - if (event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_LEFT && - event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_MIDDLE) { - return false; - } + selection_.push_back(PDFiumRange(pages_[page_index].get(), start_index, + end_index - start_index)); +} - SetMouseLeftButtonDown(event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT); +bool PDFiumEngine::OnLeftMouseDown(const pp::MouseInputEvent& event) { + SetMouseLeftButtonDown(true); auto selection_invalidator = base::MakeUnique<SelectionChangeInvalidator>(this); @@ -1777,13 +1803,9 @@ // Decide whether to open link or not based on user action in mouse up and // mouse move events. - if (area == PDFiumPage::WEBLINK_AREA || area == PDFiumPage::DOCLINK_AREA) + if (IsLinkArea(area)) return true; - // Prevent middle mouse button from selecting texts. - if (event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_MIDDLE) - return false; - if (page_index != -1) { last_page_mouse_down_ = page_index; double page_x; @@ -1838,37 +1860,47 @@ return true; } -void PDFiumEngine::OnSingleClick(int page_index, int char_index) { - SetSelecting(true); - selection_.push_back(PDFiumRange(pages_[page_index].get(), char_index, 0)); +bool PDFiumEngine::OnMiddleMouseDown(const pp::MouseInputEvent& event) { + SetMouseLeftButtonDown(false); + + SelectionChangeInvalidator selection_invalidator(this); + selection_.clear(); + + int unused_page_index = -1; + int unused_char_index = -1; + int unused_form_type = FPDF_FORMFIELD_UNKNOWN; + PDFiumPage::LinkTarget target; + PDFiumPage::Area area = + GetCharIndex(event.GetPosition(), &unused_page_index, &unused_char_index, + &unused_form_type, &target); + mouse_down_state_.Set(area, target); + + // Decide whether to open link or not based on user action in mouse up and + // mouse move events. + if (IsLinkArea(area)) + return true; + + // Prevent middle mouse button from selecting texts. + return false; } -void PDFiumEngine::OnMultipleClick(int click_count, - int page_index, - int char_index) { - // It would be more efficient if the SDK could support finding a space, but - // now it doesn't. - int start_index = char_index; - do { - base::char16 cur = pages_[page_index]->GetCharAtIndex(start_index); - // For double click, we want to select one word so we look for whitespace - // boundaries. For triple click, we want the whole line. - if (cur == '\n' || (click_count == 2 && (cur == ' ' || cur == '\t'))) - break; - } while (--start_index >= 0); - if (start_index) - start_index++; +bool PDFiumEngine::OnRightMouseDown(const pp::MouseInputEvent& event) { + DCHECK_EQ(PP_INPUTEVENT_MOUSEBUTTON_RIGHT, event.GetButton()); - int end_index = char_index; - int total = pages_[page_index]->GetCharCount(); - while (end_index++ <= total) { - base::char16 cur = pages_[page_index]->GetCharAtIndex(end_index); - if (cur == '\n' || (click_count == 2 && (cur == ' ' || cur == '\t'))) - break; + if (selection_.empty()) + return false; + + std::vector<pp::Rect> selection_rect_vector; + GetAllScreenRectsUnion(&selection_, GetVisibleRect().point(), + &selection_rect_vector); + pp::Point point = event.GetPosition(); + for (const auto& rect : selection_rect_vector) { + if (rect.Contains(point.x(), point.y())) + return false; } - - selection_.push_back(PDFiumRange(pages_[page_index].get(), start_index, - end_index - start_index)); + SelectionChangeInvalidator selection_invalidator(this); + selection_.clear(); + return true; } bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) { @@ -2004,10 +2036,8 @@ // We're selecting but right now we're not over text, so don't change the // current selection. - if (area != PDFiumPage::TEXT_AREA && area != PDFiumPage::WEBLINK_AREA && - area != PDFiumPage::DOCLINK_AREA) { + if (area != PDFiumPage::TEXT_AREA && !IsLinkArea(area)) return false; - } SelectionChangeInvalidator selection_invalidator(this); return ExtendSelection(page_index, char_index);
diff --git a/pdf/pdfium/pdfium_engine.h b/pdf/pdfium/pdfium_engine.h index 7dd2cee..fc3dd35 100644 --- a/pdf/pdfium/pdfium_engine.h +++ b/pdf/pdfium/pdfium_engine.h
@@ -349,6 +349,9 @@ void OnSingleClick(int page_index, int char_index); void OnMultipleClick(int click_count, int page_index, int char_index); + bool OnLeftMouseDown(const pp::MouseInputEvent& event); + bool OnMiddleMouseDown(const pp::MouseInputEvent& event); + bool OnRightMouseDown(const pp::MouseInputEvent& event); // Starts a progressive paint operation given a rectangle in screen // coordinates. Returns the index in progressive_rects_.
diff --git a/services/viz/public/cpp/compositing/struct_traits_unittest.cc b/services/viz/public/cpp/compositing/struct_traits_unittest.cc index 91b56566..681c2fb 100644 --- a/services/viz/public/cpp/compositing/struct_traits_unittest.cc +++ b/services/viz/public/cpp/compositing/struct_traits_unittest.cc
@@ -18,7 +18,6 @@ #include "cc/ipc/selection_struct_traits.h" #include "cc/ipc/shared_quad_state_struct_traits.h" #include "cc/ipc/surface_id_struct_traits.h" -#include "cc/ipc/surface_sequence_struct_traits.h" #include "cc/ipc/texture_mailbox_struct_traits.h" #include "cc/ipc/transferable_resource_struct_traits.h" #include "cc/output/compositor_frame.h" @@ -42,9 +41,11 @@ #include "services/viz/public/cpp/compositing/resource_settings_struct_traits.h" #include "services/viz/public/cpp/compositing/returned_resource_struct_traits.h" #include "services/viz/public/cpp/compositing/surface_info_struct_traits.h" +#include "services/viz/public/cpp/compositing/surface_sequence_struct_traits.h" #include "services/viz/public/interfaces/compositing/compositor_frame.mojom.h" #include "services/viz/public/interfaces/compositing/returned_resource.mojom.h" #include "services/viz/public/interfaces/compositing/surface_info.mojom.h" +#include "services/viz/public/interfaces/compositing/surface_sequence.mojom.h" #include "skia/public/interfaces/bitmap_skbitmap_struct_traits.h" #include "skia/public/interfaces/blur_image_filter_tile_mode_struct_traits.h" #include "skia/public/interfaces/image_filter_struct_traits.h" @@ -98,6 +99,19 @@ output.buffer_to_texture_target_map); } +TEST_F(StructTraitsTest, SurfaceSequence) { + const FrameSinkId frame_sink_id(2016, 1234); + const uint32_t sequence = 0xfbadbeef; + + SurfaceSequence input(frame_sink_id, sequence); + SurfaceSequence output; + mojom::SurfaceSequence::Deserialize(mojom::SurfaceSequence::Serialize(&input), + &output); + + EXPECT_EQ(frame_sink_id, output.frame_sink_id); + EXPECT_EQ(sequence, output.sequence); +} + // Note that this is a fairly trivial test of CompositorFrame serialization as // most of the heavy lifting has already been done by CompositorFrameMetadata, // RenderPass, and QuadListBasic unit tests.
diff --git a/services/viz/public/cpp/compositing/surface_sequence.typemap b/services/viz/public/cpp/compositing/surface_sequence.typemap new file mode 100644 index 0000000..b2377ba --- /dev/null +++ b/services/viz/public/cpp/compositing/surface_sequence.typemap
@@ -0,0 +1,12 @@ +# Copyright 2016 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +mojom = "//services/viz/public/interfaces/compositing/surface_sequence.mojom" +public_headers = [ "//components/viz/common/surfaces/surface_sequence.h" ] +traits_headers = + [ "//services/viz/public/cpp/compositing/surface_sequence_struct_traits.h" ] +deps = [ + "//components/viz/common", +] +type_mappings = [ "viz.mojom.SurfaceSequence=viz::SurfaceSequence" ]
diff --git a/cc/ipc/surface_sequence_struct_traits.h b/services/viz/public/cpp/compositing/surface_sequence_struct_traits.h similarity index 60% rename from cc/ipc/surface_sequence_struct_traits.h rename to services/viz/public/cpp/compositing/surface_sequence_struct_traits.h index ead28b37..24563cb02 100644 --- a/cc/ipc/surface_sequence_struct_traits.h +++ b/services/viz/public/cpp/compositing/surface_sequence_struct_traits.h
@@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CC_IPC_SURFACE_SEQUENCE_STRUCT_TRAITS_H_ -#define CC_IPC_SURFACE_SEQUENCE_STRUCT_TRAITS_H_ +#ifndef SERVICES_VIZ_PUBLIC_CPP_COMPOSITING_SURFACE_SEQUENCE_STRUCT_TRAITS_H_ +#define SERVICES_VIZ_PUBLIC_CPP_COMPOSITING_SURFACE_SEQUENCE_STRUCT_TRAITS_H_ -#include "cc/ipc/surface_sequence.mojom-shared.h" #include "components/viz/common/surfaces/surface_sequence.h" +#include "services/viz/public/interfaces/compositing/surface_sequence.mojom-shared.h" namespace mojo { template <> -struct StructTraits<cc::mojom::SurfaceSequenceDataView, viz::SurfaceSequence> { +struct StructTraits<viz::mojom::SurfaceSequenceDataView, viz::SurfaceSequence> { static const viz::FrameSinkId& frame_sink_id(const viz::SurfaceSequence& id) { return id.frame_sink_id; } @@ -20,7 +20,7 @@ return id.sequence; } - static bool Read(cc::mojom::SurfaceSequenceDataView data, + static bool Read(viz::mojom::SurfaceSequenceDataView data, viz::SurfaceSequence* out) { viz::FrameSinkId frame_sink_id; if (!data.ReadFrameSinkId(&frame_sink_id)) @@ -32,4 +32,4 @@ } // namespace mojo -#endif // CC_IPC_SURFACE_SEQUENCE_STRUCT_TRAITS_H_ +#endif // SERVICES_VIZ_PUBLIC_CPP_COMPOSITING_SURFACE_SEQUENCE_STRUCT_TRAITS_H_
diff --git a/services/viz/public/cpp/compositing/typemaps.gni b/services/viz/public/cpp/compositing/typemaps.gni index db606faf..e287bc7 100644 --- a/services/viz/public/cpp/compositing/typemaps.gni +++ b/services/viz/public/cpp/compositing/typemaps.gni
@@ -6,5 +6,6 @@ "//services/viz/public/cpp/compositing/compositor_frame.typemap", "//services/viz/public/cpp/compositing/resource_settings.typemap", "//services/viz/public/cpp/compositing/returned_resource.typemap", + "//services/viz/public/cpp/compositing/surface_sequence.typemap", "//services/viz/public/cpp/compositing/surface_info.typemap", ]
diff --git a/services/viz/public/interfaces/compositing/BUILD.gn b/services/viz/public/interfaces/compositing/BUILD.gn index 4f10daa0..3ca8344a 100644 --- a/services/viz/public/interfaces/compositing/BUILD.gn +++ b/services/viz/public/interfaces/compositing/BUILD.gn
@@ -11,6 +11,7 @@ "resource_settings.mojom", "returned_resource.mojom", "surface_info.mojom", + "surface_sequence.mojom", ] public_deps = [
diff --git a/services/viz/public/interfaces/compositing/compositor_frame_sink.mojom b/services/viz/public/interfaces/compositing/compositor_frame_sink.mojom index 2951b77..fde38d4f 100644 --- a/services/viz/public/interfaces/compositing/compositor_frame_sink.mojom +++ b/services/viz/public/interfaces/compositing/compositor_frame_sink.mojom
@@ -9,7 +9,6 @@ import "cc/ipc/frame_sink_id.mojom"; import "cc/ipc/local_surface_id.mojom"; import "cc/ipc/surface_id.mojom"; -import "cc/ipc/surface_sequence.mojom"; import "services/viz/public/interfaces/hit_test/hit_test_region_list.mojom"; import "services/viz/public/interfaces/compositing/compositor_frame.mojom"; import "services/viz/public/interfaces/compositing/returned_resource.mojom";
diff --git a/cc/ipc/surface_sequence.mojom b/services/viz/public/interfaces/compositing/surface_sequence.mojom similarity index 87% rename from cc/ipc/surface_sequence.mojom rename to services/viz/public/interfaces/compositing/surface_sequence.mojom index ba02ee5..d23159f 100644 --- a/cc/ipc/surface_sequence.mojom +++ b/services/viz/public/interfaces/compositing/surface_sequence.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -module cc.mojom; +module viz.mojom; import "cc/ipc/frame_sink_id.mojom"; @@ -10,7 +10,6 @@ // dependencies between frames. A sequence number may be satisfied once, and // may be depended on once. struct SurfaceSequence { - FrameSinkId frame_sink_id; + cc.mojom.FrameSinkId frame_sink_id; uint32 sequence; }; -
diff --git a/testing/buildbot/filters/fuchsia.base_unittests.filter b/testing/buildbot/filters/fuchsia.base_unittests.filter index 3af890a..9fb4b64 100644 --- a/testing/buildbot/filters/fuchsia.base_unittests.filter +++ b/testing/buildbot/filters/fuchsia.base_unittests.filter
@@ -25,6 +25,16 @@ -ProcessMemoryDumpTest.CountResidentBytes -ProcessMemoryDumpTest.CountResidentBytesInSharedMemory -ProcessMemoryDumpTest.TakeAllDumpsFrom +-SysInfoTest.AmountOfFreeDiskSpace +-SysInfoTest.AmountOfMem +-SysInfoTest.AmountOfTotalDiskSpace + +# CancelableSyncSocket tests fail: https://crbug.com/741783 +-CancelableSyncSocket* + +# These tests all rely on being able to set the exit code of an externally +# terminated process, which mx_task_kill() does not support. +# https://crbug.com/753490. -ProcessTest.Terminate -ProcessTest.TerminateCurrentProcessImmediatelyWithNonZeroExitCode -ProcessTest.TerminateCurrentProcessImmediatelyWithZeroExitCode @@ -32,12 +42,6 @@ -ProcessUtilTest.GetTerminationStatusCrash -ProcessUtilTest.GetTerminationStatusSigKill -ProcessUtilTest.GetTerminationStatusSigTerm --SysInfoTest.AmountOfFreeDiskSpace --SysInfoTest.AmountOfMem --SysInfoTest.AmountOfTotalDiskSpace - -# CancelableSyncSocket tests fail: https://crbug.com/741783 --CancelableSyncSocket* # These tests are occasionally flaking. See https://crbug.com/738275. Please be # pretty confident you've fixed their rarely-flakiness before re-enabling.
diff --git a/testing/buildbot/filters/fuchsia.ui_base_unittests.filter b/testing/buildbot/filters/fuchsia.ui_base_unittests.filter index 9ff1f700..5e608d4 100644 --- a/testing/buildbot/filters/fuchsia.ui_base_unittests.filter +++ b/testing/buildbot/filters/fuchsia.ui_base_unittests.filter
@@ -5,6 +5,9 @@ -*DataPackTest.* -ResourceBundleImageTest.* +# Failing after turning on Ozone/Aura. We probably don't have any need for this. +-OSExchangeDataTest.* + # Flaking, see https://crbug.com/752220. -ClipboardTest/0.ClearTest -L10nUtilTest.TimeDurationFormatAllLocales
diff --git a/third_party/WebKit/LayoutTests/plugins/navigator-pluginarray.html b/third_party/WebKit/LayoutTests/plugins/navigator-pluginarray.html index b02ba400..d0f00058 100644 --- a/third_party/WebKit/LayoutTests/plugins/navigator-pluginarray.html +++ b/third_party/WebKit/LayoutTests/plugins/navigator-pluginarray.html
@@ -56,6 +56,14 @@ assert_less_than_equal(navigator.mimeTypes[i-1].type.localeCompare(navigator.mimeTypes[i].type), 0); } }, "Tests that navigator.plugins returns plugins sorted in alphabetical order by plugin name."); + +test(function() { + assert_greater_than_equal(navigator.plugins.length, 1, "At least one plugin must be available."); + assert_greater_than_equal(navigator.mimeTypes.length, 1, "At least one mime type must be available."); + assert_equals(null, navigator.plugins.item(navigator.plugins.length)); + assert_equals(null, navigator.mimeTypes.item(navigator.mimeTypes.length)); + assert_equals(null, navigator.plugins[0].item(navigator.plugins[0].length)); +}, "Tests out-of-bounds access in navigator.plugins"); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioBuffer/huge-buffer.html b/third_party/WebKit/LayoutTests/webaudio/AudioBuffer/huge-buffer.html new file mode 100644 index 0000000..c9d8eed --- /dev/null +++ b/third_party/WebKit/LayoutTests/webaudio/AudioBuffer/huge-buffer.html
@@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html> + <head> + <title> + Test Creation of Huge AudioBuffer + </title> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> + <script src="../resources/audit.js"></script> + </head> + <body> + <script id="layout-test-code"> + let audit = Audit.createTaskRunner(); + + audit.define('huge buffer', (task, should) => { + // Set options to try to allocate a huge amount of memory in an + // AudioBuffer. This should fail gracefully with an error instead of + // crashing with an OOM error. + let options = { + numberOfChannels: 32, + length: 1 << 30, + sampleRate: 16000 + }; + should( + () => new AudioBuffer(options), + 'new AudioBuffer(' + JSON.stringify(options) + ')') + .throw('NotSupportedError'); + task.done(); + }); + + audit.run(); + </script> + </body> +</html>
diff --git a/third_party/WebKit/Source/core/css/OffscreenFontSelector.cpp b/third_party/WebKit/Source/core/css/OffscreenFontSelector.cpp index 4a16fb18..cc00c3ba 100644 --- a/third_party/WebKit/Source/core/css/OffscreenFontSelector.cpp +++ b/third_party/WebKit/Source/core/css/OffscreenFontSelector.cpp
@@ -20,12 +20,15 @@ namespace blink { -OffscreenFontSelector::OffscreenFontSelector( - const GenericFontFamilySettings& settings) - : generic_font_family_settings_(settings) {} +OffscreenFontSelector::OffscreenFontSelector() {} OffscreenFontSelector::~OffscreenFontSelector() {} +void OffscreenFontSelector::UpdateGenericFontFamilySettings( + const GenericFontFamilySettings& settings) { + generic_font_family_settings_ = settings; +} + void OffscreenFontSelector::RegisterForInvalidationCallbacks( FontSelectorClient* client) {}
diff --git a/third_party/WebKit/Source/core/css/OffscreenFontSelector.h b/third_party/WebKit/Source/core/css/OffscreenFontSelector.h index 494e33e..0a5897e 100644 --- a/third_party/WebKit/Source/core/css/OffscreenFontSelector.h +++ b/third_party/WebKit/Source/core/css/OffscreenFontSelector.h
@@ -20,10 +20,7 @@ class CORE_EXPORT OffscreenFontSelector : public FontSelector { public: - static OffscreenFontSelector* Create( - const GenericFontFamilySettings& settings) { - return new OffscreenFontSelector(settings); - } + static OffscreenFontSelector* Create() { return new OffscreenFontSelector(); } ~OffscreenFontSelector() override; unsigned Version() const override { return 1; } @@ -48,15 +45,17 @@ void FontCacheInvalidated() override; + void UpdateGenericFontFamilySettings(const GenericFontFamilySettings&); + DECLARE_VIRTUAL_TRACE(); protected: - explicit OffscreenFontSelector(const GenericFontFamilySettings&); + explicit OffscreenFontSelector(); void DispatchInvalidationCallbacks(); private: - const GenericFontFamilySettings generic_font_family_settings_; + GenericFontFamilySettings generic_font_family_settings_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/exported/WebViewTest.cpp b/third_party/WebKit/Source/core/exported/WebViewTest.cpp index 42724c9..af31524 100644 --- a/third_party/WebKit/Source/core/exported/WebViewTest.cpp +++ b/third_party/WebKit/Source/core/exported/WebViewTest.cpp
@@ -246,6 +246,10 @@ } protected: + void SetViewportSize(const WebSize& size) { + web_view_helper_.SetViewportSize(size); + } + std::string RegisterMockedHttpURLLoad(const std::string& file_name) { return URLTestHelpers::RegisterMockedURLLoadFromBase( WebString::FromUTF8(base_url_), testing::CoreTestDataPath(), @@ -4598,7 +4602,7 @@ WebViewImpl* web_view_impl = web_view_helper_.InitializeAndLoad(base_url_ + "200-by-300.html"); web_view_impl->Resize(WebSize(100, 150)); - web_view_impl->LayerTreeView()->SetViewportSize(WebSize(100, 150)); + SetViewportSize(WebSize(100, 150)); VisualViewport* visual_viewport = &web_view_impl->GetPage()->GetVisualViewport(); DevToolsEmulator* dev_tools_emulator = web_view_impl->GetDevToolsEmulator(); @@ -4673,7 +4677,7 @@ WebViewImpl* web_view_impl = web_view_helper_.InitializeAndLoad(base_url_ + "200-by-300.html"); web_view_impl->Resize(WebSize(100, 150)); - web_view_impl->LayerTreeView()->SetViewportSize(WebSize(100, 150)); + SetViewportSize(WebSize(100, 150)); LocalFrameView* frame_view = web_view_impl->MainFrameImpl()->GetFrame()->View(); DevToolsEmulator* dev_tools_emulator = web_view_impl->GetDevToolsEmulator();
diff --git a/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp b/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp index 3f9593a..a031b5d 100644 --- a/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp +++ b/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp
@@ -36,7 +36,6 @@ #include "core/frame/WebLocalFrameImpl.h" #include "platform/testing/URLTestHelpers.h" #include "platform/testing/UnitTestHelpers.h" -#include "platform/testing/WebLayerTreeViewImplForTesting.h" #include "platform/wtf/Functional.h" #include "platform/wtf/PtrUtil.h" #include "platform/wtf/StdLibExtras.h" @@ -333,6 +332,11 @@ return ToWebRemoteFrameImpl(web_view_->MainFrame()); } +void WebViewHelper::SetViewportSize(const WebSize& viewport_size) { + test_web_view_client_->GetLayerTreeViewForTesting()->SetViewportSize( + viewport_size); +} + void WebViewHelper::Resize(WebSize size) { test_web_view_client_->ClearAnimationScheduled(); WebView()->Resize(size); @@ -425,6 +429,11 @@ self_owned_.reset(); } +WebLayerTreeViewImplForTesting* +TestWebViewClient::GetLayerTreeViewForTesting() { + return layer_tree_view_.get(); +} + WebLayerTreeView* TestWebViewClient::InitializeLayerTreeView() { layer_tree_view_ = WTF::MakeUnique<WebLayerTreeViewImplForTesting>(); return layer_tree_view_.get();
diff --git a/third_party/WebKit/Source/core/frame/FrameTestHelpers.h b/third_party/WebKit/Source/core/frame/FrameTestHelpers.h index e9011df38..0b9a0ec 100644 --- a/third_party/WebKit/Source/core/frame/FrameTestHelpers.h +++ b/third_party/WebKit/Source/core/frame/FrameTestHelpers.h
@@ -40,6 +40,7 @@ #include "platform/RuntimeEnabledFeatures.h" #include "platform/WebTaskRunner.h" #include "platform/scroll/ScrollbarTheme.h" +#include "platform/testing/WebLayerTreeViewImplForTesting.h" #include "public/platform/Platform.h" #include "public/platform/WebCachePolicy.h" #include "public/platform/WebMouseEvent.h" @@ -258,6 +259,8 @@ public: ~TestWebViewClient() override {} + WebLayerTreeViewImplForTesting* GetLayerTreeViewForTesting(); + // WebViewClient: WebLayerTreeView* InitializeLayerTreeView() override; void ScheduleAnimation() override { animation_scheduled_ = true; } @@ -269,7 +272,7 @@ private: friend class TestWebViewWidgetClient; - std::unique_ptr<WebLayerTreeView> layer_tree_view_; + std::unique_ptr<WebLayerTreeViewImplForTesting> layer_tree_view_; bool animation_scheduled_ = false; }; @@ -327,6 +330,8 @@ WebLocalFrameImpl* LocalMainFrame() const; WebRemoteFrameImpl* RemoteMainFrame() const; + void SetViewportSize(const WebSize&); + private: void InitializeWebView(TestWebViewClient*);
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp index 1a62583..0af7065 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -37,10 +37,12 @@ #include "build/build_config.h" #include "core/HTMLNames.h" #include "core/InputTypeNames.h" +#include "core/css/CSSFontSelector.h" #include "core/dom/Document.h" #include "core/dom/Element.h" #include "core/dom/ElementTraversal.h" #include "core/dom/ExceptionCode.h" +#include "core/dom/StyleEngine.h" #include "core/dom/TaskRunnerHelper.h" #include "core/fileapi/File.h" #include "core/frame/LocalFrame.h" @@ -1465,4 +1467,8 @@ SetNeedsCompositingUpdate(); } +FontSelector* HTMLCanvasElement::GetFontSelector() { + return GetDocument().GetStyleEngine().GetFontSelector(); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h index cf6bac6a..aabbe4c6 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
@@ -165,6 +165,8 @@ ImageBuffer* GetImageBuffer() const override { return image_buffer_.get(); } ImageBuffer* GetOrCreateImageBuffer() override; + FontSelector* GetFontSelector() override; + bool ShouldBeDirectComposited() const; void PrepareSurfaceForPaintingIfNeeded();
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContextHost.h b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContextHost.h index bef3cdd7..d942035 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContextHost.h +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContextHost.h
@@ -18,6 +18,7 @@ namespace blink { +class FontSelector; class StaticBitmapImage; class KURL; @@ -52,6 +53,8 @@ virtual bool IsWebGLAllowed() const = 0; + virtual FontSelector* GetFontSelector() = 0; + // TODO(fserb): remove this. virtual bool IsOffscreenCanvas() const { return false; }
diff --git a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.cpp b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.cpp index f8f0f8c..8afad95 100644 --- a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.cpp +++ b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.cpp
@@ -5,8 +5,11 @@ #include "core/offscreencanvas/OffscreenCanvas.h" #include <memory> +#include "core/css/CSSFontSelector.h" +#include "core/css/OffscreenFontSelector.h" #include "core/dom/ExceptionCode.h" #include "core/dom/ExecutionContext.h" +#include "core/dom/StyleEngine.h" #include "core/fileapi/Blob.h" #include "core/html/ImageData.h" #include "core/html/canvas/CanvasAsyncBlobCreator.h" @@ -14,6 +17,7 @@ #include "core/html/canvas/CanvasRenderingContext.h" #include "core/html/canvas/CanvasRenderingContextFactory.h" #include "core/imagebitmap/ImageBitmap.h" +#include "core/workers/WorkerGlobalScope.h" #include "platform/graphics/Image.h" #include "platform/graphics/ImageBuffer.h" #include "platform/graphics/OffscreenCanvasFrameDispatcherImpl.h" @@ -408,6 +412,13 @@ return resolver->Promise(); } +FontSelector* OffscreenCanvas::GetFontSelector() { + if (GetExecutionContext()->IsDocument()) { + return ToDocument(execution_context_)->GetStyleEngine().GetFontSelector(); + } + return ToWorkerGlobalScope(execution_context_)->GetFontSelector(); +} + DEFINE_TRACE(OffscreenCanvas) { visitor->Trace(context_); visitor->Trace(execution_context_);
diff --git a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h index 763a3909..76dc52bc 100644 --- a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h +++ b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h
@@ -152,6 +152,8 @@ bool IsWebGLAllowed() const override { return true; } + FontSelector* GetFontSelector() override; + DECLARE_VIRTUAL_TRACE(); private:
diff --git a/third_party/WebKit/Source/core/page/PageOverlayTest.cpp b/third_party/WebKit/Source/core/page/PageOverlayTest.cpp index 40f6894..e8468ef 100644 --- a/third_party/WebKit/Source/core/page/PageOverlayTest.cpp +++ b/third_party/WebKit/Source/core/page/PageOverlayTest.cpp
@@ -90,6 +90,8 @@ WTF::MakeUnique<SolidColorOverlay>(SK_ColorYELLOW)); } + void SetViewportSize(const WebSize& size) { helper_.SetViewportSize(size); } + template <typename OverlayType> void RunPageOverlayTestWithAcceleratedCompositing(); @@ -117,8 +119,7 @@ TEST_F(PageOverlayTest, PageOverlay_AcceleratedCompositing) { Initialize(kAcceleratedCompositing); - GetWebView()->LayerTreeView()->SetViewportSize( - WebSize(kViewportWidth, kViewportHeight)); + SetViewportSize(WebSize(kViewportWidth, kViewportHeight)); std::unique_ptr<PageOverlay> page_overlay = CreateSolidYellowOverlay(); page_overlay->Update();
diff --git a/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.cpp b/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.cpp index 1af03ea..752d7c2 100644 --- a/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.cpp +++ b/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.cpp
@@ -11,6 +11,7 @@ #include "platform/instrumentation/tracing/TraceEvent.h" #include "platform/loader/fetch/ResourceFetcher.h" #include "platform/wtf/Functional.h" +#include "public/platform/WebLayerTreeView.h" namespace blink { @@ -90,7 +91,7 @@ return; // Skip document background-only paints. - if (paint_timing_->FirstPaint() == 0.0) + if (paint_timing_->FirstPaintRendered() == 0.0) return; provisional_first_meaningful_paint_ = MonotonicallyIncreasingTime(); @@ -120,7 +121,7 @@ // This is called only on FirstMeaningfulPaintDetector for main frame. void FirstMeaningfulPaintDetector::NotifyInputEvent() { // Ignore user inputs before first paint. - if (paint_timing_->FirstPaint() == 0.0) + if (paint_timing_->FirstPaintRendered() == 0.0) return; had_user_input_ = kHadUserInput; } @@ -159,7 +160,7 @@ void FirstMeaningfulPaintDetector::Network0QuietTimerFired(TimerBase*) { if (!GetDocument() || network0_quiet_reached_ || ActiveConnections() > 0 || - !paint_timing_->FirstContentfulPaint()) + !paint_timing_->FirstContentfulPaintRendered()) return; network0_quiet_reached_ = true; @@ -167,14 +168,14 @@ // Enforce FirstContentfulPaint <= FirstMeaningfulPaint. first_meaningful_paint0_quiet_ = std::max(provisional_first_meaningful_paint_, - paint_timing_->FirstContentfulPaint()); + paint_timing_->FirstContentfulPaintRendered()); } ReportHistograms(); } void FirstMeaningfulPaintDetector::Network2QuietTimerFired(TimerBase*) { if (!GetDocument() || network2_quiet_reached_ || ActiveConnections() > 2 || - !paint_timing_->FirstContentfulPaint()) + !paint_timing_->FirstContentfulPaintRendered()) return; network2_quiet_reached_ = true; @@ -186,10 +187,11 @@ provisional_first_meaningful_paint_); // Enforce FirstContentfulPaint <= FirstMeaningfulPaint. if (provisional_first_meaningful_paint_ < - paint_timing_->FirstContentfulPaint()) { - first_meaningful_paint2_quiet_ = paint_timing_->FirstContentfulPaint(); + paint_timing_->FirstContentfulPaintRendered()) { + first_meaningful_paint2_quiet_ = + paint_timing_->FirstContentfulPaintRendered(); first_meaningful_paint2_quiet_swap_ = - paint_timing_->FirstContentfulPaintSwap(); + paint_timing_->FirstContentfulPaint(); // It's possible that this timer fires between when the first contentful // paint is set and its SwapPromise is fulfilled. If this happens, defer // until NotifyFirstContentfulPaint() is called. @@ -267,18 +269,27 @@ WrapCrossThreadWeakPersistent(this), event)); } -void FirstMeaningfulPaintDetector::ReportSwapTime(PaintEvent event, - bool did_swap, - double timestamp) { +void FirstMeaningfulPaintDetector::ReportSwapTime( + PaintEvent event, + WebLayerTreeView::SwapResult result, + double timestamp) { DCHECK(event == PaintEvent::kProvisionalFirstMeaningfulPaint); DCHECK_GT(outstanding_swap_promise_count_, 0U); --outstanding_swap_promise_count_; - // TODO(shaseley): Add UMAs here to see how often swaps fail. If this happens, - // the FMP will be 0.0 if this is the provisional timestamp we end up using. - if (!did_swap) - return; - + // If the swap fails for any reason, we use the timestamp when the SwapPromise + // was broken. |result| == WebLayerTreeView::SwapResult::kDidNotSwapSwapFails + // usually means the compositor decided not swap because there was no actual + // damage, which can happen when what's being painted isn't visible. In this + // case, the timestamp will be consistent with the case where the swap + // succeeds, as they both capture the time up to swap. In other failure cases + // (aborts during commit), this timestamp is an improvement over the blink + // paint time, but does not capture some time we're interested in, e.g. image + // decoding. + // + // TODO(crbug.com/738235): Consider not reporting any timestamp when failing + // for reasons other than kDidNotSwapSwapFails. + paint_timing_->ReportSwapResultHistogram(result); provisional_first_meaningful_paint_swap_ = timestamp; if (defer_first_meaningful_paint_ == kDeferOutstandingSwapPromises &&
diff --git a/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.h b/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.h index 1bd25b66..48fe9a50 100644 --- a/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.h +++ b/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.h
@@ -10,6 +10,7 @@ #include "platform/Timer.h" #include "platform/heap/Handle.h" #include "platform/wtf/Noncopyable.h" +#include "public/platform/WebLayerTreeView.h" namespace blink { @@ -49,7 +50,7 @@ void NotifyInputEvent(); void NotifyPaint(); void CheckNetworkStable(); - void ReportSwapTime(PaintEvent, bool did_swap, double timestamp); + void ReportSwapTime(PaintEvent, WebLayerTreeView::SwapResult, double); void NotifyFirstContentfulPaint(double swap_stamp); DECLARE_TRACE();
diff --git a/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetectorTest.cpp b/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetectorTest.cpp index 34663ed..3bf0cd53 100644 --- a/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetectorTest.cpp +++ b/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetectorTest.cpp
@@ -9,6 +9,7 @@ #include "core/testing/DummyPageHolder.h" #include "platform/testing/TestingPlatformSupport.h" #include "platform/wtf/text/StringBuilder.h" +#include "public/platform/WebLayerTreeView.h" #include "testing/gtest/include/gtest/gtest.h" namespace blink { @@ -76,20 +77,23 @@ void ClearFirstPaintSwapPromise() { platform_->AdvanceClockSeconds(0.001); - GetPaintTiming().ReportSwapTime(PaintEvent::kFirstPaint, true, + GetPaintTiming().ReportSwapTime(PaintEvent::kFirstPaint, + WebLayerTreeView::SwapResult::kDidSwap, MonotonicallyIncreasingTime()); } void ClearFirstContentfulPaintSwapPromise() { platform_->AdvanceClockSeconds(0.001); - GetPaintTiming().ReportSwapTime(PaintEvent::kFirstContentfulPaint, true, + GetPaintTiming().ReportSwapTime(PaintEvent::kFirstContentfulPaint, + WebLayerTreeView::SwapResult::kDidSwap, MonotonicallyIncreasingTime()); } void ClearProvisionalFirstMeaningfulPaintSwapPromise() { platform_->AdvanceClockSeconds(0.001); Detector().ReportSwapTime(PaintEvent::kProvisionalFirstMeaningfulPaint, - true, MonotonicallyIncreasingTime()); + WebLayerTreeView::SwapResult::kDidSwap, + MonotonicallyIncreasingTime()); } unsigned OutstandingDetectorSwapPromiseCount() { @@ -123,8 +127,8 @@ SimulateLayoutAndPaint(1); EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 0U); SimulateNetworkStable(); + EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), 0.0); EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), 0.0); - EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintSwap(), 0.0); } TEST_F(FirstMeaningfulPaintDetectorTest, OneLayout) { @@ -133,15 +137,15 @@ EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U); ClearProvisionalFirstMeaningfulPaintSwapPromise(); double after_paint = AdvanceClockAndGetTime(); + EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), 0.0); EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), 0.0); - EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintSwap(), 0.0); SimulateNetworkStable(); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(), + GetPaintTiming().FirstPaintRendered()); EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), - GetPaintTiming().FirstPaint()); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), - GetPaintTiming().FirstMeaningfulPaint()); + GetPaintTiming().FirstMeaningfulPaintRendered()); + EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintRendered(), after_paint); EXPECT_LT(GetPaintTiming().FirstMeaningfulPaint(), after_paint); - EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintSwap(), after_paint); } TEST_F(FirstMeaningfulPaintDetectorTest, TwoLayoutsSignificantSecond) { @@ -155,12 +159,12 @@ ClearProvisionalFirstMeaningfulPaintSwapPromise(); double after_layout2 = AdvanceClockAndGetTime(); SimulateNetworkStable(); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(), after_layout1); EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), after_layout1); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), after_layout1); + EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintRendered(), after_layout2); EXPECT_LT(GetPaintTiming().FirstMeaningfulPaint(), after_layout2); - EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintSwap(), after_layout2); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), - GetPaintTiming().FirstMeaningfulPaint()); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), + GetPaintTiming().FirstMeaningfulPaintRendered()); } TEST_F(FirstMeaningfulPaintDetectorTest, TwoLayoutsSignificantFirst) { @@ -172,12 +176,12 @@ SimulateLayoutAndPaint(1); EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 0U); SimulateNetworkStable(); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(), + GetPaintTiming().FirstPaintRendered()); EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), - GetPaintTiming().FirstPaint()); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), - GetPaintTiming().FirstPaint()); + GetPaintTiming().FirstPaintRendered()); + EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintRendered(), after_layout1); EXPECT_LT(GetPaintTiming().FirstMeaningfulPaint(), after_layout1); - EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintSwap(), after_layout1); } TEST_F(FirstMeaningfulPaintDetectorTest, FirstMeaningfulPaintCandidate) { @@ -220,14 +224,14 @@ EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U); ClearProvisionalFirstMeaningfulPaintSwapPromise(); SimulateNetworkStable(); + EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), 0.0); EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), 0.0); - EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintSwap(), 0.0); MarkFirstContentfulPaintAndClearSwapPromise(); SimulateNetworkStable(); + EXPECT_NE(GetPaintTiming().FirstMeaningfulPaintRendered(), 0.0); EXPECT_NE(GetPaintTiming().FirstMeaningfulPaint(), 0.0); - EXPECT_NE(GetPaintTiming().FirstMeaningfulPaintSwap(), 0.0); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), - GetPaintTiming().FirstMeaningfulPaint()); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), + GetPaintTiming().FirstMeaningfulPaintRendered()); } TEST_F(FirstMeaningfulPaintDetectorTest, @@ -239,12 +243,12 @@ platform_->AdvanceClockSeconds(0.001); MarkFirstContentfulPaintAndClearSwapPromise(); SimulateNetworkStable(); + EXPECT_GE(GetPaintTiming().FirstMeaningfulPaintRendered(), + GetPaintTiming().FirstContentfulPaintRendered()); EXPECT_GE(GetPaintTiming().FirstMeaningfulPaint(), GetPaintTiming().FirstContentfulPaint()); - EXPECT_GE(GetPaintTiming().FirstMeaningfulPaintSwap(), - GetPaintTiming().FirstContentfulPaintSwap()); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), - GetPaintTiming().FirstMeaningfulPaint()); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), + GetPaintTiming().FirstMeaningfulPaintRendered()); } TEST_F(FirstMeaningfulPaintDetectorTest, Network2QuietThen0Quiet) { @@ -262,14 +266,13 @@ SimulateNetwork0Quiet(); // The first paint is FirstMeaningfulPaint. + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(), 0.0); EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), 0.0); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), 0.0); - EXPECT_LT(GetPaintTiming().FirstMeaningfulPaint(), after_first_paint); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), after_first_paint); - EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintSwap(), - after_first_paint_swap); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), - GetPaintTiming().FirstMeaningfulPaint()); + EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintRendered(), after_first_paint); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), after_first_paint); + EXPECT_LT(GetPaintTiming().FirstMeaningfulPaint(), after_first_paint_swap); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), + GetPaintTiming().FirstMeaningfulPaintRendered()); } TEST_F(FirstMeaningfulPaintDetectorTest, Network0QuietThen2Quiet) { @@ -288,14 +291,15 @@ SimulateNetwork2Quiet(); // The second paint is FirstMeaningfulPaint. + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(), after_first_paint); EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), after_first_paint); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), after_first_paint); + EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintRendered(), + after_second_paint); EXPECT_LT(GetPaintTiming().FirstMeaningfulPaint(), after_second_paint); - EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintSwap(), after_second_paint); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), - GetPaintTiming().FirstMeaningfulPaint()); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), - GetPaintTiming().FirstMeaningfulPaint()); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), + GetPaintTiming().FirstMeaningfulPaintRendered()); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), + GetPaintTiming().FirstMeaningfulPaintRendered()); } TEST_F(FirstMeaningfulPaintDetectorTest, Network0QuietTimer) { @@ -347,8 +351,8 @@ EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U); ClearProvisionalFirstMeaningfulPaintSwapPromise(); SimulateNetworkStable(); + EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), 0.0); EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), 0.0); - EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintSwap(), 0.0); } TEST_F(FirstMeaningfulPaintDetectorTest, UserInteractionBeforeFirstPaint) { @@ -358,10 +362,10 @@ EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U); ClearProvisionalFirstMeaningfulPaintSwapPromise(); SimulateNetworkStable(); + EXPECT_NE(GetPaintTiming().FirstMeaningfulPaintRendered(), 0.0); EXPECT_NE(GetPaintTiming().FirstMeaningfulPaint(), 0.0); - EXPECT_NE(GetPaintTiming().FirstMeaningfulPaintSwap(), 0.0); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), - GetPaintTiming().FirstMeaningfulPaint()); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), + GetPaintTiming().FirstMeaningfulPaintRendered()); } TEST_F(FirstMeaningfulPaintDetectorTest, @@ -370,13 +374,13 @@ SimulateLayoutAndPaint(10); EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U); SimulateNetworkStable(); + EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), 0.0); EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), 0.0); - EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintSwap(), 0.0); ClearProvisionalFirstMeaningfulPaintSwapPromise(); + EXPECT_NE(GetPaintTiming().FirstMeaningfulPaintRendered(), 0.0); EXPECT_NE(GetPaintTiming().FirstMeaningfulPaint(), 0.0); - EXPECT_NE(GetPaintTiming().FirstMeaningfulPaintSwap(), 0.0); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), - GetPaintTiming().FirstMeaningfulPaint()); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), + GetPaintTiming().FirstMeaningfulPaintRendered()); } TEST_F(FirstMeaningfulPaintDetectorTest, @@ -389,22 +393,22 @@ EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 2U); // Having outstanding swap promises should defer setting FMP. SimulateNetworkStable(); + EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), 0.0); EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), 0.0); - EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintSwap(), 0.0); // Clearing the first swap promise should have no effect on FMP. ClearProvisionalFirstMeaningfulPaintSwapPromise(); EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U); + EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), 0.0); EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), 0.0); - EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintSwap(), 0.0); double after_first_swap = AdvanceClockAndGetTime(); // Clearing the last outstanding swap promise should set FMP. ClearProvisionalFirstMeaningfulPaintSwapPromise(); EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 0U); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(), 0.0); EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), 0.0); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), 0.0); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), after_first_swap); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), - GetPaintTiming().FirstMeaningfulPaint()); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), after_first_swap); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), + GetPaintTiming().FirstMeaningfulPaintRendered()); } TEST_F(FirstMeaningfulPaintDetectorTest, @@ -418,20 +422,20 @@ GetPaintTiming().MarkFirstContentfulPaint(); // FCP > FMP candidate, but still waiting for FCP swap. SimulateNetworkStable(); + EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), 0.0); EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), 0.0); - EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintSwap(), 0.0); // Trigger notifying the detector about the FCP swap. ClearFirstContentfulPaintSwapPromise(); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(), 0.0); EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), 0.0); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), 0.0); + EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), + GetPaintTiming().FirstContentfulPaintRendered()); EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), GetPaintTiming().FirstContentfulPaint()); - EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintSwap(), - GetPaintTiming().FirstContentfulPaintSwap()); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(), after_first_meaningful_paint_candidate); - EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintSwap(), - GetPaintTiming().FirstMeaningfulPaint()); + EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), + GetPaintTiming().FirstMeaningfulPaintRendered()); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PaintEvent.h b/third_party/WebKit/Source/core/paint/PaintEvent.h index 26182adb..291f6a2 100644 --- a/third_party/WebKit/Source/core/paint/PaintEvent.h +++ b/third_party/WebKit/Source/core/paint/PaintEvent.h
@@ -8,11 +8,13 @@ namespace blink { // Paint events that either PaintTiming or FirstMeaningfulPaintDetector receive -// GPU swap times for. +// SwapPromise swap times for. enum class PaintEvent { kFirstPaint, kFirstContentfulPaint, kProvisionalFirstMeaningfulPaint, + kFirstTextPaint, + kFirstImagePaint, }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PaintTiming.cpp b/third_party/WebKit/Source/core/paint/PaintTiming.cpp index 1934f5cf..9862a7d 100644 --- a/third_party/WebKit/Source/core/paint/PaintTiming.cpp +++ b/third_party/WebKit/Source/core/paint/PaintTiming.cpp
@@ -55,7 +55,6 @@ if (first_paint_ != 0.0) return; SetFirstPaint(MonotonicallyIncreasingTime()); - NotifyPaintTimingChanged(); } void PaintTiming::MarkFirstContentfulPaint() { @@ -66,7 +65,6 @@ if (first_contentful_paint_ != 0.0) return; SetFirstContentfulPaint(MonotonicallyIncreasingTime()); - NotifyPaintTimingChanged(); } void PaintTiming::MarkFirstTextPaint() { @@ -74,10 +72,7 @@ return; first_text_paint_ = MonotonicallyIncreasingTime(); SetFirstContentfulPaint(first_text_paint_); - TRACE_EVENT_MARK_WITH_TIMESTAMP1( - "loading,rail,devtools.timeline", "firstTextPaint", - TraceEvent::ToTraceTimestamp(first_text_paint_), "frame", GetFrame()); - NotifyPaintTimingChanged(); + RegisterNotifySwapTime(PaintEvent::kFirstTextPaint); } void PaintTiming::MarkFirstImagePaint() { @@ -85,10 +80,7 @@ return; first_image_paint_ = MonotonicallyIncreasingTime(); SetFirstContentfulPaint(first_image_paint_); - TRACE_EVENT_MARK_WITH_TIMESTAMP1( - "loading,rail,devtools.timeline", "firstImagePaint", - TraceEvent::ToTraceTimestamp(first_image_paint_), "frame", GetFrame()); - NotifyPaintTimingChanged(); + RegisterNotifySwapTime(PaintEvent::kFirstImagePaint); } void PaintTiming::SetFirstMeaningfulPaintCandidate(double timestamp) { @@ -105,16 +97,22 @@ double swap_stamp, FirstMeaningfulPaintDetector::HadUserInput had_input) { DCHECK_EQ(first_meaningful_paint_, 0.0); - TRACE_EVENT_MARK_WITH_TIMESTAMP2("loading,rail,devtools.timeline", - "firstMeaningfulPaint", - TraceEvent::ToTraceTimestamp(stamp), "frame", - GetFrame(), "afterUserInput", had_input); + DCHECK_EQ(first_meaningful_paint_swap_, 0.0); + DCHECK_GT(stamp, 0.0); + DCHECK_GT(swap_stamp, 0.0); + + TRACE_EVENT_MARK_WITH_TIMESTAMP2( + "loading,rail,devtools.timeline", "firstMeaningfulPaint", + TraceEvent::ToTraceTimestamp(swap_stamp), "frame", GetFrame(), + "afterUserInput", had_input); // Notify FMP for UMA only if there's no user input before FMP, so that layout // changes caused by user interactions wouldn't be considered as FMP. if (had_input == FirstMeaningfulPaintDetector::kNoUserInput) { first_meaningful_paint_ = stamp; first_meaningful_paint_swap_ = swap_stamp; + ReportSwapTimeDeltaHistogram(first_meaningful_paint_, + first_meaningful_paint_swap_); NotifyPaintTimingChanged(); } @@ -166,8 +164,6 @@ if (first_paint_ != 0.0) return; first_paint_ = stamp; - TRACE_EVENT_INSTANT1("loading,rail,devtools.timeline", "firstPaint", - TRACE_EVENT_SCOPE_PROCESS, "frame", GetFrame()); RegisterNotifySwapTime(PaintEvent::kFirstPaint); } @@ -176,10 +172,7 @@ return; SetFirstPaint(stamp); first_contentful_paint_ = stamp; - TRACE_EVENT_INSTANT1("loading,rail,devtools.timeline", "firstContentfulPaint", - TRACE_EVENT_SCOPE_PROCESS, "frame", GetFrame()); RegisterNotifySwapTime(PaintEvent::kFirstContentfulPaint); - GetFrame()->Loader().Progress().DidFirstContentfulPaint(); } void PaintTiming::RegisterNotifySwapTime(PaintEvent event) { @@ -188,9 +181,8 @@ WrapCrossThreadWeakPersistent(this), event)); } -void PaintTiming::RegisterNotifySwapTime( - PaintEvent event, - WTF::Function<void(bool, double)> callback) { +void PaintTiming::RegisterNotifySwapTime(PaintEvent event, + ReportTimeCallback callback) { // ReportSwapTime on layerTreeView will queue a swap-promise, the callback is // called when the swap for current render frame completes or fails to happen. if (!GetFrame() || !GetFrame()->GetPage()) @@ -203,26 +195,110 @@ } void PaintTiming::ReportSwapTime(PaintEvent event, - bool did_swap, + WebLayerTreeView::SwapResult result, double timestamp) { - if (!did_swap) - return; - Performance* performance = GetPerformanceInstance(GetFrame()); + // If the swap fails for any reason, we use the timestamp when the SwapPromise + // was broken. |result| == WebLayerTreeView::SwapResult::kDidNotSwapSwapFails + // usually means the compositor decided not swap because there was no actual + // damage, which can happen when what's being painted isn't visible. In this + // case, the timestamp will be consistent with the case where the swap + // succeeds, as they both capture the time up to swap. In other failure cases + // (aborts during commit), this timestamp is an improvement over the blink + // paint time, but does not capture some time we're interested in, e.g. image + // decoding. + // + // TODO(crbug.com/738235): Consider not reporting any timestamp when failing + // for reasons other than kDidNotSwapSwapFails. + ReportSwapResultHistogram(result); switch (event) { case PaintEvent::kFirstPaint: - first_paint_swap_ = timestamp; - if (performance) - performance->AddFirstPaintTiming(first_paint_); + SetFirstPaintSwap(timestamp); return; case PaintEvent::kFirstContentfulPaint: - first_contentful_paint_swap_ = timestamp; - if (performance) - performance->AddFirstContentfulPaintTiming(first_contentful_paint_); - fmp_detector_->NotifyFirstContentfulPaint(timestamp); + SetFirstContentfulPaintSwap(timestamp); + return; + case PaintEvent::kFirstTextPaint: + SetFirstTextPaintSwap(timestamp); + return; + case PaintEvent::kFirstImagePaint: + SetFirstImagePaintSwap(timestamp); return; default: NOTREACHED(); } } +void PaintTiming::SetFirstPaintSwap(double stamp) { + DCHECK_EQ(first_paint_swap_, 0.0); + first_paint_swap_ = stamp; + TRACE_EVENT_INSTANT_WITH_TIMESTAMP1( + "loading,rail,devtools.timeline", "firstPaint", TRACE_EVENT_SCOPE_PROCESS, + TraceEvent::ToTraceTimestamp(first_paint_swap_), "frame", GetFrame()); + Performance* performance = GetPerformanceInstance(GetFrame()); + if (performance) + performance->AddFirstPaintTiming(first_paint_swap_); + ReportSwapTimeDeltaHistogram(first_paint_, first_paint_swap_); + NotifyPaintTimingChanged(); +} + +void PaintTiming::SetFirstContentfulPaintSwap(double stamp) { + DCHECK_EQ(first_contentful_paint_swap_, 0.0); + first_contentful_paint_swap_ = stamp; + TRACE_EVENT_INSTANT_WITH_TIMESTAMP1( + "loading,rail,devtools.timeline", "firstContentfulPaint", + TRACE_EVENT_SCOPE_PROCESS, + TraceEvent::ToTraceTimestamp(first_contentful_paint_swap_), "frame", + GetFrame()); + Performance* performance = GetPerformanceInstance(GetFrame()); + if (performance) + performance->AddFirstContentfulPaintTiming(first_contentful_paint_swap_); + if (GetFrame()) + GetFrame()->Loader().Progress().DidFirstContentfulPaint(); + ReportSwapTimeDeltaHistogram(first_contentful_paint_, + first_contentful_paint_swap_); + NotifyPaintTimingChanged(); + fmp_detector_->NotifyFirstContentfulPaint(first_contentful_paint_swap_); +} + +void PaintTiming::SetFirstTextPaintSwap(double stamp) { + DCHECK_EQ(first_text_paint_swap_, 0.0); + first_text_paint_swap_ = stamp; + TRACE_EVENT_MARK_WITH_TIMESTAMP1( + "loading,rail,devtools.timeline", "firstTextPaint", + TraceEvent::ToTraceTimestamp(first_text_paint_swap_), "frame", + GetFrame()); + ReportSwapTimeDeltaHistogram(first_text_paint_, first_text_paint_swap_); + NotifyPaintTimingChanged(); +} + +void PaintTiming::SetFirstImagePaintSwap(double stamp) { + DCHECK_EQ(first_image_paint_swap_, 0.0); + first_image_paint_swap_ = stamp; + TRACE_EVENT_MARK_WITH_TIMESTAMP1( + "loading,rail,devtools.timeline", "firstImagePaint", + TraceEvent::ToTraceTimestamp(first_image_paint_swap_), "frame", + GetFrame()); + ReportSwapTimeDeltaHistogram(first_image_paint_, first_image_paint_swap_); + NotifyPaintTimingChanged(); +} + +void PaintTiming::ReportSwapResultHistogram( + const WebLayerTreeView::SwapResult result) { + DEFINE_STATIC_LOCAL(EnumerationHistogram, did_swap_histogram, + ("PageLoad.Internal.Renderer.PaintTiming.SwapResult", + WebLayerTreeView::SwapResult::kSwapResultMax)); + did_swap_histogram.Count(result); +} + +void PaintTiming::ReportSwapTimeDeltaHistogram(double timestamp, + double swap_timestamp) { + DEFINE_STATIC_LOCAL( + CustomCountHistogram, swap_time_diff_histogram, + ("PageLoad.Internal.Renderer.PaintTiming.SwapTimeDelta", 0, 10000, 50)); + DCHECK_GT(timestamp, 0.0); + DCHECK_GT(swap_timestamp, 0.0); + DCHECK_GE(swap_timestamp, timestamp); + swap_time_diff_histogram.Count((swap_timestamp - timestamp) * 1000.0); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PaintTiming.h b/third_party/WebKit/Source/core/paint/PaintTiming.h index db3f9fd7..cdf70667 100644 --- a/third_party/WebKit/Source/core/paint/PaintTiming.h +++ b/third_party/WebKit/Source/core/paint/PaintTiming.h
@@ -14,6 +14,7 @@ #include "platform/heap/Handle.h" #include "platform/wtf/Functional.h" #include "platform/wtf/Noncopyable.h" +#include "public/platform/WebLayerTreeView.h" namespace blink { @@ -26,23 +27,26 @@ public Supplement<Document> { WTF_MAKE_NONCOPYABLE(PaintTiming); USING_GARBAGE_COLLECTED_MIXIN(PaintTiming); + friend class FirstMeaningfulPaintDetector; + using ReportTimeCallback = + WTF::Function<void(WebLayerTreeView::SwapResult, double)>; public: virtual ~PaintTiming() {} static PaintTiming& From(Document&); - // mark*() methods record the time for the given paint event, record a trace - // event, and notify that paint timing has changed. These methods do nothing + // Mark*() methods record the time for the given paint event and queue a swap + // promise to record the |first_*_swap_| timestamp. These methods do nothing // (early return) if a time has already been recorded for the given paint // event. void MarkFirstPaint(); - // markFirstTextPaint, markFirstImagePaint, and markFirstContentfulPaint + // MarkFirstTextPaint, MarkFirstImagePaint, and MarkFirstContentfulPaint // will also record first paint if first paint hasn't been recorded yet. void MarkFirstContentfulPaint(); - // markFirstTextPaint and markFirstImagePaint will also record first + // MarkFirstTextPaint and MarkFirstImagePaint will also record first // contentful paint if first contentful paint hasn't been recorded yet. void MarkFirstTextPaint(); void MarkFirstImagePaint(); @@ -58,32 +62,26 @@ // given paint event has not yet occurred. See the comments for // monotonicallyIncreasingTime in wtf/CurrentTime.h for additional details. - // firstPaint returns the first time that anything was painted for the + // FirstPaint returns the first time that anything was painted for the // current document. - double FirstPaint() const { return first_paint_; } + double FirstPaint() const { return first_paint_swap_; } - // firstContentfulPaint returns the first time that 'contentful' content was + // FirstContentfulPaint returns the first time that 'contentful' content was // painted. For instance, the first time that text or image content was // painted. - double FirstContentfulPaint() const { return first_contentful_paint_; } - double FirstContentfulPaintSwap() const { - return first_contentful_paint_swap_; - } + double FirstContentfulPaint() const { return first_contentful_paint_swap_; } - // firstTextPaint returns the first time that text content was painted. - double FirstTextPaint() const { return first_text_paint_; } + // FirstTextPaint returns the first time that text content was painted. + double FirstTextPaint() const { return first_text_paint_swap_; } - // firstImagePaint returns the first time that image content was painted. - double FirstImagePaint() const { return first_image_paint_; } + // FirstImagePaint returns the first time that image content was painted. + double FirstImagePaint() const { return first_image_paint_swap_; } - // firstMeaningfulPaint returns the first time that page's primary content + // FirstMeaningfulPaint returns the first time that page's primary content // was painted. - double FirstMeaningfulPaint() const { return first_meaningful_paint_; } - double FirstMeaningfulPaintSwap() const { - return first_meaningful_paint_swap_; - } + double FirstMeaningfulPaint() const { return first_meaningful_paint_swap_; } - // firstMeaningfulPaintCandidate indicates the first time we considered a + // FirstMeaningfulPaintCandidate indicates the first time we considered a // paint to qualify as the potentially first meaningful paint. Unlike // firstMeaningfulPaint, this signal is available in real time, but it may be // an optimistic (i.e., too early) estimate. @@ -95,9 +93,12 @@ return *fmp_detector_; } - void RegisterNotifySwapTime(PaintEvent, - WTF::Function<void(bool, double)> callback); - void ReportSwapTime(PaintEvent, bool did_swap, double timestamp); + void RegisterNotifySwapTime(PaintEvent, ReportTimeCallback); + void ReportSwapTime(PaintEvent, + WebLayerTreeView::SwapResult, + double timestamp); + + void ReportSwapResultHistogram(const WebLayerTreeView::SwapResult); DECLARE_VIRTUAL_TRACE(); @@ -106,26 +107,52 @@ LocalFrame* GetFrame() const; void NotifyPaintTimingChanged(); - // set*() set the timing for the given paint event to the given timestamp - // and record a trace event if the value is currently zero, but do not - // notify that paint timing changed. These methods can be invoked from other - // mark*() or set*() methods to make sure that first paint is marked as part - // of marking first contentful paint, or that first contentful paint is - // marked as part of marking first text/image paint, for example. + // Set*() set the timing for the given paint event to the given timestamp if + // the value is currently zero, and queue a swap promise to record the + // |first_*_swap_| timestamp. These methods can be invoked from other Mark*() + // or Set*() methods to make sure that first paint is marked as part of + // marking first contentful paint, or that first contentful paint is marked as + // part of marking first text/image paint, for example. void SetFirstPaint(double stamp); // setFirstContentfulPaint will also set first paint time if first paint // time has not yet been recorded. void SetFirstContentfulPaint(double stamp); + // Set*Swap() are called when the SwapPromise is fulfilled and the swap + // timestamp is available. These methods will record trace events, update Web + // Perf API (FP and FCP only), and notify that paint timing has changed, which + // triggers UMAs and UKMS. + // |stamp| is the swap timestamp used for tracing, UMA, UKM, and Web Perf API. + void SetFirstPaintSwap(double stamp); + void SetFirstContentfulPaintSwap(double stamp); + void SetFirstImagePaintSwap(double stamp); + void SetFirstTextPaintSwap(double stamp); + void RegisterNotifySwapTime(PaintEvent); void ReportUserInputHistogram( FirstMeaningfulPaintDetector::HadUserInput had_input); + void ReportSwapTimeDeltaHistogram(double timestamp, double swap_timestamp); + double FirstPaintRendered() const { return first_paint_; } + + double FirstContentfulPaintRendered() const { + return first_contentful_paint_; + } + + double FirstMeaningfulPaintRendered() const { + return first_meaningful_paint_; + } + + // TODO(crbug/738235): Non first_*_swap_ variables are only being tracked to + // compute deltas for reporting histograms and should be removed once we + // confirm the deltas and discrepancies look reasonable. double first_paint_ = 0.0; double first_paint_swap_ = 0.0; double first_text_paint_ = 0.0; + double first_text_paint_swap_ = 0.0; double first_image_paint_ = 0.0; + double first_image_paint_swap_ = 0.0; double first_contentful_paint_ = 0.0; double first_contentful_paint_swap_ = 0.0; double first_meaningful_paint_ = 0.0; @@ -133,6 +160,43 @@ double first_meaningful_paint_candidate_ = 0.0; Member<FirstMeaningfulPaintDetector> fmp_detector_; + + FRIEND_TEST_ALL_PREFIXES(FirstMeaningfulPaintDetectorTest, NoFirstPaint); + FRIEND_TEST_ALL_PREFIXES(FirstMeaningfulPaintDetectorTest, OneLayout); + FRIEND_TEST_ALL_PREFIXES(FirstMeaningfulPaintDetectorTest, + TwoLayoutsSignificantSecond); + FRIEND_TEST_ALL_PREFIXES(FirstMeaningfulPaintDetectorTest, + TwoLayoutsSignificantFirst); + FRIEND_TEST_ALL_PREFIXES(FirstMeaningfulPaintDetectorTest, + FirstMeaningfulPaintCandidate); + FRIEND_TEST_ALL_PREFIXES( + FirstMeaningfulPaintDetectorTest, + OnlyOneFirstMeaningfulPaintCandidateBeforeNetworkStable); + FRIEND_TEST_ALL_PREFIXES(FirstMeaningfulPaintDetectorTest, + NetworkStableBeforeFirstContentfulPaint); + FRIEND_TEST_ALL_PREFIXES( + FirstMeaningfulPaintDetectorTest, + FirstMeaningfulPaintShouldNotBeBeforeFirstContentfulPaint); + FRIEND_TEST_ALL_PREFIXES(FirstMeaningfulPaintDetectorTest, + Network2QuietThen0Quiet); + FRIEND_TEST_ALL_PREFIXES(FirstMeaningfulPaintDetectorTest, + Network0QuietThen2Quiet); + FRIEND_TEST_ALL_PREFIXES(FirstMeaningfulPaintDetectorTest, + Network0QuietTimer); + FRIEND_TEST_ALL_PREFIXES(FirstMeaningfulPaintDetectorTest, + Network2QuietTimer); + FRIEND_TEST_ALL_PREFIXES(FirstMeaningfulPaintDetectorTest, + FirstMeaningfulPaintAfterUserInteraction); + FRIEND_TEST_ALL_PREFIXES(FirstMeaningfulPaintDetectorTest, + UserInteractionBeforeFirstPaint); + FRIEND_TEST_ALL_PREFIXES( + FirstMeaningfulPaintDetectorTest, + WaitForSingleOutstandingSwapPromiseAfterNetworkStable); + FRIEND_TEST_ALL_PREFIXES( + FirstMeaningfulPaintDetectorTest, + WaitForMultipleOutstandingSwapPromisesAfterNetworkStable); + FRIEND_TEST_ALL_PREFIXES(FirstMeaningfulPaintDetectorTest, + WaitForFirstContentfulPaintSwapAfterNetworkStable); }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/resize_observer/README.md b/third_party/WebKit/Source/core/resize_observer/README.md new file mode 100644 index 0000000..47f9aa44 --- /dev/null +++ b/third_party/WebKit/Source/core/resize_observer/README.md
@@ -0,0 +1,68 @@ +# ResizeObserver + +Implements ResizeObserver [spec]( https://github.com/WICG/ResizeObserver), which has a nice [explainer](https://github.com/WICG/ResizeObserver/blob/master/explainer.md). + +The purpose of ResizeObserver is to expose a ResizeObserver DOM API that +notifies observer when Element's size has changed. + +# Architecture overview + +The externally exposed APIs are: + +[`ResizeObserver.idl`](ResizeObserver.idl) implements a general observer pattern, observe(), unobserve(), disconnect(). + +[`ResizeObserverEntry.idl`](ResizeObserverEntry.idl) represents an observation to be delivered, with target and contentRect. + +Classes used internally are: + +[`ResizeObservation`](ResizeObservation.h) internal representation of an Element that is being observed, and its last observed size. + +[`ResizeObserverController`](ResizeObservationController.h) ties Document to its ResizeObservers. + +# Notification lifecycle + +ResizeObserver needs to deliver notifications before every animation frame. + +There are 2 phases of notification lifecycle: + +###### 1) Size change detection + +`ResizeObservation` stores last observed element size. + +There are 2 ways to detect size change. One way is "pull", where every watched +Element's size is compared to last observed size. This is inefficient, because +all observed Elements must be polled in every frame. + +That is why we use "push", where Element sets a flag that it's size has changed. +The flag gets set by calling `Element::SetNeedsResizeObserverUpdate()`. This +notifies ResizeObservation, which also notifies ResizeObserver. +`SetNeedsResizeObserverUpdate` has to be carefully added to all places +that might trigger a resize observation. + +###### 2) Notification delivery + +Notification delivery is done by calling `LocalFrameView::NotifyResizeObservers()` +for every rAF. It calls `ResizeObserverController::DeliverObservations()` +which delivers observations for all ResizeObservers that have detected size changes. +`DeliverObservations()` will not run if size has not changed. To deliver initial +observation, ResizeObserver must call `LocalFrameView::ScheduleAnimation`. + +# Object lifetime + +ResizeObserver objects are garbage collected. Figuring out how to arrange references +to ensure proper lifetime is tricky. + +ResizeObserver must be kept alive as long as at least one of these is true: +1) There is a Javascript reference to ResizeObserver. +2) There is an active observation. This happens when Javascript has no more +references to ResizeObserver, but observations should still be delivered. + +You can use the reference chain below to trace object lifetime chain: +``` +Javascript => ResizeObserver +Element.resize_observer_data_ => ResizeObserver, ResizeObservation +Document.resize_observer_controller_ => ResizeObserverController +ResizeObserver => ResizeObserverEntry +ResizeObserver => ResizeObserverCallback +ResizeObserverEntry => Element +```
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp index c524206..03842d7 100644 --- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp +++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
@@ -32,6 +32,7 @@ #include "bindings/core/v8/SourceLocation.h" #include "bindings/core/v8/V8AbstractEventListener.h" #include "bindings/core/v8/WorkerOrWorkletScriptController.h" +#include "core/css/OffscreenFontSelector.h" #include "core/dom/ContextLifecycleNotifier.h" #include "core/dom/ExceptionCode.h" #include "core/dom/SuspendableObject.h" @@ -370,7 +371,8 @@ thread_(thread), event_queue_(WorkerEventQueue::Create(this)), timers_(TaskRunnerHelper::Get(TaskType::kTimer, this)), - time_origin_(time_origin) { + time_origin_(time_origin), + font_selector_(OffscreenFontSelector::Create()) { InstanceCounters::IncrementCounter( InstanceCounters::kWorkerGlobalScopeCounter); SetSecurityOrigin(SecurityOrigin::Create(url)); @@ -406,6 +408,8 @@ std::unique_ptr<WorkerSettings> worker_settings) { worker_settings_ = std::move(worker_settings); worker_settings_->MakeGenericFontFamilySettingsAtomic(); + font_selector_->UpdateGenericFontFamilySettings( + worker_settings_->GetGenericFontFamilySettings()); } void WorkerGlobalScope::ExceptionThrown(ErrorEvent* event) { @@ -433,6 +437,7 @@ visitor->Trace(timers_); visitor->Trace(event_listeners_); visitor->Trace(pending_error_events_); + visitor->Trace(font_selector_); EventTargetWithInlineData::Trace(visitor); SecurityContext::Trace(visitor); WorkerOrWorkletGlobalScope::Trace(visitor);
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h index 9fdd4397..40f364f 100644 --- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h +++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
@@ -6,9 +6,9 @@ * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -48,6 +48,7 @@ class ConsoleMessage; class ExceptionState; +class OffscreenFontSelector; class V8AbstractEventListener; class WorkerLocation; class WorkerNavigator; @@ -130,6 +131,8 @@ WorkerEventQueue* GetEventQueue() const final; bool IsSecureContext(String& error_message) const override; + OffscreenFontSelector* GetFontSelector() { return font_selector_; } + CoreProbeSink* GetProbeSink() final; // EventTarget @@ -224,6 +227,8 @@ HeapHashMap<int, Member<ErrorEvent>> pending_error_events_; int last_pending_error_event_id_ = 0; + + Member<OffscreenFontSelector> font_selector_; }; DEFINE_TYPE_CASTS(WorkerGlobalScope,
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp index 32e02d67..7637740 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
@@ -473,8 +473,7 @@ DCHECK(font_lru_list_.Contains(new_font)); font_lru_list_.erase(new_font); font_lru_list_.insert(new_font); - ModifiableState().SetFont( - i->value, canvas()->GetDocument().GetStyleEngine().GetFontSelector()); + ModifiableState().SetFont(i->value, host()->GetFontSelector()); } else { MutableStylePropertySet* parsed_style = canvas_font_cache->ParseFont(new_font); @@ -508,17 +507,13 @@ font_lru_list_.insert(new_font); PruneLocalFontCache(canvas_font_cache->HardMaxFonts()); // hard limit should_prune_local_font_cache_ = true; // apply soft limit - ModifiableState().SetFont( - final_font, - canvas()->GetDocument().GetStyleEngine().GetFontSelector()); + ModifiableState().SetFont(final_font, host()->GetFontSelector()); } } else { Font resolved_font; if (!canvas_font_cache->GetFontUsingDefaultStyle(new_font, resolved_font)) return; - ModifiableState().SetFont( - resolved_font, - canvas()->GetDocument().GetStyleEngine().GetFontSelector()); + ModifiableState().SetFont(resolved_font, host()->GetFontSelector()); } // The parse succeeded.
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp index fb1ff16..7daad30 100644 --- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp
@@ -35,8 +35,6 @@ Settings* settings = ToDocument(execution_context)->GetSettings(); if (settings->GetDisableReadingFromCanvas()) canvas->SetDisableReadingFromCanvasTrue(); - font_selector_ = - OffscreenFontSelector::Create(settings->GetGenericFontFamilySettings()); return; } dirty_rect_for_commit_.setEmpty(); @@ -44,12 +42,9 @@ ToWorkerGlobalScope(execution_context)->GetWorkerSettings(); if (worker_settings && worker_settings->DisableReadingFromCanvas()) canvas->SetDisableReadingFromCanvasTrue(); - font_selector_ = OffscreenFontSelector::Create( - worker_settings->GetGenericFontFamilySettings()); } DEFINE_TRACE(OffscreenCanvasRenderingContext2D) { - visitor->Trace(font_selector_); CanvasRenderingContext::Trace(visitor); BaseRenderingContext2D::Trace(visitor); } @@ -298,7 +293,7 @@ FontDescription desc = FontStyleResolver::ComputeFont(*style); Font font = Font(desc); - ModifiableState().SetFont(font, font_selector_); + ModifiableState().SetFont(font, host()->GetFontSelector()); ModifiableState().SetUnparsedFont(new_font); }
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h index 4cc50ef..425e3af 100644 --- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h +++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h
@@ -14,7 +14,6 @@ namespace blink { class Font; -class OffscreenFontSelector; class TextMetrics; class MODULES_EXPORT OffscreenCanvasRenderingContext2D final @@ -140,8 +139,6 @@ String ColorSpaceAsString() const override; CanvasPixelFormat PixelFormat() const override; SkIRect dirty_rect_for_commit_; - - Member<OffscreenFontSelector> font_selector_; }; DEFINE_TYPE_CASTS(OffscreenCanvasRenderingContext2D,
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioBuffer.cpp b/third_party/WebKit/Source/modules/webaudio/AudioBuffer.cpp index 3e883d5..7ad0ec8 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioBuffer.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioBuffer.cpp
@@ -162,7 +162,7 @@ switch (policy) { case kZeroInitialize: - buffer = WTF::Float32Array::Create(length); + buffer = WTF::Float32Array::CreateOrNull(length); break; case kDontInitialize: buffer = WTF::Float32Array::CreateUninitializedOrNull(length);
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp index db0a8214..cb634a1 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
@@ -95,7 +95,7 @@ std::unique_ptr<FakeGraphicsLayer> clip_layer_; private: - std::unique_ptr<WebLayerTreeView> layer_tree_view_; + std::unique_ptr<WebLayerTreeViewImplForTesting> layer_tree_view_; FakeGraphicsLayerClient client_; };
diff --git a/third_party/WebKit/Source/platform/plugins/PluginData.cpp b/third_party/WebKit/Source/platform/plugins/PluginData.cpp index c4fb8d7..5eb6af5f 100644 --- a/third_party/WebKit/Source/platform/plugins/PluginData.cpp +++ b/third_party/WebKit/Source/platform/plugins/PluginData.cpp
@@ -53,7 +53,7 @@ } const MimeClassInfo* PluginInfo::GetMimeClassInfo(size_t index) const { - if (index > mimes_.size()) + if (index >= mimes_.size()) return nullptr; return mimes_[index]; }
diff --git a/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp b/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp index 90e3280..612fa5a 100644 --- a/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp +++ b/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp
@@ -53,6 +53,13 @@ layer_tree_host_.get(); } +void WebLayerTreeViewImplForTesting::SetViewportSize( + const WebSize& device_viewport_size) { + gfx::Size gfx_size(std::max(0, device_viewport_size.width), + std::max(0, device_viewport_size.height)); + layer_tree_host_->SetViewportSize(gfx_size); +} + void WebLayerTreeViewImplForTesting::SetRootLayer(const blink::WebLayer& root) { layer_tree_host_->SetRootLayer( static_cast<const cc_blink::WebLayerImpl*>(&root)->layer()); @@ -66,21 +73,6 @@ return animation_host_.get(); } -void WebLayerTreeViewImplForTesting::SetViewportSize( - const WebSize& unused_deprecated, - const WebSize& device_viewport_size) { - gfx::Size gfx_size(std::max(0, device_viewport_size.width), - std::max(0, device_viewport_size.height)); - layer_tree_host_->SetViewportSize(gfx_size); -} - -void WebLayerTreeViewImplForTesting::SetViewportSize( - const WebSize& device_viewport_size) { - gfx::Size gfx_size(std::max(0, device_viewport_size.width), - std::max(0, device_viewport_size.height)); - layer_tree_host_->SetViewportSize(gfx_size); -} - WebSize WebLayerTreeViewImplForTesting::GetViewportSize() const { return WebSize(layer_tree_host_->device_viewport_size().width(), layer_tree_host_->device_viewport_size().height());
diff --git a/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.h b/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.h index 6efd9cba..46a4058 100644 --- a/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.h +++ b/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.h
@@ -36,14 +36,12 @@ static cc::LayerTreeSettings DefaultLayerTreeSettings(); cc::LayerTreeHost* GetLayerTreeHost() { return layer_tree_host_.get(); } bool HasLayer(const WebLayer&); + void SetViewportSize(const blink::WebSize&); // blink::WebLayerTreeView implementation. void SetRootLayer(const blink::WebLayer&) override; void ClearRootLayer() override; cc::AnimationHost* CompositorAnimationHost() override; - virtual void SetViewportSize(const blink::WebSize& unused_deprecated, - const blink::WebSize& device_viewport_size); - void SetViewportSize(const blink::WebSize&) override; WebSize GetViewportSize() const override; void SetDeviceScaleFactor(float) override; void SetBackgroundColor(blink::WebColor) override;
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py index 4bffc342..9e93d3b 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
@@ -78,7 +78,7 @@ _, show_ref_output = self.run(['git', 'show-ref', 'origin/master'], cwd=local_wpt.path) import_commit = 'wpt@%s' % show_ref_output.split()[0] - _log.info('Importing wpt@%s to Chromium %s', import_commit, chromium_commit) + _log.info('Importing %s to Chromium %s', import_commit, chromium_commit) commit_message = self._commit_message(chromium_commit, import_commit)
diff --git a/third_party/WebKit/public/blink_typemaps.gni b/third_party/WebKit/public/blink_typemaps.gni index 7bb342b..aab6457 100644 --- a/third_party/WebKit/public/blink_typemaps.gni +++ b/third_party/WebKit/public/blink_typemaps.gni
@@ -7,7 +7,7 @@ "//cc/ipc/frame_sink_id.typemap", "//cc/ipc/local_surface_id.typemap", "//cc/ipc/surface_id.typemap", - "//cc/ipc/surface_sequence.typemap", + "//services/viz/public/cpp/compositing/surface_sequence.typemap", "//gpu/ipc/common/mailbox_holder_for_blink.typemap", "//gpu/ipc/common/sync_token.typemap", "//services/viz/public/cpp/compositing/compositor_frame_for_blink.typemap",
diff --git a/third_party/WebKit/public/platform/WebLayerTreeView.h b/third_party/WebKit/public/platform/WebLayerTreeView.h index 358409e9..a341f0e 100644 --- a/third_party/WebKit/public/platform/WebLayerTreeView.h +++ b/third_party/WebKit/public/platform/WebLayerTreeView.h
@@ -35,6 +35,7 @@ #include "WebImageLayer.h" #include "WebSize.h" #include "base/callback.h" +#include "cc/output/swap_promise.h" #include "components/viz/common/surfaces/frame_sink_id.h" #include "third_party/skia/include/core/SkImage.h" @@ -53,9 +54,22 @@ class WebSelection; class WebLayerTreeView { - using ReportTimeCallback = base::Callback<void(bool, double)>; - public: + // SwapResult mirrors the values of cc::SwapPromise::DidNotSwapReason, and + // should be kept consistent with it. SwapResult additionally adds a success + // value (kDidSwap). + // These values are written to logs. New enum values can be added, but + // existing enums must never be renumbered, deleted or reused. + enum SwapResult { + kDidSwap = 0, + kDidNotSwapSwapFails = 1, + kDidNotSwapCommitFails = 2, + kDidNotSwapCommitNoUpdate = 3, + kDidNotSwapActivationFails = 4, + kSwapResultMax, + }; + using ReportTimeCallback = base::Callback<void(SwapResult, double)>; + virtual ~WebLayerTreeView() {} // Initialization and lifecycle -------------------------------------- @@ -70,7 +84,6 @@ // View properties --------------------------------------------------- // Viewport size is given in physical pixels. - virtual void SetViewportSize(const WebSize& device_viewport_size) {} virtual WebSize GetViewportSize() const { return WebSize(); } virtual void SetDeviceScaleFactor(float) {}
diff --git a/third_party/WebKit/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom b/third_party/WebKit/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom index 870a31817..d7f62a09 100644 --- a/third_party/WebKit/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom +++ b/third_party/WebKit/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom
@@ -6,13 +6,13 @@ import "cc/ipc/frame_sink_id.mojom"; import "cc/ipc/surface_id.mojom"; -import "cc/ipc/surface_sequence.mojom"; import "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom"; import "services/viz/public/interfaces/compositing/surface_info.mojom"; +import "services/viz/public/interfaces/compositing/surface_sequence.mojom"; interface OffscreenCanvasSurface { - Require(cc.mojom.SurfaceId surface_id, cc.mojom.SurfaceSequence sequence); - Satisfy(cc.mojom.SurfaceSequence sequence); + Require(cc.mojom.SurfaceId surface_id, viz.mojom.SurfaceSequence sequence); + Satisfy(viz.mojom.SurfaceSequence sequence); }; interface OffscreenCanvasSurfaceClient {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 3d561bc..b8274150 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -3429,6 +3429,11 @@ <int value="1" label="Needs to be clearred"/> </enum> +<enum name="BooleanNetworkQuietBeforeSwap"> + <int value="0" label="FMP OK, network not yet quiet"/> + <int value="1" label="FMP not OK, network was already quiet"/> +</enum> + <enum name="BooleanNullStream"> <int value="0" label="Stream is not a nullptr"/> <int value="1" label="Stream is a nullptr"/> @@ -4200,6 +4205,7 @@ <int value="1" label="Omnibox Focus"/> <int value="2" label="New Tab Creation"/> <int value="3" label="Expand Button Pressed"/> + <int value="4" label="Browser Startup"/> </enum> <enum name="ChromeNotifierServiceActionType"> @@ -36438,6 +36444,14 @@ <int value="1" label="YUY2"/> </enum> +<enum name="SwapResult"> + <int value="0" label="Swap was successful"/> + <int value="1" label="Swap was unsuccessful (swap fails)"/> + <int value="2" label="Swap was unsuccessful (commit fails)"/> + <int value="3" label="Swap was unsuccessful (commit no update)"/> + <int value="4" label="Swap was unsuccessful (activation fails)"/> +</enum> + <enum name="SwReporterRunningTimeRegistryError"> <int value="0" label="No error"/> <int value="1" label="Registry key invalid"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 148e47d9..5799cad8 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -52380,6 +52380,37 @@ </summary> </histogram> +<histogram name="PageLoad.Internal.Renderer.PaintTiming.SwapResult" + enum="SwapResult"> + <owner>panicker@chromium.org</owner> + <summary> + For first paint, first contentful paint, first meaningful paint, first text + paint, and first image paint, we use the swap timestamp of the corresponding + paint, which is the timestamp the CC SwapPromise was positively fulfilled + (i.e. DidSwap() was invoked). If the swap did not occur (DidNotSwap() was + invoked), we use the timestamp when the swap promise fails. However, in the + future we may stop reporting timestamps for certain failure reasons. This + metric records whether or not the swap occurred, and the reason for failure + if it failed. The distribution of this metric will help determine the effect + of not reporting timestamps in certain cases. + </summary> +</histogram> + +<histogram name="PageLoad.Internal.Renderer.PaintTiming.SwapTimeDelta" + units="ms"> + <owner>panicker@chromium.org</owner> + <summary> + Records the delta between the renderer timestamp and swap timestamp for + first paint, first contentful paint, first meaningful paint, first text + paint, and first image paint. The renderer timestamp is recorded on the + Paint path, while the swap timestamp is the result of a CC SwapPromise + (queued on the Paint path) either being successfully fulfilled, or broken in + cases where the swap did not occur. As we switch to using the swap + timestamps in place of their renderer counterparts, this metric allows us to + see the discrepancies between the two timestamps. + </summary> +</histogram> + <histogram name="PageLoad.Navigation.RedirectChainLength" units="urls"> <owner>csharrison@chromium.org</owner> <summary> @@ -54345,6 +54376,9 @@ <histogram name="PaymentRequest.CanMakePayment.NotUsed.WithShowEffectOnCompletion" enum="PaymentRequestFlowCompletionStatus"> + <obsolete> + M62+ Part of PaymentRequest.Events + </obsolete> <owner>sebsg@chromium.org</owner> <summary> Whether the flow was completed when CanMakePayment was not called by the @@ -54354,6 +54388,9 @@ <histogram name="PaymentRequest.CanMakePayment.Usage" enum="CanMakePaymentUsage"> + <obsolete> + M62+ Part of PaymentRequest.Events + </obsolete> <owner>sebsg@chromium.org</owner> <summary> Whether the merchant used the CanMakePayment method during a Payment @@ -54363,6 +54400,9 @@ <histogram name="PaymentRequest.CanMakePayment.Used.EffectOnShow" enum="PaymentRequestCanMakePaymentEffectOnShow"> + <obsolete> + M62+ Part of PaymentRequest.Events + </obsolete> <owner>sebsg@chromium.org</owner> <summary> The effect of the CanMakePayment return value on whether Show was called. @@ -54372,6 +54412,9 @@ <histogram name="PaymentRequest.CanMakePayment.Used.FalseWithShowEffectOnCompletion" enum="PaymentRequestFlowCompletionStatus"> + <obsolete> + M62+ Part of PaymentRequest.Events + </obsolete> <owner>sebsg@chromium.org</owner> <summary> Whether the flow was completed when CanMakePayment was called by the @@ -54382,6 +54425,9 @@ <histogram name="PaymentRequest.CanMakePayment.Used.TrueWithShowEffectOnCompletion" enum="PaymentRequestFlowCompletionStatus"> + <obsolete> + M62+ Part of PaymentRequest.Events + </obsolete> <owner>sebsg@chromium.org</owner> <summary> Whether the flow was completed when CanMakePayment was called by the @@ -54522,6 +54568,9 @@ <histogram name="PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything.EffectOnCompletion" enum="PaymentRequestFlowCompletionStatus"> + <obsolete> + M62+ Part of PaymentRequest.Events + </obsolete> <owner>sebsg@chromium.org</owner> <summary> Whether the flow was completed when the user did not have a complete @@ -54546,6 +54595,9 @@ <histogram name="PaymentRequest.UserDidNotHaveSuggestionsForEverything.EffectOnCompletion" enum="PaymentRequestFlowCompletionStatus"> + <obsolete> + M62+ Part of PaymentRequest.Events + </obsolete> <owner>sebsg@chromium.org</owner> <summary> Whether the flow was completed when the user did not have suggestions @@ -54556,6 +54608,9 @@ <histogram name="PaymentRequest.UserHadCompleteSuggestionsForEverything.EffectOnCompletion" enum="PaymentRequestFlowCompletionStatus"> + <obsolete> + M62+ Part of PaymentRequest.Events + </obsolete> <owner>sebsg@chromium.org</owner> <summary> Whether the flow was completed when the user had at least one complete @@ -97548,23 +97603,25 @@ <suffix name="OtherAborted" label="The Payment Request was aborted but not but the user"/> <affected-histogram name="PaymentRequest.NumberOfSelectionAdds.ContactInfo"/> - <affected-histogram name="PaymentRequest.NumberOfSelectionAdds.CreditCards"/> + <affected-histogram + name="PaymentRequest.NumberOfSelectionAdds.PaymentMethod"/> <affected-histogram name="PaymentRequest.NumberOfSelectionAdds.ShippingAddress"/> <affected-histogram name="PaymentRequest.NumberOfSelectionChanges.ContactInfo"/> <affected-histogram - name="PaymentRequest.NumberOfSelectionChanges.CreditCards"/> + name="PaymentRequest.NumberOfSelectionChanges.PaymentMethod"/> <affected-histogram name="PaymentRequest.NumberOfSelectionChanges.ShippingAddress"/> <affected-histogram name="PaymentRequest.NumberOfSelectionEdits.ContactInfo"/> - <affected-histogram name="PaymentRequest.NumberOfSelectionEdits.CreditCards"/> + <affected-histogram + name="PaymentRequest.NumberOfSelectionEdits.PaymentMethod"/> <affected-histogram name="PaymentRequest.NumberOfSelectionEdits.ShippingAddress"/> <affected-histogram name="PaymentRequest.NumberOfSuggestionsShown.ContactInfo"/> <affected-histogram - name="PaymentRequest.NumberOfSuggestionsShown.CreditCards"/> + name="PaymentRequest.NumberOfSuggestionsShown.PaymentMethod"/> <affected-histogram name="PaymentRequest.NumberOfSuggestionsShown.ShippingAddress"/> </histogram_suffixes> @@ -97572,8 +97629,14 @@ <histogram_suffixes name="PaymentRequestSection" separator="."> <suffix name="ContactInfo" label="For the contact info section of a Payment Request"/> + <suffix name="PaymentMethod" + label="For the payment method section of a Payment Request"/> <suffix name="CreditCards" - label="For the credit card section of a Payment Request"/> + label="For the payment method section of a Payment Request"> + <obsolete> + Renamed to PaymentMethod. + </obsolete> + </suffix> <suffix name="ShippingAddress" label="For the shipping address section of a Payment Request"/> <affected-histogram name="PaymentRequest.NumberOfSelectionAdds"/>
diff --git a/tools/perf/benchmarks/benchmark_smoke_unittest.py b/tools/perf/benchmarks/benchmark_smoke_unittest.py index 71cd4889..dc4fef9 100644 --- a/tools/perf/benchmarks/benchmark_smoke_unittest.py +++ b/tools/perf/benchmarks/benchmark_smoke_unittest.py
@@ -100,6 +100,12 @@ battor #Flaky on android, crbug.com/618330. } +# The list of benchmark names to be excluded from our smoke tests. +_BLACK_LIST_TEST_NAMES = [ + 'memory.long_running_idle_gmail_background_tbmv2', + 'tab_switching.typical_25', +] + def MergeDecorators(method, method_attribute, benchmark, benchmark_attribute): # Do set union of attributes to eliminate duplicates. @@ -124,6 +130,8 @@ for benchmark in all_benchmarks: if sys.modules[benchmark.__module__] in _BLACK_LIST_TEST_MODULES: continue + if benchmark.Name() in _BLACK_LIST_TEST_NAMES: + continue class BenchmarkSmokeTest(unittest.TestCase): pass
diff --git a/ui/app_list/views/apps_grid_view.cc b/ui/app_list/views/apps_grid_view.cc index 4302cfb..20811b3 100644 --- a/ui/app_list/views/apps_grid_view.cc +++ b/ui/app_list/views/apps_grid_view.cc
@@ -61,6 +61,9 @@ // Padding space in pixels between pages. constexpr int kPagePadding = 40; +// Extra page padding which ensures that the page break space for apps are 48px. +constexpr int kExtraPagePdding = 36; + // Preferred tile size when showing in fixed layout. constexpr int kPreferredTileWidth = 100; constexpr int kPreferredTileHeight = 100; @@ -1303,22 +1306,24 @@ gfx::Vector2d offset = CalculateTransitionOffset(view_index.page); const PaginationModel::Transition& transition = pagination_model_.transition(); - // When transition is progressing, eliminate empty spaces between pages. if (is_fullscreen_app_list_enabled_ && transition.progress > 0) { const int current_page = pagination_model_.selected_page(); const bool forward = transition.target_page > current_page ? true : false; - // When transiting to previous page, eliminate empty space from just - // previous page since only the previous page is visiable; vice versa. + // When transiting to previous page, ensure 48px page break space from + // just previous page since only the previous page could be visiable; + // and vice versa. if (!forward && view_index.page == current_page - 1) { if (view_index.page == 0) { offset.set_y(offset.y() + GetHeightOnTopOfAllAppsTiles(0) - GetHeightOnTopOfAllAppsTiles(1) - - 2 * kTileVerticalPadding); + 2 * kTileVerticalPadding - kExtraPagePdding); } else { - offset.set_y(offset.y() + GetHeightOnTopOfAllAppsTiles(current_page)); + offset.set_y(offset.y() + GetHeightOnTopOfAllAppsTiles(current_page) - + kExtraPagePdding); } } else if (forward && view_index.page == current_page + 1) { - offset.set_y(offset.y() - GetHeightOnTopOfAllAppsTiles(current_page)); + offset.set_y(offset.y() - GetHeightOnTopOfAllAppsTiles(current_page) + + kExtraPagePdding); } } tile_slot.Offset(offset.x(), offset.y());
diff --git a/ui/app_list/views/search_box_view.cc b/ui/app_list/views/search_box_view.cc index 6cbddf10..c8a5c68 100644 --- a/ui/app_list/views/search_box_view.cc +++ b/ui/app_list/views/search_box_view.cc
@@ -325,7 +325,7 @@ NOTREACHED(); } - SetSelected(focused_view_ == FOCUS_SEARCH_BOX); + SetSelected(search_box_->text().empty() && focused_view_ == FOCUS_SEARCH_BOX); return (focused_view_ < FOCUS_CONTENTS_VIEW); }
diff --git a/ui/ozone/platform/headless/headless_surface_factory.cc b/ui/ozone/platform/headless/headless_surface_factory.cc index d3c9f35..444c32a4 100644 --- a/ui/ozone/platform/headless/headless_surface_factory.cc +++ b/ui/ozone/platform/headless/headless_surface_factory.cc
@@ -10,6 +10,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/task_scheduler/post_task.h" +#include "build/build_config.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkSurface.h" #include "ui/gfx/codec/png_codec.h" @@ -108,14 +109,24 @@ HeadlessSurfaceFactory::HeadlessSurfaceFactory( HeadlessWindowManager* window_manager) - : window_manager_(window_manager), - osmesa_implementation_(base::MakeUnique<GLOzoneOSMesa>()) {} + : window_manager_(window_manager) { +#if !defined(OS_FUCHSIA) + osmesa_implementation_ = base::MakeUnique<GLOzoneOSMesa>(); +#endif +} HeadlessSurfaceFactory::~HeadlessSurfaceFactory() {} std::vector<gl::GLImplementation> HeadlessSurfaceFactory::GetAllowedGLImplementations() { +#if defined(OS_FUCHSIA) + // TODO(fuchsia): Enable this or a variant with EGL support when GPU/UI is + // available. (crbug.com/750943) + NOTIMPLEMENTED(); + return std::vector<gl::GLImplementation>{}; +#else return std::vector<gl::GLImplementation>{gl::kGLImplementationOSMesaGL}; +#endif } GLOzone* HeadlessSurfaceFactory::GetGLOzone(
diff --git a/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html b/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html index 20d15055..ad9d19f 100644 --- a/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html +++ b/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html
@@ -64,14 +64,14 @@ outline: none; } - :host ::content .drawer-content { + :host ::slotted(.drawer-content) { height: calc(100% - 56px); overflow: auto; } </style> <div id="container" on-tap="onContainerTap_"> <div class="drawer-header" tabindex="-1">[[heading]]</div> - <content></content> + <slot></slot> </div> </template> </dom-module>