diff --git a/DEPS b/DEPS index a864b57..a0847ba 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '65a88fadab72abd104fdf4cc4a97488b2e901c60', + 'skia_revision': '0ac06e47269a40c177747310a613d213c95d1d6d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '0a326e1f76471a5009e18f970bfa7a0778575323', + 'v8_revision': 'ca06d3ccb68a47c86cae4c403289667617876d9b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'a1a4adff333a739a9126801f008adf97d1487f39', + 'catapult_revision': '6065b9274f907f556afab696d631dd816e325ff8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -130,7 +130,7 @@ Var('chromium_git') + '/chromium/buildtools.git' + '@' + Var('buildtools_revision'), 'src/sdch/open-vcdiff': - Var('chromium_git') + '/external/github.com/google/open-vcdiff.git' + '@' + '2b9bd1fe548520e9355e457a134bab7e2f9c56c0', + Var('chromium_git') + '/external/github.com/google/open-vcdiff.git' + '@' + '7162d8ee5a7f1cca110749ec5c7585cdab3f0144', 'src/third_party/freetype/src': Var('chromium_git') + '/chromium/src/third_party/freetype2.git' + '@' + Var('freetype_revision'), @@ -1208,7 +1208,7 @@ 'action': [ 'python', 'src/build/fuchsia/update_sdk.py', - 'bb4f07c0178ae528aeb9d284333e3d0bf59a0eb7', + '2dea304860bf6cd92b68d20195c46adabc6ad33d', ], }, ],
diff --git a/android_webview/browser/aw_browser_main_parts.cc b/android_webview/browser/aw_browser_main_parts.cc index 07715b2885..7f05440 100644 --- a/android_webview/browser/aw_browser_main_parts.cc +++ b/android_webview/browser/aw_browser_main_parts.cc
@@ -122,17 +122,6 @@ base::android::AttachCurrentThread()); breakpad::CrashDumpObserver::Create(); - if (crash_reporter::IsCrashReporterEnabled()) { - base::FilePath crash_dir; - if (PathService::Get(android_webview::DIR_CRASH_DUMPS, &crash_dir)) { - if (!base::PathExists(crash_dir)) - base::CreateDirectory(crash_dir); - breakpad::CrashDumpObserver::GetInstance()->RegisterClient( - base::MakeUnique<breakpad::CrashDumpManager>( - crash_dir, kAndroidMinidumpDescriptor)); - } - } - // We need to create the safe browsing specific directory even if the // AwSafeBrowsingConfigHelper::GetSafeBrowsingEnabled() is false // initially, because safe browsing can be enabled later at runtime @@ -144,11 +133,19 @@ base::CreateDirectory(safe_browsing_dir); } + base::FilePath crash_dir; + if (crash_reporter::IsCrashReporterEnabled()) { + if (PathService::Get(android_webview::DIR_CRASH_DUMPS, &crash_dir)) { + if (!base::PathExists(crash_dir)) + base::CreateDirectory(crash_dir); + } + } + if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kWebViewSandboxedRenderer)) { // Create the renderers crash manager on the UI thread. breakpad::CrashDumpObserver::GetInstance()->RegisterClient( - base::MakeUnique<AwBrowserTerminator>()); + base::MakeUnique<AwBrowserTerminator>(crash_dir)); } if (base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/android_webview/browser/aw_browser_terminator.cc b/android_webview/browser/aw_browser_terminator.cc index 77f89227..03637aa0 100644 --- a/android_webview/browser/aw_browser_terminator.cc +++ b/android_webview/browser/aw_browser_terminator.cc
@@ -14,6 +14,7 @@ #include "base/logging.h" #include "base/stl_util.h" #include "base/sync_socket.h" +#include "base/task_scheduler/post_task.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_data.h" #include "content/public/browser/notification_service.h" @@ -89,16 +90,14 @@ } // By this point we have moved the minidump to the crash directory, so it can - // now be copied and uploaded. This is guaranteed by the order in which we - // register breakpad::CrashDumpManager and AwBrowserTerminator as - // breakpad::CrashDumpObserver clients over in AwBrowserMainParts - // (CrashDumpManager is registered first). + // now be copied and uploaded. TriggerMinidumpUploading(); } } // namespace -AwBrowserTerminator::AwBrowserTerminator() {} +AwBrowserTerminator::AwBrowserTerminator(base::FilePath crash_dump_dir) + : crash_dump_dir_(crash_dump_dir) {} AwBrowserTerminator::~AwBrowserTerminator() {} @@ -117,12 +116,33 @@ mappings->Transfer(kAndroidWebViewCrashSignalDescriptor, base::ScopedFD(dup(child_pipe->handle()))); } + if (crash_reporter::IsCrashReporterEnabled()) { + base::ScopedFD file( + breakpad::CrashDumpManager::GetInstance()->CreateMinidumpFileForChild( + child_process_id)); + if (file != base::kInvalidPlatformFile) + mappings->Transfer(kAndroidMinidumpDescriptor, std::move(file)); + } } -void AwBrowserTerminator::ProcessTerminationStatus( +void AwBrowserTerminator::OnChildExitAsync( int child_process_id, base::ProcessHandle pid, + content::ProcessType process_type, + base::TerminationStatus termination_status, + base::android::ApplicationState app_state, + base::FilePath crash_dump_dir, std::unique_ptr<base::SyncSocket> pipe) { + if (crash_reporter::IsCrashReporterEnabled()) { + breakpad::CrashDumpManager::GetInstance()->ProcessMinidumpFileFromChild( + crash_dump_dir, child_process_id, process_type, termination_status, + app_state); + } + + if (!pipe.get() || + termination_status == base::TERMINATION_STATUS_NORMAL_TERMINATION) + return; + bool crashed = false; // If the child process hasn't written anything into the pipe. This implies @@ -150,23 +170,27 @@ { base::AutoLock auto_lock(child_process_id_to_pipe_lock_); + // We might get a NOTIFICATION_RENDERER_PROCESS_TERMINATED and a + // NOTIFICATION_RENDERER_PROCESS_CLOSED. In that case we only want + // to process the first notification. const auto& iter = child_process_id_to_pipe_.find(child_process_id); - if (iter == child_process_id_to_pipe_.end()) { - // We might get a NOTIFICATION_RENDERER_PROCESS_TERMINATED and a - // NOTIFICATION_RENDERER_PROCESS_CLOSED. - return; + if (iter != child_process_id_to_pipe_.end()) { + pipe = std::move(iter->second); + DCHECK(pipe->handle() != base::SyncSocket::kInvalidHandle); + child_process_id_to_pipe_.erase(iter); } - pipe = std::move(iter->second); - child_process_id_to_pipe_.erase(iter); } - if (termination_status == base::TERMINATION_STATUS_NORMAL_TERMINATION) - return; - OnRenderProcessGone(child_process_id); - DCHECK(pipe->handle() != base::SyncSocket::kInvalidHandle); - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - base::Bind(&AwBrowserTerminator::ProcessTerminationStatus, - child_process_id, pid, base::Passed(std::move(pipe)))); + if (pipe.get()) { + OnRenderProcessGone(child_process_id); + } + + base::PostTaskWithTraits( + FROM_HERE, + {base::MayBlock(), base::TaskPriority::USER_VISIBLE, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, + base::Bind(&AwBrowserTerminator::OnChildExitAsync, child_process_id, pid, + process_type, termination_status, app_state, crash_dump_dir_, + base::Passed(std::move(pipe)))); } } // namespace android_webview
diff --git a/android_webview/browser/aw_browser_terminator.h b/android_webview/browser/aw_browser_terminator.h index 98430307..a13ce0c8 100644 --- a/android_webview/browser/aw_browser_terminator.h +++ b/android_webview/browser/aw_browser_terminator.h
@@ -8,6 +8,7 @@ #include <map> #include "base/synchronization/lock.h" +#include "components/crash/content/browser/crash_dump_manager_android.h" #include "components/crash/content/browser/crash_dump_observer_android.h" namespace base { @@ -26,7 +27,7 @@ // crash status. class AwBrowserTerminator : public breakpad::CrashDumpObserver::Client { public: - AwBrowserTerminator(); + AwBrowserTerminator(base::FilePath crash_dump_dir); ~AwBrowserTerminator() override; // breakpad::CrashDumpObserver::Client implementation. @@ -39,9 +40,15 @@ base::android::ApplicationState app_state) override; private: - static void ProcessTerminationStatus(int child_process_id, - base::ProcessHandle pid, - std::unique_ptr<base::SyncSocket> pipe); + static void OnChildExitAsync(int child_process_id, + base::ProcessHandle pid, + content::ProcessType process_type, + base::TerminationStatus termination_status, + base::android::ApplicationState app_state, + base::FilePath crash_dump_dir, + std::unique_ptr<base::SyncSocket> pipe); + + base::FilePath crash_dump_dir_; // This map should only be accessed with its lock aquired as it is accessed // from the PROCESS_LAUNCHER, FILE, and UI threads.
diff --git a/android_webview/browser/aw_contents_io_thread_client.cc b/android_webview/browser/aw_contents_io_thread_client.cc index 75a73d5..02ebae7 100644 --- a/android_webview/browser/aw_contents_io_thread_client.cc +++ b/android_webview/browser/aw_contents_io_thread_client.cc
@@ -310,6 +310,8 @@ std::unique_ptr<AwWebResourceResponse> RunShouldInterceptRequest( const AwWebResourceRequest& request, JavaObjectWeakGlobalRef ref) { + base::ThreadRestrictions::AssertIOAllowed(); + JNIEnv* env = AttachCurrentThread(); base::android::ScopedJavaLocalRef<jobject> obj = ref.get(env); if (obj.is_null())
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc index ab41f72f..68c6c81 100644 --- a/ash/accelerators/accelerator_controller.cc +++ b/ash/accelerators/accelerator_controller.cc
@@ -54,6 +54,7 @@ #include "chromeos/chromeos_switches.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/power_manager_client.h" +#include "ui/app_list/app_list_constants.h" #include "ui/app_list/presenter/app_list.h" #include "ui/base/accelerators/accelerator.h" #include "ui/base/accelerators/accelerator_manager.h" @@ -448,7 +449,7 @@ void HandleToggleAppList(const ui::Accelerator& accelerator) { if (accelerator.key_code() == ui::VKEY_LWIN) base::RecordAction(UserMetricsAction("Accel_Search_LWin")); - Shell::Get()->ToggleAppList(); + Shell::Get()->ToggleAppList(app_list::kSearchKey); } void HandleToggleFullscreen(const ui::Accelerator& accelerator) {
diff --git a/ash/mus/shell_delegate_mus.cc b/ash/mus/shell_delegate_mus.cc index 4b945f524..f5b3253 100644 --- a/ash/mus/shell_delegate_mus.cc +++ b/ash/mus/shell_delegate_mus.cc
@@ -132,14 +132,6 @@ return nullptr; } -PrefService* ShellDelegateMus::GetLocalStatePrefService() const { - // This code should never be called in the case of Config::MASH. Rather, the - // PrefService instance is stored by Shell when it manages to connect to the - // pref service in Chrome. - NOTREACHED(); - return nullptr; -} - bool ShellDelegateMus::IsTouchscreenEnabledInPrefs(bool use_local_state) const { NOTIMPLEMENTED(); return true;
diff --git a/ash/mus/shell_delegate_mus.h b/ash/mus/shell_delegate_mus.h index 97c140c..ecd4156 100644 --- a/ash/mus/shell_delegate_mus.h +++ b/ash/mus/shell_delegate_mus.h
@@ -45,7 +45,6 @@ base::string16 GetProductName() const override; gfx::Image GetDeprecatedAcceleratorImage() const override; PrefService* GetActiveUserPrefService() const override; - PrefService* GetLocalStatePrefService() const override; bool IsTouchscreenEnabledInPrefs(bool use_local_state) const override; void SetTouchscreenEnabledInPrefs(bool enabled, bool use_local_state) override;
diff --git a/ash/shelf/app_list_button.h b/ash/shelf/app_list_button.h index 45a0f56..2bf9232 100644 --- a/ash/shelf/app_list_button.h +++ b/ash/shelf/app_list_button.h
@@ -75,7 +75,7 @@ // Helper function to determine whether and event at |location| should be // handled by the back button or the app list circle. Returns false if we are - // not in maximized mode (there is no back button). + // not in tablet mode (there is no back button). bool IsBackEvent(const gfx::Point& location); // Generate and send a VKEY_BROWSER_BACK key event when the back button
diff --git a/ash/shelf/app_list_shelf_item_delegate.cc b/ash/shelf/app_list_shelf_item_delegate.cc index a8cc9bf..62eb73e 100644 --- a/ash/shelf/app_list_shelf_item_delegate.cc +++ b/ash/shelf/app_list_shelf_item_delegate.cc
@@ -8,6 +8,7 @@ #include "ash/public/cpp/shelf_model.h" #include "ash/shell.h" +#include "ui/app_list/app_list_constants.h" namespace ash { @@ -20,7 +21,7 @@ int64_t display_id, ShelfLaunchSource source, ItemSelectedCallback callback) { - Shell::Get()->ToggleAppList(); + Shell::Get()->ToggleAppList(app_list::kShelfButton); std::move(callback).Run(SHELF_ACTION_APP_LIST_SHOWN, base::nullopt); }
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index 85a0845..869b5b6a 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -29,6 +29,8 @@ #include "base/auto_reset.h" #include "base/command_line.h" #include "base/i18n/rtl.h" +#include "base/metrics/histogram_macros.h" +#include "ui/app_list/app_list_constants.h" #include "ui/app_list/app_list_features.h" #include "ui/app_list/views/app_list_view.h" #include "ui/base/ui_base_switches.h" @@ -1112,7 +1114,7 @@ if (CanStartFullscreenAppListDrag( gesture_in_screen.details().scroll_y_hint())) { gesture_drag_status_ = GESTURE_DRAG_APPLIST_IN_PROGRESS; - Shell::Get()->ShowAppList(); + Shell::Get()->ShowAppList(app_list::kSwipeFromShelf); Shell::Get()->UpdateAppListYPositionAndOpacity( gesture_in_screen.location().y(), GetAppListBackgroundOpacityOnShelfOpacity(), @@ -1234,6 +1236,10 @@ .work_area() .y(), GetAppListBackgroundOpacityOnShelfOpacity(), true /* is_end_gesture */); + UMA_HISTOGRAM_ENUMERATION(app_list::kAppListToggleMethodHistogram, + app_list::kSwipeFromShelf, + app_list::kMaxAppListToggleMethod); + } else { Shell::Get()->DismissAppList(); }
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h index 3ced02a..c2e2b71e 100644 --- a/ash/shelf/shelf_layout_manager.h +++ b/ash/shelf/shelf_layout_manager.h
@@ -31,7 +31,7 @@ namespace ui { class ImplicitAnimationObserver; class MouseEvent; -} +} // namespace ui namespace ash { @@ -326,7 +326,7 @@ // Do any windows overlap the shelf? This is maintained by WorkspaceManager. bool window_overlaps_shelf_; - // Is the AppList visible? This is maintained by + // Whether the app list is visible. This is maintained by // OnAppListVisibilityChanged. bool is_app_list_visible_ = false;
diff --git a/ash/shell.cc b/ash/shell.cc index 2482f44..9b151c25 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -128,6 +128,7 @@ #include "base/bind_helpers.h" #include "base/command_line.h" #include "base/memory/ptr_util.h" +#include "base/metrics/histogram_macros.h" #include "base/sys_info.h" #include "base/threading/sequenced_worker_pool.h" #include "base/trace_event/trace_event.h" @@ -425,16 +426,16 @@ PrefService* Shell::GetActiveUserPrefService() const { if (shell_port_->GetAshConfig() == Config::MASH) - return profile_pref_service_.get(); + return profile_pref_service_mash_.get(); return shell_delegate_->GetActiveUserPrefService(); } PrefService* Shell::GetLocalStatePrefService() const { if (shell_port_->GetAshConfig() == Config::MASH) - return local_state_.get(); + return local_state_mash_.get(); - return shell_delegate_->GetLocalStatePrefService(); + return local_state_non_mash_; } WebNotificationTray* Shell::GetWebNotificationTray() { @@ -496,7 +497,11 @@ shell_observers_.RemoveObserver(observer); } -void Shell::ShowAppList() { +void Shell::ShowAppList(app_list::AppListShowSource toggle_method) { + if (IsAppListVisible()) { + UMA_HISTOGRAM_ENUMERATION(app_list::kAppListToggleMethodHistogram, + toggle_method, app_list::kMaxAppListToggleMethod); + } // Show the app list on the default display for new windows. app_list_->Show(display::Screen::GetScreen() ->GetDisplayNearestWindow(GetRootWindowForNewWindows()) @@ -514,7 +519,11 @@ app_list_->Dismiss(); } -void Shell::ToggleAppList() { +void Shell::ToggleAppList(app_list::AppListShowSource toggle_method) { + if (IsAppListVisible()) { + UMA_HISTOGRAM_ENUMERATION(app_list::kAppListToggleMethodHistogram, + toggle_method, app_list::kMaxAppListToggleMethod); + } // Toggle the app list on the default display for new windows. app_list_->ToggleAppList( display::Screen::GetScreen() @@ -592,6 +601,15 @@ g_is_browser_process_with_mash = true; } +void Shell::SetLocalStatePrefService(PrefService* local_state) { + DCHECK(GetAshConfig() != Config::MASH); + DCHECK(local_state); + local_state_non_mash_ = local_state; + + for (auto& observer : shell_observers_) + observer.OnLocalStatePrefServiceInitialized(local_state_non_mash_); +} + void Shell::NotifyAppListVisibilityChanged(bool visible, aura::Window* root_window) { for (auto& observer : shell_observers_) @@ -840,7 +858,9 @@ // NightLightController depeneds on the PrefService and must be destructed // before it. crbug.com/724231. night_light_controller_ = nullptr; - profile_pref_service_ = nullptr; + profile_pref_service_mash_.reset(); + local_state_mash_.reset(); + local_state_non_mash_ = nullptr; shell_delegate_.reset(); for (auto& observer : shell_observers_) @@ -1335,22 +1355,28 @@ void Shell::OnProfilePrefServiceInitialized( std::unique_ptr<PrefService> pref_service) { + DCHECK(GetAshConfig() == Config::MASH); // Keep the old PrefService object alive so OnActiveUserPrefServiceChanged() // clients can unregister pref observers on the old service. - std::unique_ptr<PrefService> old_service = std::move(profile_pref_service_); - profile_pref_service_ = std::move(pref_service); + std::unique_ptr<PrefService> old_service = + std::move(profile_pref_service_mash_); + profile_pref_service_mash_ = std::move(pref_service); // |pref_service| can be null if can't connect to Chrome (as happens when // running mash outside of chrome --mash and chrome isn't built). for (auto& observer : shell_observers_) - observer.OnActiveUserPrefServiceChanged(profile_pref_service_.get()); + observer.OnActiveUserPrefServiceChanged(profile_pref_service_mash_.get()); // |old_service| is deleted. } void Shell::OnLocalStatePrefServiceInitialized( std::unique_ptr<::PrefService> pref_service) { + DCHECK(GetAshConfig() == Config::MASH); // |pref_service| is null if can't connect to Chrome (as happens when // running mash outside of chrome --mash and chrome isn't built). - local_state_ = std::move(pref_service); + local_state_mash_ = std::move(pref_service); + + for (auto& observer : shell_observers_) + observer.OnLocalStatePrefServiceInitialized(local_state_mash_.get()); } } // namespace ash
diff --git a/ash/shell.h b/ash/shell.h index 08b86645..1a34aebd 100644 --- a/ash/shell.h +++ b/ash/shell.h
@@ -18,6 +18,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" +#include "ui/app_list/app_list_constants.h" #include "ui/aura/window.h" #include "ui/display/screen.h" #include "ui/events/event_target.h" @@ -37,7 +38,7 @@ class Window; class WindowManagerClient; class WindowTreeClient; -} +} // namespace aura namespace chromeos { class AudioA11yController; @@ -45,13 +46,13 @@ namespace app_list { class AppList; -} +} // namespace app_list namespace display { class DisplayChangeObserver; class DisplayConfigurator; class DisplayManager; -} +} // namespace display namespace gfx { class Insets; @@ -60,7 +61,7 @@ namespace ui { class UserActivityDetector; class UserActivityPowerManagerNotifier; -} +} // namespace ui namespace views { class NonClientFrameView; @@ -68,7 +69,7 @@ namespace corewm { class TooltipController; } -} +} // namespace views namespace wm { class AcceleratorFilter; @@ -78,7 +79,7 @@ class ShadowController; class VisibilityController; class WindowModalityController; -} +} // namespace wm namespace ash { @@ -544,7 +545,7 @@ void RemoveShellObserver(ShellObserver* observer); // Shows the app list on the active root window. - void ShowAppList(); + void ShowAppList(app_list::AppListShowSource toggle_method); // Updates y position and opacity of app list. |is_end_gesture| means it is // the end of the gesture dragging of app list from shelf and should restore @@ -557,7 +558,7 @@ void DismissAppList(); // Shows the app list if it's not visible. Dismisses it otherwise. - void ToggleAppList(); + void ToggleAppList(app_list::AppListShowSource toggle_method); // Returns app list actual visibility. This might differ from // GetAppListTargetVisibility() when hiding animation is still in flight. @@ -611,6 +612,9 @@ // Used to provide better error messages for Shell::Get() under mash. static void SetIsBrowserProcessWithMash(); + // Used when Chrome owns the pref service (not mash). + void SetLocalStatePrefService(PrefService* local_state); + void NotifyAppListVisibilityChanged(bool visible, aura::Window* root_window); void NotifyVoiceInteractionStatusChanged(bool running); @@ -736,8 +740,13 @@ // Only initialized for mash. Can be null in ash_standalone (when chrome is // not running) or when reconnecting to the mojo pref service after // multiuser profile switch. - std::unique_ptr<::PrefService> profile_pref_service_; - std::unique_ptr<::PrefService> local_state_; + std::unique_ptr<PrefService> profile_pref_service_mash_; + + // Used in non-mash. Owned by chrome. + PrefService* local_state_non_mash_ = nullptr; + + // Used in mash. + std::unique_ptr<PrefService> local_state_mash_; std::unique_ptr<views::corewm::TooltipController> tooltip_controller_; LinkHandlerModelFactory* link_handler_model_factory_;
diff --git a/ash/shell/shell_delegate_impl.cc b/ash/shell/shell_delegate_impl.cc index 0fd30d7ed..4e83767 100644 --- a/ash/shell/shell_delegate_impl.cc +++ b/ash/shell/shell_delegate_impl.cc
@@ -145,10 +145,6 @@ return nullptr; } -PrefService* ShellDelegateImpl::GetLocalStatePrefService() const { - return nullptr; -} - bool ShellDelegateImpl::IsTouchscreenEnabledInPrefs( bool use_local_state) const { return true;
diff --git a/ash/shell/shell_delegate_impl.h b/ash/shell/shell_delegate_impl.h index 0924384..fa4e693 100644 --- a/ash/shell/shell_delegate_impl.h +++ b/ash/shell/shell_delegate_impl.h
@@ -47,7 +47,6 @@ base::string16 GetProductName() const override; gfx::Image GetDeprecatedAcceleratorImage() const override; PrefService* GetActiveUserPrefService() const override; - PrefService* GetLocalStatePrefService() const override; bool IsTouchscreenEnabledInPrefs(bool use_local_state) const override; void SetTouchscreenEnabledInPrefs(bool enabled, bool use_local_state) override;
diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h index 98932ce..6f013d0 100644 --- a/ash/shell_delegate.h +++ b/ash/shell_delegate.h
@@ -122,10 +122,9 @@ virtual gfx::Image GetDeprecatedAcceleratorImage() const = 0; + // Not used in mash because ash owns the PrefService. virtual PrefService* GetActiveUserPrefService() const = 0; - virtual PrefService* GetLocalStatePrefService() const = 0; - // If |use_local_state| is true, returns the touchscreen status from local // state, otherwise from user prefs. virtual bool IsTouchscreenEnabledInPrefs(bool use_local_state) const = 0;
diff --git a/ash/shell_observer.h b/ash/shell_observer.h index 1eadbff..fbf20b4 100644 --- a/ash/shell_observer.h +++ b/ash/shell_observer.h
@@ -78,6 +78,10 @@ // most of Shell's state has been deleted. virtual void OnShellDestroyed() {} + // Called when local state prefs are available. This occurs an arbitrary + // amount of time after Shell initialization. Only called once. + virtual void OnLocalStatePrefServiceInitialized(PrefService* pref_service) {} + // Called when the user profile pref service is available. Also called after // multiprofile user switch. Never called with the login screen profile. // May be called with null in tests.
diff --git a/ash/shell_test_api.cc b/ash/shell_test_api.cc index 99decb71..8d77a0b 100644 --- a/ash/shell_test_api.cc +++ b/ash/shell_test_api.cc
@@ -9,6 +9,7 @@ #include "ash/palette_delegate.h" #include "ash/root_window_controller.h" #include "ash/shell.h" +#include "components/prefs/testing_pref_service.h" namespace ash { @@ -41,4 +42,9 @@ shell_->palette_delegate_ = std::move(palette_delegate); } +void ShellTestApi::OnLocalStatePrefServiceInitialized( + std::unique_ptr<PrefService> pref_service) { + shell_->OnLocalStatePrefServiceInitialized(std::move(pref_service)); +} + } // namespace ash
diff --git a/ash/shell_test_api.h b/ash/shell_test_api.h index 9c4c8e6..30e5d3e 100644 --- a/ash/shell_test_api.h +++ b/ash/shell_test_api.h
@@ -9,6 +9,8 @@ #include "base/macros.h" +class PrefService; + namespace ash { class NativeCursorManagerAsh; class DragDropController; @@ -34,6 +36,10 @@ void SetPaletteDelegate(std::unique_ptr<PaletteDelegate> palette_delegate); + // Calls the private method. + void OnLocalStatePrefServiceInitialized( + std::unique_ptr<PrefService> pref_service); + private: Shell* shell_; // not owned
diff --git a/ash/shell_unittest.cc b/ash/shell_unittest.cc index bd4b2a2..21b6f487 100644 --- a/ash/shell_unittest.cc +++ b/ash/shell_unittest.cc
@@ -139,11 +139,15 @@ ~TestShellObserver() override = default; // ShellObserver: + void OnLocalStatePrefServiceInitialized(PrefService* pref_service) override { + last_local_state_ = pref_service; + } void OnActiveUserPrefServiceChanged(PrefService* pref_service) override { - last_pref_service_ = pref_service; + last_user_pref_service_ = pref_service; } - PrefService* last_pref_service_ = nullptr; + PrefService* last_local_state_ = nullptr; + PrefService* last_user_pref_service_ = nullptr; private: DISALLOW_COPY_AND_ASSIGN(TestShellObserver); @@ -583,13 +587,64 @@ ash_test_helper()->test_shell_delegate()->set_active_user_pref_service( &pref_service1_); session->SwitchActiveUser(AccountId::FromUserEmail("user1@test.com")); - EXPECT_EQ(&pref_service1_, observer.last_pref_service_); + EXPECT_EQ(&pref_service1_, observer.last_user_pref_service_); // Switching users notifies observers of the new user pref service. ash_test_helper()->test_shell_delegate()->set_active_user_pref_service( &pref_service2_); session->SwitchActiveUser(AccountId::FromUserEmail("user2@test.com")); - EXPECT_EQ(&pref_service2_, observer.last_pref_service_); + EXPECT_EQ(&pref_service2_, observer.last_user_pref_service_); + + Shell::Get()->RemoveShellObserver(&observer); +} + +// Tests the local state code path used with Config::CLASSIC and Config::MUS. +class ShellLocalStateTestNonMash : public NoSessionAshTestBase { + public: + ShellLocalStateTestNonMash() = default; + ~ShellLocalStateTestNonMash() override = default; + + // Must outlive Shell. + TestingPrefServiceSimple local_state_; + + private: + DISALLOW_COPY_AND_ASSIGN(ShellLocalStateTestNonMash); +}; + +TEST_F(ShellLocalStateTestNonMash, LocalState) { + if (Shell::GetAshConfig() == Config::MASH) + return; + + TestShellObserver observer; + Shell::Get()->AddShellObserver(&observer); + + // In classic ash, chrome calls into ash to set up local state. + Shell::RegisterLocalStatePrefs(local_state_.registry()); + Shell::Get()->SetLocalStatePrefService(&local_state_); + EXPECT_EQ(&local_state_, observer.last_local_state_); + EXPECT_EQ(&local_state_, Shell::Get()->GetLocalStatePrefService()); + + Shell::Get()->RemoveShellObserver(&observer); +} + +// Tests the local state code path used with Config::MASH. +using ShellLocalStateTestMash = ShellTest; + +TEST_F(ShellLocalStateTestMash, LocalState) { + if (Shell::GetAshConfig() != Config::MASH) + return; + + TestShellObserver observer; + Shell::Get()->AddShellObserver(&observer); + + // In mash, prefs service wrapper code creates a PrefService. + std::unique_ptr<TestingPrefServiceSimple> local_state = + base::MakeUnique<TestingPrefServiceSimple>(); + Shell::RegisterLocalStatePrefs(local_state->registry()); + TestingPrefServiceSimple* local_state_ptr = local_state.get(); + ShellTestApi().OnLocalStatePrefServiceInitialized(std::move(local_state)); + EXPECT_EQ(local_state_ptr, observer.last_local_state_); + EXPECT_EQ(local_state_ptr, Shell::Get()->GetLocalStatePrefService()); Shell::Get()->RemoveShellObserver(&observer); }
diff --git a/ash/system/palette/palette_tray.cc b/ash/system/palette/palette_tray.cc index 113fdff..39ed70a 100644 --- a/ash/system/palette/palette_tray.cc +++ b/ash/system/palette/palette_tray.cc
@@ -236,6 +236,31 @@ } } +void PaletteTray::OnLocalStatePrefServiceInitialized( + PrefService* pref_service) { + local_state_pref_service_ = pref_service; + + // May be null in mash_unittests where there is no mojo pref service. + if (!local_state_pref_service_) + return; + + // If a device has an internal stylus or the flag to force stylus is set, mark + // the has seen stylus flag as true since we know the user has a stylus. + if (palette_utils::HasInternalStylus() || + palette_utils::HasForcedStylusInput()) { + local_state_pref_service_->SetBoolean(prefs::kHasSeenStylus, true); + } + + pref_change_registrar_ = base::MakeUnique<PrefChangeRegistrar>(); + pref_change_registrar_->Init(local_state_pref_service_); + pref_change_registrar_->Add( + prefs::kHasSeenStylus, + base::Bind(&PaletteTray::OnHasSeenStylusPrefChanged, + base::Unretained(this))); + + OnHasSeenStylusPrefChanged(); +} + void PaletteTray::ClickedOutsideBubble() { if (num_actions_in_bubble_ == 0) RecordPaletteOptionsUsage(PaletteTrayOptions::PALETTE_CLOSED_NO_ACTION); @@ -386,29 +411,6 @@ // which will take care of showing the palette. palette_enabled_subscription_ = delegate->AddPaletteEnableListener(base::Bind( &PaletteTray::OnPaletteEnabledPrefChanged, weak_factory_.GetWeakPtr())); - - local_state_pref_service_ = Shell::Get()->GetLocalStatePrefService(); - - // |local_state_pref_service_| may be null in tests. - // TODO(crbug.com/751191): Remove the check for Mash. - if (Shell::GetAshConfig() == Config::MASH || !local_state_pref_service_) - return; - - // If a device has an internal stylus or the flag to force stylus is set, mark - // the has seen stylus flag as true since we know the user has a stylus. - if (palette_utils::HasInternalStylus() || - palette_utils::HasForcedStylusInput()) { - local_state_pref_service_->SetBoolean(prefs::kHasSeenStylus, true); - } - - pref_change_registrar_ = base::MakeUnique<PrefChangeRegistrar>(); - pref_change_registrar_->Init(local_state_pref_service_); - pref_change_registrar_->Add( - prefs::kHasSeenStylus, - base::Bind(&PaletteTray::OnHasSeenStylusPrefChanged, - base::Unretained(this))); - - OnHasSeenStylusPrefChanged(); } bool PaletteTray::PerformAction(const ui::Event& event) {
diff --git a/ash/system/palette/palette_tray.h b/ash/system/palette/palette_tray.h index 5221dbc..affbfc1 100644 --- a/ash/system/palette/palette_tray.h +++ b/ash/system/palette/palette_tray.h
@@ -76,6 +76,7 @@ // ShellObserver: void OnLockStateChanged(bool locked) override; + void OnLocalStatePrefServiceInitialized(PrefService* pref_service) override; // TrayBackgroundView: void ClickedOutsideBubble() override;
diff --git a/ash/system/palette/palette_tray_unittest.cc b/ash/system/palette/palette_tray_unittest.cc index 5cf52292..5e53490b 100644 --- a/ash/system/palette/palette_tray_unittest.cc +++ b/ash/system/palette/palette_tray_unittest.cc
@@ -43,8 +43,6 @@ palette_utils::SetHasStylusInputForTesting(); Shell::RegisterLocalStatePrefs(pref_service_.registry()); - ash_test_helper()->test_shell_delegate()->set_local_state_pref_service( - &pref_service_); palette_tray_ = StatusAreaWidgetTestHelper::GetStatusAreaWidget()->palette_tray(); @@ -57,15 +55,7 @@ // from the palette delegate. (It was initialized without the delegate in // AshTestBase::SetUp()). palette_tray_->Initialize(); - } - - // Adds the command line flag which states this device has an internal stylus. - void InitForInternalStylus() { - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kHasInternalStylus); - // Initialize the palette tray again so the changes from adding this switch - // are applied. - palette_tray_->Initialize(); + palette_tray_->OnLocalStatePrefServiceInitialized(&pref_service_); } // Performs a tap on the palette tray button. @@ -94,10 +84,6 @@ // Verify that if the has seen stylus pref is not set initially, the palette // tray's touch event watcher should be active. TEST_F(PaletteTrayTest, PaletteTrayStylusWatcherAlive) { - // TODO(crbug.com/752997): Remove the check for Mash. - if (Shell::GetAshConfig() == Config::MASH) - return; - ASSERT_FALSE(palette_tray_->visible()); EXPECT_TRUE(test_api_->IsStylusWatcherActive()); @@ -106,10 +92,6 @@ // Verify if the has seen stylus pref is not set initially, the palette tray // should become visible after seeing a stylus event. TEST_F(PaletteTrayTest, PaletteTrayVisibleAfterStylusSeen) { - // TODO(crbug.com/752997): Remove the check for Mash. - if (Shell::GetAshConfig() == Config::MASH) - return; - ASSERT_FALSE(palette_tray_->visible()); ASSERT_FALSE(pref_service_.GetBoolean(prefs::kHasSeenStylus)); ASSERT_TRUE(test_api_->IsStylusWatcherActive()); @@ -129,10 +111,6 @@ // Verify if the has seen stylus pref is initially set, the palette tray is // visible. TEST_F(PaletteTrayTest, StylusSeenPrefInitiallySet) { - // TODO(crbug.com/752997): Remove the check for Mash. - if (Shell::GetAshConfig() == Config::MASH) - return; - ASSERT_FALSE(palette_tray_->visible()); pref_service_.SetBoolean(prefs::kHasSeenStylus, true); @@ -140,45 +118,6 @@ EXPECT_FALSE(test_api_->IsStylusWatcherActive()); } -// Verify the palette tray button exists and is visible if the device has an -// internal stylus. -TEST_F(PaletteTrayTest, PaletteTrayIsVisibleForInternalStylus) { - // TODO(crbug.com/752997): Remove the check for Mash. - if (Shell::GetAshConfig() == Config::MASH) - return; - - InitForInternalStylus(); - ASSERT_TRUE(palette_tray_); - EXPECT_TRUE(palette_tray_->visible()); -} - -// Verify that when entering or exiting the lock screen, the behavior of the -// palette tray button is as expected. -TEST_F(PaletteTrayTest, PaletteTrayOnLockScreenBehavior) { - // TODO(crbug.com/752997): Remove the check for Mash. - if (Shell::GetAshConfig() == Config::MASH) - return; - - InitForInternalStylus(); - ASSERT_TRUE(palette_tray_->visible()); - - PaletteToolManager* manager = test_api_->GetPaletteToolManager(); - manager->ActivateTool(PaletteToolId::LASER_POINTER); - EXPECT_TRUE(manager->IsToolActive(PaletteToolId::LASER_POINTER)); - - // Verify that when entering the lock screen, the palette tray button is - // hidden, and the tool that was active is no longer active. - GetSessionControllerClient()->RequestLockScreen(); - EXPECT_FALSE(manager->IsToolActive(PaletteToolId::LASER_POINTER)); - EXPECT_FALSE(palette_tray_->visible()); - - // Verify that when logging back in the tray is visible, but the tool that was - // active before locking the screen is still inactive. - GetSessionControllerClient()->UnlockScreen(); - EXPECT_TRUE(palette_tray_->visible()); - EXPECT_FALSE(manager->IsToolActive(PaletteToolId::LASER_POINTER)); -} - // Verify taps on the palette tray button results in expected behaviour. TEST_F(PaletteTrayTest, PaletteTrayWorkflow) { // Verify the palette tray button is not active, and the palette tray bubble @@ -245,4 +184,46 @@ EXPECT_FALSE(palette_tray_->is_active()); } +// Base class for tests that need to simulate an internal stylus. +class PaletteTrayTestWithInternalStylus : public PaletteTrayTest { + public: + PaletteTrayTestWithInternalStylus() { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kHasInternalStylus); + } + ~PaletteTrayTestWithInternalStylus() override = default; + + private: + DISALLOW_COPY_AND_ASSIGN(PaletteTrayTestWithInternalStylus); +}; + +// Verify the palette tray button exists and is visible if the device has an +// internal stylus. +TEST_F(PaletteTrayTestWithInternalStylus, Visible) { + ASSERT_TRUE(palette_tray_); + EXPECT_TRUE(palette_tray_->visible()); +} + +// Verify that when entering or exiting the lock screen, the behavior of the +// palette tray button is as expected. +TEST_F(PaletteTrayTestWithInternalStylus, PaletteTrayOnLockScreenBehavior) { + ASSERT_TRUE(palette_tray_->visible()); + + PaletteToolManager* manager = test_api_->GetPaletteToolManager(); + manager->ActivateTool(PaletteToolId::LASER_POINTER); + EXPECT_TRUE(manager->IsToolActive(PaletteToolId::LASER_POINTER)); + + // Verify that when entering the lock screen, the palette tray button is + // hidden, and the tool that was active is no longer active. + GetSessionControllerClient()->RequestLockScreen(); + EXPECT_FALSE(manager->IsToolActive(PaletteToolId::LASER_POINTER)); + EXPECT_FALSE(palette_tray_->visible()); + + // Verify that when logging back in the tray is visible, but the tool that was + // active before locking the screen is still inactive. + GetSessionControllerClient()->UnlockScreen(); + EXPECT_TRUE(palette_tray_->visible()); + EXPECT_FALSE(manager->IsToolActive(PaletteToolId::LASER_POINTER)); +} + } // namespace ash
diff --git a/ash/test_shell_delegate.cc b/ash/test_shell_delegate.cc index 7ab82b20..b6920eb 100644 --- a/ash/test_shell_delegate.cc +++ b/ash/test_shell_delegate.cc
@@ -139,10 +139,6 @@ return active_user_pref_service_; } -PrefService* TestShellDelegate::GetLocalStatePrefService() const { - return local_state_pref_service_; -} - bool TestShellDelegate::IsTouchscreenEnabledInPrefs( bool use_local_state) const { return use_local_state ? touchscreen_enabled_in_local_pref_ : true;
diff --git a/ash/test_shell_delegate.h b/ash/test_shell_delegate.h index bcf7cd8..ebbe439 100644 --- a/ash/test_shell_delegate.h +++ b/ash/test_shell_delegate.h
@@ -34,10 +34,6 @@ active_user_pref_service_ = pref_service; } - void set_local_state_pref_service(PrefService* pref_service) { - local_state_pref_service_ = pref_service; - } - // Overridden from ShellDelegate: ::service_manager::Connector* GetShellConnector() const override; bool IsIncognitoAllowed() const override; @@ -62,7 +58,6 @@ base::string16 GetProductName() const override; gfx::Image GetDeprecatedAcceleratorImage() const override; PrefService* GetActiveUserPrefService() const override; - PrefService* GetLocalStatePrefService() const override; bool IsTouchscreenEnabledInPrefs(bool use_local_state) const override; void SetTouchscreenEnabledInPrefs(bool enabled, bool use_local_state) override; @@ -86,7 +81,6 @@ bool media_sessions_suspended_ = false; std::unique_ptr<ShelfInitializer> shelf_initializer_; PrefService* active_user_pref_service_ = nullptr; // Not owned. - PrefService* local_state_pref_service_ = nullptr; // Not owned. DISALLOW_COPY_AND_ASSIGN(TestShellDelegate); };
diff --git a/ash/wallpaper/wallpaper_controller.cc b/ash/wallpaper/wallpaper_controller.cc index 165416e..b79db51e 100644 --- a/ash/wallpaper/wallpaper_controller.cc +++ b/ash/wallpaper/wallpaper_controller.cc
@@ -302,12 +302,6 @@ session_manager::SessionState state) { CalculateWallpaperColors(); - // The wallpaper may be dimmed/blurred based on session state. The color of - // the dimming overlay depends on the prominent color cached from a previous - // calculation, or a default color if cache is not available. It should never - // depend on any in-flight color calculation. - InstallDesktopControllerForAllWindows(); - if (state == session_manager::SessionState::ACTIVE) MoveToUnlockedContainer(); else
diff --git a/ash/wallpaper/wallpaper_view.cc b/ash/wallpaper/wallpaper_view.cc index ec74bc7..17f34a1 100644 --- a/ash/wallpaper/wallpaper_view.cc +++ b/ash/wallpaper/wallpaper_view.cc
@@ -4,7 +4,6 @@ #include "ash/wallpaper/wallpaper_view.h" -#include "ash/login/ui/login_constants.h" #include "ash/root_window_controller.h" #include "ash/session/session_controller.h" #include "ash/shell.h" @@ -19,8 +18,6 @@ #include "ui/display/manager/managed_display_info.h" #include "ui/display/screen.h" #include "ui/gfx/canvas.h" -#include "ui/gfx/color_analysis.h" -#include "ui/gfx/color_utils.h" #include "ui/gfx/geometry/safe_integer_conversions.h" #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/transform.h" @@ -74,23 +71,6 @@ DISALLOW_COPY_AND_ASSIGN(LayerControlView); }; -// Returns the color used to darken the wallpaper, needed by login, lock, OOBE -// and add user screens. -SkColor GetWallpaperDarkenColor() { - SkColor darken_color = - Shell::Get()->wallpaper_controller()->GetProminentColor( - color_utils::ColorProfile(color_utils::LumaRange::DARK, - color_utils::SaturationRange::MUTED)); - if (darken_color == WallpaperController::kInvalidColor) - darken_color = login_constants::kDefaultBaseColor; - - darken_color = color_utils::GetResultingPaintColor( - SkColorSetA(login_constants::kDefaultBaseColor, - login_constants::kTranslucentColorDarkenAlpha), - SkColorSetA(darken_color, 0xFF)); - return SkColorSetA(darken_color, login_constants::kTranslucentAlpha); -} - } // namespace // This event handler receives events in the pre-target phase and takes care of @@ -159,12 +139,6 @@ if (wallpaper.isNull()) return; - cc::PaintFlags flags; - if (Shell::Get()->session_controller()->IsUserSessionBlocked()) { - flags.setColorFilter(SkColorFilter::MakeModeFilter( - GetWallpaperDarkenColor(), SkBlendMode::kDarken)); - } - if (layout == wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED) { // The dimension with the smallest ratio must be cropped, the other one // is preserved. Both are set in gfx::Size cropped_size. @@ -190,14 +164,13 @@ canvas->DrawImageInt( wallpaper, wallpaper_cropped_rect.x(), wallpaper_cropped_rect.y(), wallpaper_cropped_rect.width(), wallpaper_cropped_rect.height(), 0, 0, - width(), height(), true, flags); + width(), height(), true); } else if (layout == wallpaper::WALLPAPER_LAYOUT_TILE) { - canvas->TileImageInt(wallpaper, 0, 0, 0, 0, width(), height(), 1.0f, - &flags); + canvas->TileImageInt(wallpaper, 0, 0, width(), height()); } else if (layout == wallpaper::WALLPAPER_LAYOUT_STRETCH) { // This is generally not recommended as it may show artifacts. canvas->DrawImageInt(wallpaper, 0, 0, wallpaper.width(), wallpaper.height(), - 0, 0, width(), height(), true, flags); + 0, 0, width(), height(), true); } else { float image_scale = canvas->image_scale(); gfx::Rect wallpaper_rect(0, 0, wallpaper.width() / image_scale, @@ -206,8 +179,7 @@ canvas->DrawImageInt(wallpaper, 0, 0, wallpaper.width(), wallpaper.height(), (width() - wallpaper_rect.width()) / 2, (height() - wallpaper_rect.height()) / 2, - wallpaper_rect.width(), wallpaper_rect.height(), true, - flags); + wallpaper_rect.width(), wallpaper_rect.height(), true); } } @@ -263,9 +235,6 @@ aura::Window* container = root_window->GetChildById(container_id); wallpaper_widget->SetBounds(container->bounds()); - if (Shell::Get()->session_controller()->IsUserSessionBlocked()) - wallpaper_widget->GetLayer()->SetLayerBlur(login_constants::kBlurSigma); - return wallpaper_widget; }
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc index 6cbc5fd..40c944aa 100644 --- a/ash/wm/overview/window_selector_unittest.cc +++ b/ash/wm/overview/window_selector_unittest.cc
@@ -33,6 +33,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/test/user_action_tester.h" +#include "ui/app_list/app_list_constants.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/focus_client.h" #include "ui/aura/test/test_windows.h" @@ -496,7 +497,9 @@ EXPECT_TRUE(wm::IsActiveWindow(window1.get())); EXPECT_EQ(window1.get(), wm::GetFocusedWindow()); - Shell::Get()->ToggleAppList(); + // Pass an enum to satisfy the function, it is arbitrary and will not effect + // histograms. + Shell::Get()->ToggleAppList(app_list::kShelfButton); // Activating overview cancels the App-list which normally would activate the // previously active |window1|. Overview mode should properly transfer focus
diff --git a/base/process/process_handle.h b/base/process/process_handle.h index bc0e08e1..4ce05e2b 100644 --- a/base/process/process_handle.h +++ b/base/process/process_handle.h
@@ -44,6 +44,15 @@ const ProcessId kNullProcessId = 0; #endif // defined(OS_WIN) +// To print ProcessIds portably use CrPRIdPid (based on PRIuS and friends from +// C99 and format_macros.h) like this: +// base::StringPrintf("PID is %" CrPRIdPid ".\n", pid); +#if defined(OS_WIN) +#define CrPRIdPid "ld" +#else +#define CrPRIdPid "d" +#endif + // Returns the id of the current process. // Note that on some platforms, this is not guaranteed to be unique across // processes (use GetUniqueIdForProcess if uniqueness is required).
diff --git a/build/args/headless.gn b/build/args/headless.gn index 9452c15..2f8a2633 100644 --- a/build/args/headless.gn +++ b/build/args/headless.gn
@@ -15,6 +15,9 @@ # Embed resource.pak into binary to simplify deployment. headless_use_embedded_resources = true +# Expose headless bindings for freetype library bundled with Chromium. +headless_fontconfig_utils = true + # Remove a dependency on a system fontconfig library. use_bundled_fontconfig = true
diff --git a/build/config/ui.gni b/build/config/ui.gni index 6ce77e6..ce384b5 100644 --- a/build/config/ui.gni +++ b/build/config/ui.gni
@@ -31,7 +31,7 @@ # Indicates if Aura is enabled. Aura is a low-level windowing library, sort # of a replacement for GDI or GTK. - use_aura = is_win || is_linux || is_fuchsia + use_aura = is_win || is_linux # Whether we should use glib, a low level C utility library. use_glib = is_linux @@ -39,8 +39,8 @@ declare_args() { # True means the UI is built using the "views" framework. - toolkit_views = (is_mac || is_win || is_chromeos || use_aura) && - !is_chromecast && !is_fuchsia + toolkit_views = + (is_mac || is_win || is_chromeos || use_aura) && !is_chromecast } # Additional dependent variables -----------------------------------------------
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 24cd3fb..ef4042c 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -853,6 +853,7 @@ "//media", "//mojo/edk/system", "//mojo/public/cpp/bindings", + "//services/viz/public/interfaces/compositing", "//skia", "//testing/gmock", "//testing/gtest",
diff --git a/cc/ipc/BUILD.gn b/cc/ipc/BUILD.gn index 4df7c2e..f3714f9 100644 --- a/cc/ipc/BUILD.gn +++ b/cc/ipc/BUILD.gn
@@ -40,7 +40,6 @@ mojom("interfaces") { sources = [ "begin_frame_args.mojom", - "compositor_frame.mojom", "compositor_frame_metadata.mojom", "copy_output_request.mojom", "copy_output_result.mojom",
diff --git a/cc/ipc/DEPS b/cc/ipc/DEPS index 44e573a..a21ff764 100644 --- a/cc/ipc/DEPS +++ b/cc/ipc/DEPS
@@ -6,4 +6,5 @@ "+ui/gfx/geometry/mojo", "+ui/latency/ipc", "+ui/latency/mojo", + "+services/viz/public", ]
diff --git a/cc/ipc/cc_serialization_perftest.cc b/cc/ipc/cc_serialization_perftest.cc index 4bd3d0d..20360903 100644 --- a/cc/ipc/cc_serialization_perftest.cc +++ b/cc/ipc/cc_serialization_perftest.cc
@@ -8,9 +8,7 @@ #include "base/test/test_suite.h" #include "cc/ipc/begin_frame_args_struct_traits.h" #include "cc/ipc/cc_param_traits.h" -#include "cc/ipc/compositor_frame.mojom.h" #include "cc/ipc/compositor_frame_metadata_struct_traits.h" -#include "cc/ipc/compositor_frame_struct_traits.h" #include "cc/ipc/render_pass_struct_traits.h" #include "cc/ipc/selection_struct_traits.h" #include "cc/ipc/shared_quad_state_struct_traits.h" @@ -23,6 +21,8 @@ #include "gpu/ipc/common/sync_token_struct_traits.h" #include "ipc/ipc_message.h" #include "mojo/public/cpp/bindings/message.h" +#include "services/viz/public/cpp/compositing/compositor_frame_struct_traits.h" +#include "services/viz/public/interfaces/compositing/compositor_frame.mojom.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/perf/perf_test.h" #include "third_party/skia/include/effects/SkBlurImageFilter.h" @@ -141,10 +141,11 @@ const std::string& test_name, const CompositorFrame& frame, UseSingleSharedQuadState single_sqs) { - mojo::Message message = mojom::CompositorFrame::SerializeAsMessage(&frame); + mojo::Message message = + viz::mojom::CompositorFrame::SerializeAsMessage(&frame); for (int i = 0; i < kNumWarmupRuns; ++i) { CompositorFrame compositor_frame; - mojom::CompositorFrame::Deserialize( + viz::mojom::CompositorFrame::Deserialize( message.payload(), message.payload_num_bytes(), &compositor_frame); } @@ -157,7 +158,7 @@ while (start < end) { for (int i = 0; i < kTimeCheckInterval; ++i) { CompositorFrame compositor_frame; - mojom::CompositorFrame::Deserialize( + viz::mojom::CompositorFrame::Deserialize( message.payload(), message.payload_num_bytes(), &compositor_frame); now = base::TimeTicks::Now(); // We don't count iterations after the end time. @@ -191,7 +192,7 @@ UseSingleSharedQuadState single_sqs) { for (int i = 0; i < kNumWarmupRuns; ++i) { mojo::Message message = - mojom::CompositorFrame::SerializeAsMessage(&frame); + viz::mojom::CompositorFrame::SerializeAsMessage(&frame); } base::TimeTicks start = base::TimeTicks::Now(); @@ -203,7 +204,7 @@ while (start < end) { for (int i = 0; i < kTimeCheckInterval; ++i) { mojo::Message message = - mojom::CompositorFrame::SerializeAsMessage(&frame); + viz::mojom::CompositorFrame::SerializeAsMessage(&frame); now = base::TimeTicks::Now(); // We don't count iterations after the end time. if (now < end)
diff --git a/cc/ipc/compositor_frame.typemap b/cc/ipc/compositor_frame.typemap deleted file mode 100644 index 8908d15..0000000 --- a/cc/ipc/compositor_frame.typemap +++ /dev/null
@@ -1,14 +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/compositor_frame.mojom" -public_headers = [ "//cc/output/compositor_frame.h" ] -traits_headers = [ "//cc/ipc/compositor_frame_struct_traits.h" ] -sources = [ - "compositor_frame_struct_traits.cc", -] -deps = [ - "//cc", -] -type_mappings = [ "cc.mojom.CompositorFrame=cc::CompositorFrame[move_only]" ]
diff --git a/cc/ipc/compositor_frame_struct_traits.h b/cc/ipc/compositor_frame_struct_traits.h deleted file mode 100644 index a90dd6f..0000000 --- a/cc/ipc/compositor_frame_struct_traits.h +++ /dev/null
@@ -1,35 +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. - -#ifndef CC_IPC_COMPOSITOR_FRAME_STRUCT_TRAITS_H_ -#define CC_IPC_COMPOSITOR_FRAME_STRUCT_TRAITS_H_ - -#include "cc/ipc/compositor_frame.mojom-shared.h" -#include "cc/output/compositor_frame.h" - -namespace mojo { - -template <> -struct StructTraits<cc::mojom::CompositorFrameDataView, cc::CompositorFrame> { - static const cc::CompositorFrameMetadata& metadata( - const cc::CompositorFrame& input) { - return input.metadata; - } - - static const std::vector<viz::TransferableResource>& resources( - const cc::CompositorFrame& input) { - return input.resource_list; - } - - static const cc::RenderPassList& passes(const cc::CompositorFrame& input) { - return input.render_pass_list; - } - - static bool Read(cc::mojom::CompositorFrameDataView data, - cc::CompositorFrame* out); -}; - -} // namespace mojo - -#endif // CC_IPC_COMPOSITOR_FRAME_STRUCT_TRAITS_H_
diff --git a/cc/ipc/struct_traits_unittest.cc b/cc/ipc/struct_traits_unittest.cc index c7eb120..95877e8 100644 --- a/cc/ipc/struct_traits_unittest.cc +++ b/cc/ipc/struct_traits_unittest.cc
@@ -51,11 +51,6 @@ std::move(callback).Run(b); } - void EchoCompositorFrame(CompositorFrame c, - EchoCompositorFrameCallback callback) override { - std::move(callback).Run(std::move(c)); - } - void EchoCompositorFrameMetadata( CompositorFrameMetadata c, EchoCompositorFrameMetadataCallback callback) override { @@ -205,128 +200,6 @@ EXPECT_FALSE(output.has_damage); } -// 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. -TEST_F(StructTraitsTest, CompositorFrame) { - std::unique_ptr<RenderPass> render_pass = RenderPass::Create(); - render_pass->SetNew(1, gfx::Rect(5, 6), gfx::Rect(2, 3), gfx::Transform()); - - // SharedQuadState. - const gfx::Transform sqs_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, 13.f, 14.f, - 15.f, 16.f); - const gfx::Rect sqs_layer_rect(1234, 5678); - const gfx::Rect sqs_visible_layer_rect(12, 34, 56, 78); - const gfx::Rect sqs_clip_rect(123, 456, 789, 101112); - const bool sqs_is_clipped = true; - const float sqs_opacity = 0.9f; - const SkBlendMode sqs_blend_mode = SkBlendMode::kSrcOver; - const int sqs_sorting_context_id = 1337; - SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState(); - sqs->SetAll(sqs_quad_to_target_transform, sqs_layer_rect, - sqs_visible_layer_rect, sqs_clip_rect, sqs_is_clipped, - sqs_opacity, sqs_blend_mode, sqs_sorting_context_id); - - // DebugBorderDrawQuad. - const gfx::Rect rect1(1234, 4321, 1357, 7531); - const SkColor color1 = SK_ColorRED; - const int32_t width1 = 1337; - DebugBorderDrawQuad* debug_quad = - render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>(); - debug_quad->SetNew(sqs, rect1, rect1, color1, width1); - - // SolidColorDrawQuad. - const gfx::Rect rect2(2468, 8642, 4321, 1234); - const uint32_t color2 = 0xffffffff; - const bool force_anti_aliasing_off = true; - SolidColorDrawQuad* solid_quad = - render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); - solid_quad->SetNew(sqs, rect2, rect2, color2, force_anti_aliasing_off); - - // viz::TransferableResource constants. - const uint32_t tr_id = 1337; - const viz::ResourceFormat tr_format = viz::ALPHA_8; - const gfx::BufferFormat tr_buffer_format = gfx::BufferFormat::R_8; - const uint32_t tr_filter = 1234; - const gfx::Size tr_size(1234, 5678); - viz::TransferableResource resource; - resource.id = tr_id; - resource.format = tr_format; - resource.buffer_format = tr_buffer_format; - resource.filter = tr_filter; - resource.size = tr_size; - - // CompositorFrameMetadata constants. - const float device_scale_factor = 2.6f; - const gfx::Vector2dF root_scroll_offset(1234.5f, 6789.1f); - const float page_scale_factor = 1337.5f; - const gfx::SizeF scrollable_viewport_size(1337.7f, 1234.5f); - const uint32_t content_source_id = 3; - const viz::BeginFrameAck begin_frame_ack(5, 10, false); - - CompositorFrame input; - input.metadata.device_scale_factor = device_scale_factor; - input.metadata.root_scroll_offset = root_scroll_offset; - input.metadata.page_scale_factor = page_scale_factor; - input.metadata.scrollable_viewport_size = scrollable_viewport_size; - input.render_pass_list.push_back(std::move(render_pass)); - input.resource_list.push_back(resource); - input.metadata.content_source_id = content_source_id; - input.metadata.begin_frame_ack = begin_frame_ack; - - mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy(); - CompositorFrame output; - proxy->EchoCompositorFrame(std::move(input), &output); - - EXPECT_EQ(device_scale_factor, output.metadata.device_scale_factor); - EXPECT_EQ(root_scroll_offset, output.metadata.root_scroll_offset); - EXPECT_EQ(page_scale_factor, output.metadata.page_scale_factor); - EXPECT_EQ(scrollable_viewport_size, output.metadata.scrollable_viewport_size); - EXPECT_EQ(content_source_id, output.metadata.content_source_id); - EXPECT_EQ(begin_frame_ack, output.metadata.begin_frame_ack); - - ASSERT_EQ(1u, output.resource_list.size()); - viz::TransferableResource out_resource = output.resource_list[0]; - EXPECT_EQ(tr_id, out_resource.id); - EXPECT_EQ(tr_format, out_resource.format); - EXPECT_EQ(tr_buffer_format, out_resource.buffer_format); - EXPECT_EQ(tr_filter, out_resource.filter); - EXPECT_EQ(tr_size, out_resource.size); - - EXPECT_EQ(1u, output.render_pass_list.size()); - const RenderPass* out_render_pass = output.render_pass_list[0].get(); - ASSERT_EQ(2u, out_render_pass->quad_list.size()); - ASSERT_EQ(1u, out_render_pass->shared_quad_state_list.size()); - - const SharedQuadState* out_sqs = - out_render_pass->shared_quad_state_list.ElementAt(0); - EXPECT_EQ(sqs_quad_to_target_transform, out_sqs->quad_to_target_transform); - EXPECT_EQ(sqs_layer_rect, out_sqs->quad_layer_rect); - EXPECT_EQ(sqs_visible_layer_rect, out_sqs->visible_quad_layer_rect); - EXPECT_EQ(sqs_clip_rect, out_sqs->clip_rect); - EXPECT_EQ(sqs_is_clipped, out_sqs->is_clipped); - EXPECT_EQ(sqs_opacity, out_sqs->opacity); - EXPECT_EQ(sqs_blend_mode, out_sqs->blend_mode); - EXPECT_EQ(sqs_sorting_context_id, out_sqs->sorting_context_id); - - const DebugBorderDrawQuad* out_debug_border_draw_quad = - DebugBorderDrawQuad::MaterialCast( - out_render_pass->quad_list.ElementAt(0)); - EXPECT_EQ(rect1, out_debug_border_draw_quad->rect); - EXPECT_EQ(rect1, out_debug_border_draw_quad->visible_rect); - EXPECT_EQ(color1, out_debug_border_draw_quad->color); - EXPECT_EQ(width1, out_debug_border_draw_quad->width); - - const SolidColorDrawQuad* out_solid_color_draw_quad = - SolidColorDrawQuad::MaterialCast(out_render_pass->quad_list.ElementAt(1)); - EXPECT_EQ(rect2, out_solid_color_draw_quad->rect); - EXPECT_EQ(rect2, out_solid_color_draw_quad->visible_rect); - EXPECT_EQ(color2, out_solid_color_draw_quad->color); - EXPECT_EQ(force_anti_aliasing_off, - out_solid_color_draw_quad->force_anti_aliasing_off); -} - TEST_F(StructTraitsTest, CompositorFrameMetadata) { const float device_scale_factor = 2.6f; const gfx::Vector2dF root_scroll_offset(1234.5f, 6789.1f);
diff --git a/cc/ipc/traits_test_service.mojom b/cc/ipc/traits_test_service.mojom index 71d2064..6ae6939 100644 --- a/cc/ipc/traits_test_service.mojom +++ b/cc/ipc/traits_test_service.mojom
@@ -5,7 +5,6 @@ module cc.mojom; import "cc/ipc/begin_frame_args.mojom"; -import "cc/ipc/compositor_frame.mojom"; import "cc/ipc/compositor_frame_metadata.mojom"; import "cc/ipc/copy_output_request.mojom"; import "cc/ipc/copy_output_result.mojom"; @@ -31,9 +30,6 @@ EchoBeginFrameAck(BeginFrameAck b) => (BeginFrameAck pass); [Sync] - EchoCompositorFrame(CompositorFrame c) => (CompositorFrame pass); - - [Sync] EchoCompositorFrameMetadata(CompositorFrameMetadata c) => (CompositorFrameMetadata pass);
diff --git a/cc/ipc/typemaps.gni b/cc/ipc/typemaps.gni index cca6caa..b5d695ce 100644 --- a/cc/ipc/typemaps.gni +++ b/cc/ipc/typemaps.gni
@@ -4,7 +4,6 @@ typemaps = [ "//cc/ipc/begin_frame_args.typemap", - "//cc/ipc/compositor_frame.typemap", "//cc/ipc/compositor_frame_metadata.typemap", "//cc/ipc/copy_output_request.typemap", "//cc/ipc/copy_output_result.typemap",
diff --git a/cc/output/overlay_candidate.cc b/cc/output/overlay_candidate.cc index 903498f5..9a8a214 100644 --- a/cc/output/overlay_candidate.cc +++ b/cc/output/overlay_candidate.cc
@@ -380,8 +380,7 @@ OverlayCandidateList&& other) = default; void OverlayCandidateList::AddPromotionHint(const OverlayCandidate& candidate) { - promotion_hint_info_map_[candidate.resource_id] = - candidate.display_rect.origin(); + promotion_hint_info_map_[candidate.resource_id] = candidate.display_rect; } } // namespace cc
diff --git a/cc/output/overlay_candidate.h b/cc/output/overlay_candidate.h index 22b40c6..2f3f597 100644 --- a/cc/output/overlay_candidate.h +++ b/cc/output/overlay_candidate.h
@@ -126,8 +126,8 @@ OverlayCandidateList& operator=(const OverlayCandidateList&); OverlayCandidateList& operator=(OverlayCandidateList&&); - // [id] == origin of candidate's |display_rect| for all promotable resources. - using PromotionHintInfoMap = std::map<viz::ResourceId, gfx::PointF>; + // [id] == candidate's |display_rect| for all promotable resources. + using PromotionHintInfoMap = std::map<viz::ResourceId, gfx::RectF>; // For android, this provides a set of resources that could be promoted to // overlay, if one backs them with a SurfaceView.
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index a7828f7e..494111ef 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc
@@ -1650,7 +1650,9 @@ bool promotable = iter != promotion_hints.end(); gl->OverlayPromotionHintCHROMIUM(resource->gl_id, promotable, promotable ? iter->second.x() : 0, - promotable ? iter->second.y() : 0); + promotable ? iter->second.y() : 0, + promotable ? iter->second.width() : 0, + promotable ? iter->second.height() : 0); } UnlockForRead(id); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java index d03a0b00c..5ade18fa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java
@@ -20,6 +20,7 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.view.WindowManager.LayoutParams; import android.widget.Button; import android.widget.ImageButton; import android.widget.TextView; @@ -252,6 +253,8 @@ } private void displayPassword() { + getActivity().getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE); + changeHowPasswordIsDisplayed( R.drawable.ic_visibility_off, InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD); }
diff --git a/chrome/app/theme/default_100_percent/common/notification_extension_installed.png b/chrome/app/theme/default_100_percent/common/notification_extension_installed.png deleted file mode 100644 index 94d75021..0000000 --- a/chrome/app/theme/default_100_percent/common/notification_extension_installed.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/notification_usb_icon.png b/chrome/app/theme/default_100_percent/common/notification_usb_icon.png deleted file mode 100644 index 8b1d24c..0000000 --- a/chrome/app/theme/default_100_percent/common/notification_usb_icon.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/info_small.png b/chrome/app/theme/default_100_percent/legacy/info_small.png similarity index 100% rename from chrome/app/theme/default_100_percent/common/info_small.png rename to chrome/app/theme/default_100_percent/legacy/info_small.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/notification_extension_installed.png b/chrome/app/theme/default_200_percent/common/notification_extension_installed.png deleted file mode 100644 index c0609b24..0000000 --- a/chrome/app/theme/default_200_percent/common/notification_extension_installed.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/notification_usb_icon.png b/chrome/app/theme/default_200_percent/common/notification_usb_icon.png deleted file mode 100644 index 4c372b1f..0000000 --- a/chrome/app/theme/default_200_percent/common/notification_usb_icon.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/info_small.png b/chrome/app/theme/default_200_percent/legacy/info_small.png similarity index 100% rename from chrome/app/theme/default_200_percent/common/info_small.png rename to chrome/app/theme/default_200_percent/legacy/info_small.png Binary files differ
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 647640fe..26c4f42 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd
@@ -214,7 +214,9 @@ <structure type="chrome_scaled_image" name="IDR_ICON_USER_MANAGER_TUTORIAL_FRIENDS" file="common/user_manager_tutorial/family_and_friends.png" /> <structure type="chrome_scaled_image" name="IDR_ICON_USER_MANAGER_TUTORIAL_COMPLETE" file="common/user_manager_tutorial/complete.png" /> </if> - <structure type="chrome_scaled_image" name="IDR_INFO" file="common/info_small.png" /> + <if expr="is_macosx"> + <structure type="chrome_scaled_image" name="IDR_INFO" file="legacy/info_small.png" /> + </if> <structure type="chrome_scaled_image" name="IDR_INFOBAR_3D_BLOCKED" file="common/infobar_3d_blocked.png" /> <structure type="chrome_scaled_image" name="IDR_INFOBAR_MEDIA_STREAM_CAMERA" file="common/infobar_media_stream_camera.png" /> <structure type="chrome_scaled_image" name="IDR_INFOBAR_MEDIA_STREAM_MIC" file="common/infobar_media_stream_mic.png" /> @@ -268,7 +270,6 @@ <structure type="chrome_scaled_image" name="IDR_PORTAL_DETECTION_ALERT" file="cros/captive_portal_icon.png" /> <structure type="chrome_scaled_image" name="IDR_ARC_PLAY_STORE_NOTIFICATION" file="cros/notification_play_store.png" /> <structure type="chrome_scaled_image" name="IDR_ARC_PLAY_STORE_OPTIN_IN_PROGRESS_NOTIFICATION" file="cros/notification_play_store_optin_in_progress.png" /> - <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_EXTENSION_INSTALLED" file="common/notification_extension_installed.png" /> <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_SCREENSHOT_ANNOTATE" file="cros/notification_screenshot_annotate.png" /> <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_SCREENSHOT_COPY_TO_CLIPBOARD" file="cros/notification_screenshot_copy_to_clipboard.png" /> <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_EASYUNLOCK_ENABLED" file="cros/notification_easyunlock_enabled.png" /> @@ -515,7 +516,6 @@ <structure type="chrome_scaled_image" name="IDR_TRANSLATE" file="legacy/translate.png" /> </if> <structure type="chrome_scaled_image" name="IDR_TRANSLATE_BUBBLE_ICON" file="common/translate_bubble_icon.png" /> - <structure type="chrome_scaled_image" name="IDR_USB_NOTIFICATION_ICON" file="common/notification_usb_icon.png" /> <if expr="chromeos"> <structure type="chrome_scaled_image" name="IDR_USER_IMAGE_CAPTURE" file="cros/snapshot_wide.png" /> <structure type="chrome_scaled_image" name="IDR_USER_IMAGE_RECYCLE" file="cros/discard_wide.png" />
diff --git a/chrome/browser/android/locale/special_locale_handler.cc b/chrome/browser/android/locale/special_locale_handler.cc index d0fd86f..689db1f 100644 --- a/chrome/browser/android/locale/special_locale_handler.cc +++ b/chrome/browser/android/locale/special_locale_handler.cc
@@ -75,9 +75,9 @@ // Otherwise, matching based on keyword is sufficient and preferred as // some logically distinct search engines share the same prepopulate ID and // only differ on keyword. - const TemplateURL* existing_url = + const TemplateURL* matching_url = template_url_service_->GetTemplateURLForKeyword(data_url->keyword()); - bool exists = existing_url != nullptr; + bool exists = matching_url != nullptr; if (!exists && data_url->prepopulate_id == TemplateURLPrepopulateData::google.id) { auto existing_urls = template_url_service_->GetTemplateURLs(); @@ -85,6 +85,7 @@ for (auto* existing_url : existing_urls) { if (existing_url->prepopulate_id() == TemplateURLPrepopulateData::google.id) { + matching_url = existing_url; exists = true; break; } @@ -95,12 +96,12 @@ // Update the visit time of any existing custom search engines to ensure // they are not filtered out in TemplateUrlServicAndroid::LoadTemplateURLs if (!template_url_service_->IsPrepopulatedOrCreatedByPolicy( - existing_url)) { + matching_url)) { UIThreadSearchTermsData search_terms_data(profile_); TemplateURLService::URLVisitedDetails visited_details; visited_details.url = - existing_url->GenerateSearchURL(search_terms_data); + matching_url->GenerateSearchURL(search_terms_data); visited_details.is_keyword_transition = false; template_url_service_->OnHistoryURLVisited(visited_details); }
diff --git a/chrome/browser/android/locale/special_locale_handler_unittest.cc b/chrome/browser/android/locale/special_locale_handler_unittest.cc index 81019fc2..7234699 100644 --- a/chrome/browser/android/locale/special_locale_handler_unittest.cc +++ b/chrome/browser/android/locale/special_locale_handler_unittest.cc
@@ -14,6 +14,7 @@ #include "components/search_engines/template_url_prepopulate_data.h" #include "components/search_engines/template_url_service.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" class MockSpecialLocaleHandler : public SpecialLocaleHandler { @@ -33,6 +34,8 @@ TemplateURLPrepopulateData::so_360)); result.push_back(TemplateURLDataFromPrepopulatedEngine( TemplateURLPrepopulateData::naver)); + result.push_back(TemplateURLDataFromPrepopulatedEngine( + TemplateURLPrepopulateData::google)); return result; } @@ -123,3 +126,24 @@ ASSERT_EQ(TemplateURLPrepopulateData::google.id, model()->GetDefaultSearchProvider()->prepopulate_id()); } + +TEST_F(SpecialLocaleHandlerTest, ChangedGoogleBaseURL) { + test_util()->VerifyLoad(); + auto google_keyword = base::ASCIIToUTF16("google.com"); + ASSERT_THAT(model()->GetTemplateURLForKeyword(google_keyword), + testing::NotNull()); + test_util()->SetGoogleBaseURL(GURL("http://google.de")); + + // After changing the base URL, the previous google keyword will no longer + // match. + ASSERT_EQ(nullptr, model()->GetTemplateURLForKeyword(google_keyword)); + + ASSERT_TRUE(handler()->LoadTemplateUrls(NULL, JavaParamRef<jobject>(NULL))); + + auto template_urls = model()->GetTemplateURLs(); + ASSERT_EQ(1, std::count_if(template_urls.begin(), template_urls.end(), + [](TemplateURL* template_url) { + return template_url->prepopulate_id() == + TemplateURLPrepopulateData::google.id; + })); +}
diff --git a/chrome/browser/autofill/content_autofill_driver_browsertest.cc b/chrome/browser/autofill/content_autofill_driver_browsertest.cc index 117c6ae3..a65633d 100644 --- a/chrome/browser/autofill/content_autofill_driver_browsertest.cc +++ b/chrome/browser/autofill/content_autofill_driver_browsertest.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" #include "components/autofill/content/browser/content_autofill_driver.h" #include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/autofill/core/browser/autofill_manager.h" @@ -21,7 +22,10 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/common/url_constants.h" +#include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/embedded_test_server.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/rect.h" @@ -29,6 +33,9 @@ namespace autofill { namespace { +const base::FilePath::CharType kDocRoot[] = + FILE_PATH_LITERAL("chrome/test/data"); + class MockAutofillClient : public TestAutofillClient { public: MockAutofillClient() {} @@ -92,6 +99,17 @@ ContentAutofillDriverFactory::CreateForWebContentsAndDelegate( web_contents, &autofill_client_, "en-US", AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER); + + embedded_test_server()->AddDefaultHandlers(base::FilePath(kDocRoot)); + // Serve both a.com and b.com (and any other domain). + host_resolver()->AddRule("*", "127.0.0.1"); + ASSERT_TRUE(embedded_test_server()->Start()); + } + + void TearDownOnMainThread() override { + // Verify the expectations here, because closing the browser may incur + // other calls in |autofill_client_| e.g., HideAutofillPopup. + testing::Mock::VerifyAndClearExpectations(&autofill_client_); } void WasHidden() override { @@ -106,20 +124,30 @@ if (!nav_entry_committed_callback_.is_null()) nav_entry_committed_callback_.Run(); + + if (navigation_handle->IsSameDocument() && + !same_document_navigation_callback_.is_null()) { + same_document_navigation_callback_.Run(); + } + + if (!navigation_handle->IsInMainFrame() && + !subframe_navigation_callback_.is_null()) { + subframe_navigation_callback_.Run(); + } } protected: base::Closure web_contents_hidden_callback_; base::Closure nav_entry_committed_callback_; + base::Closure same_document_navigation_callback_; + base::Closure subframe_navigation_callback_; testing::NiceMock<MockAutofillClient> autofill_client_; }; IN_PROC_BROWSER_TEST_F(ContentAutofillDriverBrowserTest, SwitchTabAndHideAutofillPopup) { - // Notification is different on platforms. On linux this will be called twice, - // while on windows only once. - EXPECT_CALL(autofill_client_, HideAutofillPopup()).Times(testing::AtLeast(1)); + EXPECT_CALL(autofill_client_, HideAutofillPopup()).Times(1); scoped_refptr<content::MessageLoopRunner> runner = new content::MessageLoopRunner; @@ -132,13 +160,57 @@ } IN_PROC_BROWSER_TEST_F(ContentAutofillDriverBrowserTest, - TestPageNavigationHidingAutofillPopup) { - // Notification is different on platforms. On linux this will be called twice, - // while on windows only once. + SameDocumentNavigationHideAutofillPopup) { + ui_test_utils::NavigateToURL( + browser(), + embedded_test_server()->GetURL("/autofill/autofill_test_form.html")); + + // The Autofill popup should be hidden for same document navigations. It may + // called twice because the zoom changed event may also fire for same-page + // navigations. EXPECT_CALL(autofill_client_, HideAutofillPopup()).Times(testing::AtLeast(1)); scoped_refptr<content::MessageLoopRunner> runner = new content::MessageLoopRunner; + same_document_navigation_callback_ = runner->QuitClosure(); + ui_test_utils::NavigateToURL( + browser(), + embedded_test_server()->GetURL("/autofill/autofill_test_form.html#foo")); + // This will block until a same document navigation is observed. + runner->Run(); + same_document_navigation_callback_.Reset(); +} + +IN_PROC_BROWSER_TEST_F(ContentAutofillDriverBrowserTest, + SubframeNavigationDoesntHideAutofillPopup) { + // Main frame is on a.com, iframe is on b.com. + GURL url = embedded_test_server()->GetURL( + "a.com", "/autofill/cross_origin_iframe.html"); + ui_test_utils::NavigateToURL(browser(), url); + + // The Autofill popup should NOT be hidden for subframe navigations. + EXPECT_CALL(autofill_client_, HideAutofillPopup()).Times(0); + + scoped_refptr<content::MessageLoopRunner> runner = + new content::MessageLoopRunner; + subframe_navigation_callback_ = runner->QuitClosure(); + GURL iframe_url = embedded_test_server()->GetURL( + "b.com", "/autofill/autofill_test_form.html"); + EXPECT_TRUE(content::NavigateIframeToURL( + browser()->tab_strip_model()->GetActiveWebContents(), "crossFrame", + iframe_url)); + // This will block until a subframe navigation is observed. + runner->Run(); + subframe_navigation_callback_.Reset(); +} + +IN_PROC_BROWSER_TEST_F(ContentAutofillDriverBrowserTest, + TestPageNavigationHidingAutofillPopup) { + // HideAutofillPopup is called once for each navigation. + EXPECT_CALL(autofill_client_, HideAutofillPopup()).Times(2); + + scoped_refptr<content::MessageLoopRunner> runner = + new content::MessageLoopRunner; nav_entry_committed_callback_ = runner->QuitClosure(); browser()->OpenURL(content::OpenURLParams( GURL(chrome::kChromeUIBookmarksURL), content::Referrer(),
diff --git a/chrome/browser/chrome_browser_main_android.cc b/chrome/browser/chrome_browser_main_android.cc index 8803d5a..4bf799d3 100644 --- a/chrome/browser/chrome_browser_main_android.cc +++ b/chrome/browser/chrome_browser_main_android.cc
@@ -19,7 +19,8 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/descriptors_android.h" #include "components/crash/content/app/breakpad_linux.h" -#include "components/crash/content/browser/crash_dump_manager_android.h" +#include "components/crash/content/browser/child_process_crash_observer_android.h" +#include "components/crash/content/browser/crash_dump_observer_android.h" #include "components/signin/core/browser/signin_manager.h" #include "content/public/browser/android/compositor.h" #include "content/public/browser/browser_thread.h" @@ -40,11 +41,11 @@ int ChromeBrowserMainPartsAndroid::PreCreateThreads() { TRACE_EVENT0("startup", "ChromeBrowserMainPartsAndroid::PreCreateThreads") - // The CrashDumpManager must be registered before any child process is - // created (as it needs to be notified during child process - // creation). Such processes are created on the PROCESS_LAUNCHER - // thread, and so the observer is initialized and the manager - // registered before that thread is created. + // The ChildProcessCrashObserver must be registered before any child + // process is created (as it needs to be notified during child + // process creation). Such processes are created on the + // PROCESS_LAUNCHER thread, and so the observer is initialized and + // the manager registered before that thread is created. breakpad::CrashDumpObserver::Create(); #if defined(GOOGLE_CHROME_BUILD) @@ -65,7 +66,7 @@ base::FilePath crash_dump_dir; PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_dir); breakpad::CrashDumpObserver::GetInstance()->RegisterClient( - base::MakeUnique<breakpad::CrashDumpManager>( + base::MakeUnique<breakpad::ChildProcessCrashObserver>( crash_dump_dir, kAndroidMinidumpDescriptor)); }
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index dfb3a991..3f69c8f6 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -272,7 +272,7 @@ #include "chrome/browser/android/webapps/single_tab_mode_tab_helper.h" #include "chrome/browser/chrome_browser_main_android.h" #include "chrome/common/descriptors_android.h" -#include "components/crash/content/browser/crash_dump_manager_android.h" +#include "components/crash/content/browser/crash_dump_observer_android.h" #include "components/navigation_interception/intercept_navigation_delegate.h" #include "content/public/browser/android/java_interfaces.h" #include "services/service_manager/public/cpp/interface_provider.h"
diff --git a/chrome/browser/chromeos/login/app_launch_controller.cc b/chrome/browser/chromeos/login/app_launch_controller.cc index dfee29f..c9136c83 100644 --- a/chrome/browser/chromeos/login/app_launch_controller.cc +++ b/chrome/browser/chromeos/login/app_launch_controller.cc
@@ -368,9 +368,8 @@ return should_prompt; } - // Network configuration has to be explicitly allowed by the policy. - // Default to false if the policy is missing. - return false; + // Default to true to allow network configuration if the policy is missing. + return true; } return user_manager::UserManager::Get()->GetOwnerAccountId().is_valid();
diff --git a/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto b/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto index 4ebc720..299accbb 100644 --- a/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto +++ b/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto
@@ -376,16 +376,16 @@ optional bool enable_auto_login_bailout = 4 [default = true]; // Whether network configuration should be offered or not when the device - // does not have access to the Internet. If the policy is set to true, the - // network configuration will be offered. Otherwise (policy is omitted or set - // to false), only an error message is displayed. - // Note: If enable_auto_login_bailout policy above is set to false and this - // policy is omitted or set to false, there are chances that the device might - // become totally unusable when there is no Internet access and has to go - // through the recovery process. + // does not have access to the Internet. If the policy is omitted or set to + // true, the network configuration will be offered. Otherwise, only an error + // message is displayed. + // Note: If both this policy and enable_auto_login_bailout policy above is + // set to false, there are chances that the device might become totally + // unusable when there is no Internet access and has to go through the + // recovery process. // If the device is offline at startup then the network configuration screen // is always shown, before auto-login kicks in. - optional bool prompt_for_network_when_offline = 5 [default = false]; + optional bool prompt_for_network_when_offline = 5 [default = true]; } message AllowRedeemChromeOsRegistrationOffersProto {
diff --git a/chrome/browser/content_settings/content_settings_default_provider_unittest.cc b/chrome/browser/content_settings/content_settings_default_provider_unittest.cc index d6d43b2..4dc420f 100644 --- a/chrome/browser/content_settings/content_settings_default_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_default_provider_unittest.cc
@@ -4,7 +4,9 @@ #include <memory> +#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" +#include "build/build_config.h" #include "chrome/browser/content_settings/content_settings_mock_observer.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_profile.h" @@ -24,12 +26,13 @@ namespace content_settings { -class DefaultProviderTest : public testing::Test { +class ContentSettingsDefaultProviderTest : public testing::Test { public: - DefaultProviderTest() - : provider_(profile_.GetPrefs(), false) { + ContentSettingsDefaultProviderTest() + : provider_(profile_.GetPrefs(), false) {} + ~ContentSettingsDefaultProviderTest() override { + provider_.ShutdownOnUIThread(); } - ~DefaultProviderTest() override { provider_.ShutdownOnUIThread(); } protected: content::TestBrowserThreadBundle thread_bundle_; @@ -37,7 +40,7 @@ DefaultProvider provider_; }; -TEST_F(DefaultProviderTest, DefaultValues) { +TEST_F(ContentSettingsDefaultProviderTest, DefaultValues) { // Check setting defaults. EXPECT_EQ(CONTENT_SETTING_ALLOW, TestUtils::GetContentSetting(&provider_, GURL(), GURL(), @@ -71,7 +74,7 @@ EXPECT_FALSE(value.get()); } -TEST_F(DefaultProviderTest, IgnoreNonDefaultSettings) { +TEST_F(ContentSettingsDefaultProviderTest, IgnoreNonDefaultSettings) { GURL primary_url("http://www.google.com"); GURL secondary_url("http://www.google.com"); @@ -93,7 +96,7 @@ std::string(), false)); } -TEST_F(DefaultProviderTest, Observer) { +TEST_F(ContentSettingsDefaultProviderTest, Observer) { MockObserver mock_observer; EXPECT_CALL(mock_observer, OnContentSettingChanged( @@ -113,8 +116,7 @@ new base::Value(CONTENT_SETTING_BLOCK)); } - -TEST_F(DefaultProviderTest, ObservePref) { +TEST_F(ContentSettingsDefaultProviderTest, ObservePref) { PrefService* prefs = profile_.GetPrefs(); provider_.SetWebsiteSetting(ContentSettingsPattern::Wildcard(), @@ -142,7 +144,7 @@ } // Tests that fullscreen and mouselock content settings are cleared. -TEST_F(DefaultProviderTest, DiscardObsoletePreferences) { +TEST_F(ContentSettingsDefaultProviderTest, DiscardObsoletePreferences) { static const char kFullscreenPrefPath[] = "profile.default_content_setting_values.fullscreen"; #if !defined(OS_ANDROID) @@ -173,7 +175,42 @@ EXPECT_EQ(CONTENT_SETTING_BLOCK, prefs->GetInteger(kGeolocationPrefPath)); } -TEST_F(DefaultProviderTest, OffTheRecord) { +#if !defined(OS_IOS) && !defined(OS_ANDROID) +TEST_F(ContentSettingsDefaultProviderTest, DiscardObsoletePluginsAllow) { + PrefService* prefs = profile_.GetPrefs(); + const std::string& plugins_pref_path = + WebsiteSettingsRegistry::GetInstance() + ->Get(ContentSettingsType::CONTENT_SETTINGS_TYPE_PLUGINS) + ->default_value_pref_name(); + + // The ALLOW value of the plugins content setting should be discarded. + { + prefs->SetInteger(plugins_pref_path, CONTENT_SETTING_ALLOW); + DefaultProvider provider(prefs, false); + EXPECT_FALSE(prefs->HasPrefPath(plugins_pref_path)); + } + + // Other values of the plugins content setting should be preserved. + { + prefs->SetInteger(plugins_pref_path, CONTENT_SETTING_BLOCK); + DefaultProvider provider(prefs, false); + EXPECT_TRUE(prefs->HasPrefPath(plugins_pref_path)); + EXPECT_EQ(CONTENT_SETTING_BLOCK, prefs->GetInteger(plugins_pref_path)); + } + + { + prefs->SetInteger(plugins_pref_path, + CONTENT_SETTING_DETECT_IMPORTANT_CONTENT); + DefaultProvider provider(prefs, false); + + EXPECT_TRUE(prefs->HasPrefPath(plugins_pref_path)); + EXPECT_EQ(CONTENT_SETTING_DETECT_IMPORTANT_CONTENT, + prefs->GetInteger(plugins_pref_path)); + } +} +#endif // !defined(OS_IOS) && !defined(OS_ANDROID) + +TEST_F(ContentSettingsDefaultProviderTest, OffTheRecord) { DefaultProvider otr_provider(profile_.GetPrefs(), true /* incognito */); EXPECT_EQ(CONTENT_SETTING_ALLOW,
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index eb5b3a00..bb23cb3 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -188,6 +188,8 @@ "api/extension_action/extension_action_api.h", "api/extension_action/extension_page_actions_api_constants.cc", "api/extension_action/extension_page_actions_api_constants.h", + "api/feedback_private/chrome_feedback_private_delegate.cc", + "api/feedback_private/chrome_feedback_private_delegate.h", "api/feedback_private/feedback_private_api.cc", "api/feedback_private/feedback_private_api.h", "api/feedback_private/feedback_service.cc",
diff --git a/chrome/browser/extensions/api/chrome_extensions_api_client.cc b/chrome/browser/extensions/api/chrome_extensions_api_client.cc index ad8547a3..e24adde 100644 --- a/chrome/browser/extensions/api/chrome_extensions_api_client.cc +++ b/chrome/browser/extensions/api/chrome_extensions_api_client.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/extensions/api/chrome_device_permissions_prompt.h" #include "chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.h" #include "chrome/browser/extensions/api/declarative_content/default_content_predicate_evaluators.h" +#include "chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h" #include "chrome/browser/extensions/api/file_system/chrome_file_system_delegate.h" #include "chrome/browser/extensions/api/management/chrome_management_api_delegate.h" #include "chrome/browser/extensions/api/messaging/chrome_messaging_delegate.h" @@ -193,6 +194,15 @@ return messaging_delegate_.get(); } +FeedbackPrivateDelegate* +ChromeExtensionsAPIClient::GetFeedbackPrivateDelegate() { + if (!feedback_private_delegate_) { + feedback_private_delegate_ = + base::MakeUnique<ChromeFeedbackPrivateDelegate>(); + } + return feedback_private_delegate_.get(); +} + #if defined(OS_CHROMEOS) NonNativeFileSystemDelegate* ChromeExtensionsAPIClient::GetNonNativeFileSystemDelegate() {
diff --git a/chrome/browser/extensions/api/chrome_extensions_api_client.h b/chrome/browser/extensions/api/chrome_extensions_api_client.h index ee8d8c8..b1c93a7 100644 --- a/chrome/browser/extensions/api/chrome_extensions_api_client.h +++ b/chrome/browser/extensions/api/chrome_extensions_api_client.h
@@ -57,6 +57,7 @@ NetworkingCastPrivateDelegate* GetNetworkingCastPrivateDelegate() override; FileSystemDelegate* GetFileSystemDelegate() override; MessagingDelegate* GetMessagingDelegate() override; + FeedbackPrivateDelegate* GetFeedbackPrivateDelegate() override; #if defined(OS_CHROMEOS) NonNativeFileSystemDelegate* GetNonNativeFileSystemDelegate() override; @@ -75,6 +76,7 @@ networking_cast_private_delegate_; std::unique_ptr<FileSystemDelegate> file_system_delegate_; std::unique_ptr<MessagingDelegate> messaging_delegate_; + std::unique_ptr<FeedbackPrivateDelegate> feedback_private_delegate_; #if defined(OS_CHROMEOS) std::unique_ptr<NonNativeFileSystemDelegate> non_native_file_system_delegate_;
diff --git a/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc b/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc new file mode 100644 index 0000000..13c4e52 --- /dev/null +++ b/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc
@@ -0,0 +1,89 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h" + +#include <string> + +#include "base/memory/ptr_util.h" +#include "base/values.h" +#include "chrome/browser/browser_process.h" +#include "chrome/grit/generated_resources.h" +#include "components/strings/grit/components_strings.h" +#include "content/public/browser/browser_context.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/webui/web_ui_util.h" + +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/arc/arc_util.h" +#include "chrome/browser/profiles/profile.h" +#endif // defined(OS_CHROMEOS) + +namespace extensions { + +ChromeFeedbackPrivateDelegate::ChromeFeedbackPrivateDelegate() = default; +ChromeFeedbackPrivateDelegate::~ChromeFeedbackPrivateDelegate() = default; + +std::unique_ptr<base::DictionaryValue> +ChromeFeedbackPrivateDelegate::GetStrings( + content::BrowserContext* browser_context, + bool from_crash) const { + std::unique_ptr<base::DictionaryValue> dict = + base::MakeUnique<base::DictionaryValue>(); + +#define SET_STRING(id, idr) dict->SetString(id, l10n_util::GetStringUTF16(idr)) + SET_STRING("page-title", from_crash + ? IDS_FEEDBACK_REPORT_PAGE_TITLE_SAD_TAB_FLOW + : IDS_FEEDBACK_REPORT_PAGE_TITLE); + SET_STRING("additionalInfo", IDS_FEEDBACK_ADDITIONAL_INFO_LABEL); + SET_STRING("minimize-btn-label", IDS_FEEDBACK_MINIMIZE_BUTTON_LABEL); + SET_STRING("close-btn-label", IDS_FEEDBACK_CLOSE_BUTTON_LABEL); + SET_STRING("page-url", IDS_FEEDBACK_REPORT_URL_LABEL); + SET_STRING("screenshot", IDS_FEEDBACK_SCREENSHOT_LABEL); + SET_STRING("user-email", IDS_FEEDBACK_USER_EMAIL_LABEL); + SET_STRING("anonymous-user", IDS_FEEDBACK_ANONYMOUS_EMAIL_OPTION); +#if defined(OS_CHROMEOS) + if (arc::IsArcPlayStoreEnabledForProfile( + Profile::FromBrowserContext(browser_context))) { + SET_STRING("sys-info", + IDS_FEEDBACK_INCLUDE_SYSTEM_INFORMATION_AND_METRICS_CHKBOX_ARC); + } else { + SET_STRING("sys-info", + IDS_FEEDBACK_INCLUDE_SYSTEM_INFORMATION_AND_METRICS_CHKBOX); + } +#else + SET_STRING("sys-info", IDS_FEEDBACK_INCLUDE_SYSTEM_INFORMATION_CHKBOX); +#endif + SET_STRING("attach-file-label", IDS_FEEDBACK_ATTACH_FILE_LABEL); + SET_STRING("attach-file-note", IDS_FEEDBACK_ATTACH_FILE_NOTE); + SET_STRING("attach-file-to-big", IDS_FEEDBACK_ATTACH_FILE_TO_BIG); + SET_STRING("reading-file", IDS_FEEDBACK_READING_FILE); + SET_STRING("send-report", IDS_FEEDBACK_SEND_REPORT); + SET_STRING("cancel", IDS_CANCEL); + SET_STRING("no-description", IDS_FEEDBACK_NO_DESCRIPTION); + SET_STRING("privacy-note", IDS_FEEDBACK_PRIVACY_NOTE); + SET_STRING("performance-trace", + IDS_FEEDBACK_INCLUDE_PERFORMANCE_TRACE_CHECKBOX); + // Add the localized strings needed for the "system information" page. + SET_STRING("sysinfoPageTitle", IDS_FEEDBACK_SYSINFO_PAGE_TITLE); + SET_STRING("sysinfoPageDescription", IDS_ABOUT_SYS_DESC); + SET_STRING("sysinfoPageTableTitle", IDS_ABOUT_SYS_TABLE_TITLE); + SET_STRING("sysinfoPageExpandAllBtn", IDS_ABOUT_SYS_EXPAND_ALL); + SET_STRING("sysinfoPageCollapseAllBtn", IDS_ABOUT_SYS_COLLAPSE_ALL); + SET_STRING("sysinfoPageExpandBtn", IDS_ABOUT_SYS_EXPAND); + SET_STRING("sysinfoPageCollapseBtn", IDS_ABOUT_SYS_COLLAPSE); + SET_STRING("sysinfoPageStatusLoading", IDS_FEEDBACK_SYSINFO_PAGE_LOADING); + // And the localized strings needed for the SRT Download Prompt. + SET_STRING("srtPromptBody", IDS_FEEDBACK_SRT_PROMPT_BODY); + SET_STRING("srtPromptAcceptButton", IDS_FEEDBACK_SRT_PROMPT_ACCEPT_BUTTON); + SET_STRING("srtPromptDeclineButton", IDS_FEEDBACK_SRT_PROMPT_DECLINE_BUTTON); +#undef SET_STRING + + const std::string& app_locale = g_browser_process->GetApplicationLocale(); + webui::SetLoadTimeDataDefaults(app_locale, dict.get()); + + return dict; +} + +} // namespace extensions
diff --git a/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h b/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h new file mode 100644 index 0000000..0e02e5b --- /dev/null +++ b/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h
@@ -0,0 +1,32 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_API_FEEDBACK_PRIVATE_CHROME_FEEDBACK_PRIVATE_DELEGATE_H_ +#define CHROME_BROWSER_EXTENSIONS_API_FEEDBACK_PRIVATE_CHROME_FEEDBACK_PRIVATE_DELEGATE_H_ + +#include "extensions/browser/api/feedback_private/feedback_private_delegate.h" + +#include <memory> + +#include "base/macros.h" + +namespace extensions { + +class ChromeFeedbackPrivateDelegate : public FeedbackPrivateDelegate { + public: + ChromeFeedbackPrivateDelegate(); + ~ChromeFeedbackPrivateDelegate() override; + + // FeedbackPrivateDelegate: + std::unique_ptr<base::DictionaryValue> GetStrings( + content::BrowserContext* browser_context, + bool from_crash) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(ChromeFeedbackPrivateDelegate); +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_API_FEEDBACK_PRIVATE_CHROME_FEEDBACK_PRIVATE_DELEGATE_H_
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc b/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc index e99d991..09a5063 100644 --- a/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc +++ b/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc
@@ -9,6 +9,7 @@ #include <vector> #include "base/lazy_instance.h" +#include "base/logging.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/metrics/statistics_recorder.h" @@ -28,15 +29,13 @@ #include "chrome/grit/generated_resources.h" #include "components/feedback/tracing_manager.h" #include "components/signin/core/browser/signin_manager.h" -#include "components/strings/grit/components_strings.h" +#include "extensions/browser/api/extensions_api_client.h" +#include "extensions/browser/api/feedback_private/feedback_private_delegate.h" #include "extensions/browser/event_router.h" -#include "extensions/browser/extensions_browser_client.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/webui/web_ui_util.h" #include "url/url_util.h" #if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/extensions/api/feedback_private/log_source_access_manager.h" #endif // defined(OS_CHROMEOS) @@ -188,63 +187,13 @@ auto params = feedback_private::GetStrings::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params.get()); - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - -#define SET_STRING(id, idr) \ - dict->SetString(id, l10n_util::GetStringUTF16(idr)) - SET_STRING("page-title", - params->flow == FeedbackFlow::FEEDBACK_FLOW_SADTABCRASH - ? IDS_FEEDBACK_REPORT_PAGE_TITLE_SAD_TAB_FLOW - : IDS_FEEDBACK_REPORT_PAGE_TITLE); - SET_STRING("additionalInfo", IDS_FEEDBACK_ADDITIONAL_INFO_LABEL); - SET_STRING("minimize-btn-label", IDS_FEEDBACK_MINIMIZE_BUTTON_LABEL); - SET_STRING("close-btn-label", IDS_FEEDBACK_CLOSE_BUTTON_LABEL); - SET_STRING("page-url", IDS_FEEDBACK_REPORT_URL_LABEL); - SET_STRING("screenshot", IDS_FEEDBACK_SCREENSHOT_LABEL); - SET_STRING("user-email", IDS_FEEDBACK_USER_EMAIL_LABEL); - SET_STRING("anonymous-user", IDS_FEEDBACK_ANONYMOUS_EMAIL_OPTION); -#if defined(OS_CHROMEOS) - if (arc::IsArcPlayStoreEnabledForProfile( - Profile::FromBrowserContext(browser_context()))) { - SET_STRING("sys-info", - IDS_FEEDBACK_INCLUDE_SYSTEM_INFORMATION_AND_METRICS_CHKBOX_ARC); - } else { - SET_STRING("sys-info", - IDS_FEEDBACK_INCLUDE_SYSTEM_INFORMATION_AND_METRICS_CHKBOX); - } -#else - SET_STRING("sys-info", IDS_FEEDBACK_INCLUDE_SYSTEM_INFORMATION_CHKBOX); -#endif - SET_STRING("attach-file-label", IDS_FEEDBACK_ATTACH_FILE_LABEL); - SET_STRING("attach-file-note", IDS_FEEDBACK_ATTACH_FILE_NOTE); - SET_STRING("attach-file-to-big", IDS_FEEDBACK_ATTACH_FILE_TO_BIG); - SET_STRING("reading-file", IDS_FEEDBACK_READING_FILE); - SET_STRING("send-report", IDS_FEEDBACK_SEND_REPORT); - SET_STRING("cancel", IDS_CANCEL); - SET_STRING("no-description", IDS_FEEDBACK_NO_DESCRIPTION); - SET_STRING("privacy-note", IDS_FEEDBACK_PRIVACY_NOTE); - SET_STRING("performance-trace", - IDS_FEEDBACK_INCLUDE_PERFORMANCE_TRACE_CHECKBOX); - // Add the localized strings needed for the "system information" page. - SET_STRING("sysinfoPageTitle", IDS_FEEDBACK_SYSINFO_PAGE_TITLE); - SET_STRING("sysinfoPageDescription", IDS_ABOUT_SYS_DESC); - SET_STRING("sysinfoPageTableTitle", IDS_ABOUT_SYS_TABLE_TITLE); - SET_STRING("sysinfoPageExpandAllBtn", IDS_ABOUT_SYS_EXPAND_ALL); - SET_STRING("sysinfoPageCollapseAllBtn", IDS_ABOUT_SYS_COLLAPSE_ALL); - SET_STRING("sysinfoPageExpandBtn", IDS_ABOUT_SYS_EXPAND); - SET_STRING("sysinfoPageCollapseBtn", IDS_ABOUT_SYS_COLLAPSE); - SET_STRING("sysinfoPageStatusLoading", IDS_FEEDBACK_SYSINFO_PAGE_LOADING); - // And the localized strings needed for the SRT Download Prompt. - SET_STRING("srtPromptBody", IDS_FEEDBACK_SRT_PROMPT_BODY); - SET_STRING("srtPromptAcceptButton", IDS_FEEDBACK_SRT_PROMPT_ACCEPT_BUTTON); - SET_STRING("srtPromptDeclineButton", - IDS_FEEDBACK_SRT_PROMPT_DECLINE_BUTTON); -#undef SET_STRING - - const std::string& app_locale = - ExtensionsBrowserClient::Get()->GetApplicationLocale(); - webui::SetLoadTimeDataDefaults(app_locale, dict.get()); - + FeedbackPrivateDelegate* feedback_private_delegate = + ExtensionsAPIClient::Get()->GetFeedbackPrivateDelegate(); + DCHECK(feedback_private_delegate); + std::unique_ptr<base::DictionaryValue> dict = + feedback_private_delegate->GetStrings( + browser_context(), + params->flow == FeedbackFlow::FEEDBACK_FLOW_SADTABCRASH); if (test_callback_ && !test_callback_->is_null()) test_callback_->Run();
diff --git a/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.cc b/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.cc index 14aef77a..19cfdbe 100644 --- a/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.cc +++ b/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.cc
@@ -167,16 +167,15 @@ } bool ImageWriterPrivateListRemovableStorageDevicesFunction::RunAsync() { - RemovableStorageProvider::GetAllDevices( - base::Bind( + RemovableStorageProvider::GetAllDevices(base::BindOnce( &ImageWriterPrivateListRemovableStorageDevicesFunction::OnDeviceListReady, this)); return true; } void ImageWriterPrivateListRemovableStorageDevicesFunction::OnDeviceListReady( - scoped_refptr<StorageDeviceList> device_list, - bool success) { + scoped_refptr<StorageDeviceList> device_list) { + const bool success = device_list.get() != nullptr; if (success) { results_ = image_writer_api::ListRemovableStorageDevices::Results::Create( device_list->data);
diff --git a/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.h b/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.h index a7abf444..68b17d7 100644 --- a/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.h +++ b/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.h
@@ -72,8 +72,7 @@ private: ~ImageWriterPrivateListRemovableStorageDevicesFunction() override; bool RunAsync() override; - void OnDeviceListReady(scoped_refptr<StorageDeviceList> device_list, - bool success); + void OnDeviceListReady(scoped_refptr<StorageDeviceList> device_list); }; } // namespace extensions
diff --git a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider.cc b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider.cc index 1b2a3cd..c16b847 100644 --- a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider.cc +++ b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/extensions/api/image_writer_private/removable_storage_provider.h" #include "base/lazy_instance.h" +#include "base/task_scheduler/post_task.h" #include "base/threading/thread_task_runner_handle.h" #include "content/public/browser/browser_thread.h" @@ -19,29 +20,30 @@ void RemovableStorageProvider::GetAllDevices(DeviceListReadyCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (g_test_device_list.Get().get() != NULL) { + if (g_test_device_list.Get().get() != nullptr) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(callback, g_test_device_list.Get(), true)); + FROM_HERE, + base::BindOnce(std::move(callback), g_test_device_list.Get())); return; } - - scoped_refptr<StorageDeviceList> device_list(new StorageDeviceList); - // We need to do some file i/o to get the device block size - content::BrowserThread::PostTaskAndReplyWithResult( - content::BrowserThread::FILE, + base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, - base::Bind(PopulateDeviceList, device_list), - base::Bind(callback, device_list)); + {base::MayBlock(), base::TaskPriority::USER_VISIBLE, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, + base::BindOnce(&RemovableStorageProvider::PopulateDeviceList), + std::move(callback)); } +// static void RemovableStorageProvider::SetDeviceListForTesting( scoped_refptr<StorageDeviceList> device_list) { g_test_device_list.Get() = device_list; } +// static void RemovableStorageProvider::ClearDeviceListForTesting() { - g_test_device_list.Get() = NULL; + g_test_device_list.Get() = nullptr; } } // namespace extensions
diff --git a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider.h b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider.h index 7c67242..5dd0087 100644 --- a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider.h +++ b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider.h
@@ -19,8 +19,8 @@ // storage devices class RemovableStorageProvider { public: - typedef base::Callback<void(scoped_refptr<StorageDeviceList>, bool)> - DeviceListReadyCallback; + using DeviceListReadyCallback = + base::OnceCallback<void(scoped_refptr<StorageDeviceList>)>; // Gets the list of all available devices and returns it via callback. static void GetAllDevices(DeviceListReadyCallback callback); @@ -34,8 +34,9 @@ static void ClearDeviceListForTesting(); private: - // Fills the provided empty device list with the available devices. - static bool PopulateDeviceList(scoped_refptr<StorageDeviceList> device_list); + // Returns available list of devices. If there is an error retrieving devices, + // then returns nullptr. + static scoped_refptr<StorageDeviceList> PopulateDeviceList(); }; } // namespace extensions
diff --git a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_chromeos.cc b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_chromeos.cc index 6dfc9f1..c359977 100644 --- a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_chromeos.cc +++ b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_chromeos.cc
@@ -17,10 +17,11 @@ // fixed disk. In fact, some SD cards will present themselves as fixed disks // (see http://crbug.com/340761). Thus we just expose all USB and SD drives. // static -bool RemovableStorageProvider::PopulateDeviceList( - scoped_refptr<StorageDeviceList> device_list) { +scoped_refptr<StorageDeviceList> +RemovableStorageProvider::PopulateDeviceList() { DiskMountManager* disk_mount_manager = DiskMountManager::GetInstance(); const DiskMountManager::DiskMap& disks = disk_mount_manager->disks(); + scoped_refptr<StorageDeviceList> device_list(new StorageDeviceList()); for (DiskMountManager::DiskMap::const_iterator iter = disks.begin(); iter != disks.end(); @@ -48,7 +49,7 @@ } } - return true; + return device_list; } } // namespace extensions
diff --git a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_chromeos_unittest.cc b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_chromeos_unittest.cc index 098f786..70687146 100644 --- a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_chromeos_unittest.cc +++ b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_chromeos_unittest.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "chrome/browser/extensions/api/image_writer_private/removable_storage_provider.h" #include "chromeos/disks/mock_disk_mount_manager.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -33,6 +34,9 @@ class RemovableStorageProviderChromeOsUnitTest : public testing::Test { public: + RemovableStorageProviderChromeOsUnitTest() + : scoped_task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::UI) {} void SetUp() override { disk_mount_manager_mock_ = new MockDiskMountManager(); DiskMountManager::InitializeForTesting(disk_mount_manager_mock_); @@ -41,7 +45,7 @@ void TearDown() override { DiskMountManager::Shutdown(); } - void DevicesCallback(scoped_refptr<StorageDeviceList> devices, bool success) { + void DevicesCallback(scoped_refptr<StorageDeviceList> devices) { devices_ = devices; } @@ -109,6 +113,7 @@ EXPECT_EQ(capacity, device->capacity); } + base::test::ScopedTaskEnvironment scoped_task_environment_; MockDiskMountManager* disk_mount_manager_mock_; scoped_refptr<StorageDeviceList> devices_; @@ -132,7 +137,7 @@ base::Bind(&RemovableStorageProviderChromeOsUnitTest::DevicesCallback, base::Unretained(this))); - base::RunLoop().RunUntilIdle(); + scoped_task_environment_.RunUntilIdle(); ASSERT_EQ(2U, devices_->data.size()); @@ -153,7 +158,7 @@ base::Bind(&RemovableStorageProviderChromeOsUnitTest::DevicesCallback, base::Unretained(this))); - base::RunLoop().RunUntilIdle(); + scoped_task_environment_.RunUntilIdle(); ASSERT_EQ(2U, devices_->data.size());
diff --git a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc index 60921f31..389479b1 100644 --- a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc +++ b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc
@@ -42,14 +42,16 @@ return blk_size; } -bool RemovableStorageProvider::PopulateDeviceList( - scoped_refptr<StorageDeviceList> device_list) { +// static +scoped_refptr<StorageDeviceList> +RemovableStorageProvider::PopulateDeviceList() { device::ScopedUdevPtr udev(device::udev_new()); if (!udev) { DLOG(ERROR) << "Can't create udev"; - return false; + return nullptr; } + scoped_refptr<StorageDeviceList> device_list(new StorageDeviceList()); /* Create a list of the devices in the 'block' subsystem. */ device::ScopedUdevEnumeratePtr enumerate( device::udev_enumerate_new(udev.get())); @@ -106,7 +108,7 @@ device_list->data.push_back(std::move(device_item)); } - return true; + return device_list; } } // namespace extensions
diff --git a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_mac.cc b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_mac.cc index ad1f5d3..8191b1c 100644 --- a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_mac.cc +++ b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_mac.cc
@@ -22,8 +22,8 @@ namespace extensions { // static -bool RemovableStorageProvider::PopulateDeviceList( - scoped_refptr<StorageDeviceList> device_list) { +scoped_refptr<StorageDeviceList> +RemovableStorageProvider::PopulateDeviceList() { base::ThreadRestrictions::AssertIOAllowed(); // Match only writable whole-disks. CFMutableDictionaryRef matching = IOServiceMatching(kIOMediaClass); @@ -34,11 +34,12 @@ if (IOServiceGetMatchingServices( kIOMasterPortDefault, matching, &disk_iterator) != KERN_SUCCESS) { LOG(ERROR) << "Unable to get disk services."; - return false; + return nullptr; } base::mac::ScopedIOObject<io_service_t> iterator_ref(disk_iterator); io_object_t disk_obj; + scoped_refptr<StorageDeviceList> device_list(new StorageDeviceList()); while ((disk_obj = IOIteratorNext(disk_iterator))) { base::mac::ScopedIOObject<io_object_t> disk_obj_ref(disk_obj); @@ -100,7 +101,7 @@ device_list->data.push_back(std::move(device)); } - return true; + return device_list; } } // namespace extensions
diff --git a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_win.cc b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_win.cc index a48c2b7e..51db3d51 100644 --- a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_win.cc +++ b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_win.cc
@@ -174,8 +174,9 @@ } // namespace -bool RemovableStorageProvider::PopulateDeviceList( - scoped_refptr<StorageDeviceList> device_list) { +// static +scoped_refptr<StorageDeviceList> +RemovableStorageProvider::PopulateDeviceList() { HDEVINFO interface_enumerator = SetupDiGetClassDevs( &DiskClassGuid, NULL, // Enumerator. @@ -185,13 +186,14 @@ if (interface_enumerator == INVALID_HANDLE_VALUE) { DPLOG(ERROR) << "SetupDiGetClassDevs failed."; - return false; + return nullptr; } DWORD index = 0; SP_DEVICE_INTERFACE_DATA interface_data; interface_data.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA); + scoped_refptr<StorageDeviceList> device_list(new StorageDeviceList()); while (SetupDiEnumDeviceInterfaces( interface_enumerator, NULL, // Device Info data. @@ -207,11 +209,11 @@ if (error_code != ERROR_NO_MORE_ITEMS) { PLOG(ERROR) << "SetupDiEnumDeviceInterfaces failed"; SetupDiDestroyDeviceInfoList(interface_enumerator); - return false; + return nullptr; } SetupDiDestroyDeviceInfoList(interface_enumerator); - return true; + return device_list; } } // namespace extensions
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index 349f7c5a..9d797e6 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -445,6 +445,14 @@ password_field_exists); } } + +void ChromePasswordManagerClient::LogPasswordReuseDetectedEvent() { + safe_browsing::PasswordProtectionService* pps = + GetPasswordProtectionService(); + if (pps) { + pps->MaybeLogPasswordReuseDetectedEvent(web_contents()); + } +} #endif ukm::UkmRecorder* ChromePasswordManagerClient::GetUkmRecorder() {
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h index f9b6ee7..9c01080 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.h +++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -115,6 +115,8 @@ void CheckProtectedPasswordEntry(const std::string& password_saved_domain, bool password_field_exists) override; + + void LogPasswordReuseDetectedEvent() override; #endif ukm::UkmRecorder* GetUkmRecorder() override;
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc index 334ed68..aa4f4314 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -85,6 +85,7 @@ MOCK_METHOD0(IsIncognito, bool()); MOCK_METHOD2(IsPingingEnabled, bool(const base::Feature&, RequestOutcome*)); MOCK_METHOD0(IsHistorySyncEnabled, bool()); + MOCK_METHOD1(MaybeLogPasswordReuseDetectedEvent, void(WebContents*)); MOCK_METHOD4(MaybeStartPasswordFieldOnFocusRequest, void(WebContents*, const GURL&, const GURL&, const GURL&)); MOCK_METHOD4(MaybeStartProtectedPasswordEntryRequest, @@ -642,4 +643,16 @@ client->CheckProtectedPasswordEntry(std::string("saved_domain.com"), true); } +TEST_F(ChromePasswordManagerClientTest, VerifyLogPasswordReuseDetectedEvent) { + std::unique_ptr<WebContents> test_web_contents( + content::WebContentsTester::CreateTestWebContents( + web_contents()->GetBrowserContext(), nullptr)); + std::unique_ptr<MockChromePasswordManagerClient> client( + new MockChromePasswordManagerClient(test_web_contents.get())); + EXPECT_CALL(*client->password_protection_service(), + MaybeLogPasswordReuseDetectedEvent(test_web_contents.get())) + .Times(1); + client->LogPasswordReuseDetectedEvent(); +} + #endif
diff --git a/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc b/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc index 9940399..566eec3d 100644 --- a/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc +++ b/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc
@@ -470,7 +470,7 @@ EXPECT_FALSE(CheckServiceProcessReady()); startup_channel_handle_ = mojo::edk::NamedPlatformHandle( - base::StringPrintf("%d.%p.%d", base::GetCurrentProcId(), this, + base::StringPrintf("%" CrPRIdPid ".%p.%d", base::GetCurrentProcId(), this, base::RandInt(0, std::numeric_limits<int>::max()))); startup_channel_ = IPC::ChannelProxy::Create( peer_connection_
diff --git a/chrome/browser/referrer_policy_browsertest.cc b/chrome/browser/referrer_policy_browsertest.cc index 5c97e7aa..395e78b 100644 --- a/chrome/browser/referrer_policy_browsertest.cc +++ b/chrome/browser/referrer_policy_browsertest.cc
@@ -516,6 +516,15 @@ // Watch for all possible outcomes to avoid timeouts if something breaks. AddAllPossibleTitles(start_url, &title_watcher); + // Erase the current title in the NavigationEntry. + // + // TitleWatcher overrides WebContentObserver's TitleWasSet() but also + // DidStopLoading(). The page that is being reloaded sets its title after load + // is complete, so the title change is missed because the title is checked on + // load. Clearing the title ensures that TitleWatcher will wait for the actual + // title setting. + tab->GetController().GetActiveEntry()->SetTitle(base::string16()); + // Request tablet version. chrome::ToggleRequestTabletSite(browser()); EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
diff --git a/chrome/browser/resources/chromeos/arc_support/background.js b/chrome/browser/resources/chromeos/arc_support/background.js index 8e02a25..91d507f4 100644 --- a/chrome/browser/resources/chromeos/arc_support/background.js +++ b/chrome/browser/resources/chromeos/arc_support/background.js
@@ -447,7 +447,7 @@ // end of the SAML flow. Before that, we're on the Active Directory // Federation Services server. if (this.deviceManagementUrlPrefix_ && - details.url.startsWith(this.deviceManagementUrlPrefix)) { + details.url.startsWith(this.deviceManagementUrlPrefix_)) { // Did it actually work? if (details.statusCode == 200) { // 'code' is unused, but it needs to be there.
diff --git a/chrome/browser/resources/inspect/inspect.css b/chrome/browser/resources/inspect/inspect.css index 8c3957b..13875de 100644 --- a/chrome/browser/resources/inspect/inspect.css +++ b/chrome/browser/resources/inspect/inspect.css
@@ -182,8 +182,7 @@ } .used-for-port-forwarding { - background-image: -webkit-image-set(url(chrome://theme/IDR_INFO) 1x, - url(chrome://theme/IDR_INFO@2x) 2x); + background-image: url(../../../../ui/webui/resources/images/info.svg); height: 15px; margin-left: 20px; width: 15px;
diff --git a/chrome/browser/resources/options/clear_browser_data_overlay.css b/chrome/browser/resources/options/clear_browser_data_overlay.css index 2cfeb46..555ff4dc 100644 --- a/chrome/browser/resources/options/clear_browser_data_overlay.css +++ b/chrome/browser/resources/options/clear_browser_data_overlay.css
@@ -71,7 +71,7 @@ } #clear-browser-data-general-footer { - background: url(info.svg) left no-repeat; + background: url(../../../../ui/webui/resources/images/info.svg) left no-repeat; margin: 0; min-height: 18px; }
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 new file mode 100644 index 0000000..4ba4c5a --- /dev/null +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_browsertest_win.cc
@@ -0,0 +1,113 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.h" + +#include <memory> + +#include "base/memory/ptr_util.h" +#include "base/memory/ref_counted.h" +#include "base/run_loop.h" +#include "chrome/browser/lifetime/keep_alive_types.h" +#include "chrome/browser/lifetime/scoped_keep_alive.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace safe_browsing { +namespace { + +using ::testing::_; +using ::testing::StrictMock; +using ::testing::Return; + +class MockChromeCleanerPromptDelegate : public ChromeCleanerPromptDelegate { + public: + MOCK_METHOD3(ShowChromeCleanerPrompt, + void(Browser* browser, + ChromeCleanerDialogController* dialog_controller, + ChromeCleanerController* cleaner_controller)); +}; + +class MockChromeCleanerController + : public safe_browsing::ChromeCleanerController { + public: + MOCK_METHOD0(ShouldShowCleanupInSettingsUI, bool()); + MOCK_METHOD0(IsPoweredByPartner, bool()); + MOCK_CONST_METHOD0(state, State()); + MOCK_CONST_METHOD0(idle_reason, IdleReason()); + MOCK_METHOD1(SetLogsEnabled, void(bool)); + MOCK_CONST_METHOD0(logs_enabled, bool()); + MOCK_METHOD0(ResetIdleState, void()); + MOCK_METHOD1(AddObserver, void(Observer*)); + MOCK_METHOD1(RemoveObserver, void(Observer*)); + MOCK_METHOD1(Scan, void(const safe_browsing::SwReporterInvocation&)); + MOCK_METHOD2(ReplyWithUserResponse, void(Profile*, UserResponse)); + MOCK_METHOD0(Reboot, void()); +}; + +class ChromeCleanerPromptUserTest : public InProcessBrowserTest { + public: + void SetUpInProcessBrowserTestFixture() override { +// dialog_controller_ expects that the cleaner controller would be on +// scanning state. +#if DCHECK_IS_ON() + EXPECT_CALL(mock_cleaner_controller_, state()) + .WillOnce(Return(ChromeCleanerController::State::kScanning)); +#endif + EXPECT_CALL(mock_cleaner_controller_, AddObserver(_)); + dialog_controller_ = + new ChromeCleanerDialogControllerImpl(&mock_cleaner_controller_); + dialog_controller_->SetPromptDelegateForTests(&mock_delegate_); + } + + protected: + MockChromeCleanerController mock_cleaner_controller_; + ChromeCleanerDialogControllerImpl* dialog_controller_; + StrictMock<MockChromeCleanerPromptDelegate> mock_delegate_; +}; + +IN_PROC_BROWSER_TEST_F(ChromeCleanerPromptUserTest, + OnInfectedBrowserAvailable) { + EXPECT_CALL(mock_delegate_, ShowChromeCleanerPrompt(_, _, _)).Times(1); + dialog_controller_->OnInfected(std::set<base::FilePath>()); +} + +IN_PROC_BROWSER_TEST_F(ChromeCleanerPromptUserTest, + OnInfectedBrowserNotAvailable) { + browser()->window()->Minimize(); + base::RunLoop().RunUntilIdle(); + dialog_controller_->OnInfected(std::set<base::FilePath>()); + + // 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); + + browser()->window()->Restore(); + base::RunLoop().RunUntilIdle(); +} + +IN_PROC_BROWSER_TEST_F(ChromeCleanerPromptUserTest, AllBrowsersClosed) { + std::unique_ptr<ScopedKeepAlive> keep_alive = + base::MakeUnique<ScopedKeepAlive>(KeepAliveOrigin::BROWSER, + KeepAliveRestartOption::DISABLED); + + CloseAllBrowsers(); + base::RunLoop().RunUntilIdle(); + dialog_controller_->OnInfected(std::set<base::FilePath>()); + + // 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); + + CreateBrowser(ProfileManager::GetActiveUserProfile()); + base::RunLoop().RunUntilIdle(); +} + +} // namespace +} // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.cc index 949162f..52dbed6 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/browser_list.h" #include "ui/base/window_open_disposition.h" namespace safe_browsing { @@ -43,14 +44,30 @@ } // namespace +ChromeCleanerPromptDelegate::~ChromeCleanerPromptDelegate() = default; + +class ChromeCleanerPromptDelegateImpl : public ChromeCleanerPromptDelegate { + public: + void ShowChromeCleanerPrompt( + Browser* browser, + ChromeCleanerDialogController* dialog_controller, + ChromeCleanerController* cleaner_controller) override { + chrome::ShowChromeCleanerPrompt(browser, dialog_controller, + cleaner_controller); + } +}; + ChromeCleanerDialogControllerImpl::ChromeCleanerDialogControllerImpl( ChromeCleanerController* cleaner_controller) - : cleaner_controller_(cleaner_controller) { + : cleaner_controller_(cleaner_controller), + prompt_delegate_impl_( + base::MakeUnique<ChromeCleanerPromptDelegateImpl>()) { DCHECK(cleaner_controller_); DCHECK_EQ(ChromeCleanerController::State::kScanning, cleaner_controller_->state()); cleaner_controller_->AddObserver(this); + prompt_delegate_ = prompt_delegate_impl_.get(); } ChromeCleanerDialogControllerImpl::~ChromeCleanerDialogControllerImpl() = @@ -173,18 +190,15 @@ browser_ = chrome_cleaner_util::FindBrowser(); if (!browser_) { - // TODO(alito): Register with chrome::BrowserListObserver to get notified - // later if a suitable browser window becomes available to show the - // prompt. http://crbug.com/734677 RecordPromptNotShownWithReasonHistogram( - NO_PROMPT_REASON_BROWSER_NOT_AVAILABLE); - OnInteractionDone(); + NO_PROMPT_REASON_WAITING_FOR_BROWSER); + prompt_pending_ = true; + BrowserList::AddObserver(this); return; } - - chrome::ShowChromeCleanerPrompt(browser_, this, cleaner_controller_); - RecordPromptShownHistogram(); - dialog_shown_ = true; + ShowChromeCleanerPrompt(); + RecordPromptShownWithTypeHistogram( + PromptTypeHistogramValue::PROMPT_TYPE_ON_TRANSITION_TO_INFECTED_STATE); } void ChromeCleanerDialogControllerImpl::OnCleaning( @@ -198,7 +212,37 @@ OnInteractionDone(); } +void ChromeCleanerDialogControllerImpl::OnBrowserSetLastActive( + Browser* browser) { + DCHECK(prompt_pending_); + DCHECK(browser); + DCHECK(!browser_); + + browser_ = browser; + ShowChromeCleanerPrompt(); + RecordPromptShownWithTypeHistogram( + PromptTypeHistogramValue::PROMPT_TYPE_ON_BROWSER_WINDOW_AVAILABLE); + prompt_pending_ = false; + BrowserList::RemoveObserver(this); +} + +void ChromeCleanerDialogControllerImpl::SetPromptDelegateForTests( + ChromeCleanerPromptDelegate* delegate) { + prompt_delegate_ = delegate; +} + +void ChromeCleanerDialogControllerImpl::ShowChromeCleanerPrompt() { + prompt_delegate_->ShowChromeCleanerPrompt(browser_, this, + cleaner_controller_); + dialog_shown_ = true; +} + void ChromeCleanerDialogControllerImpl::OnInteractionDone() { + if (prompt_pending_) { + BrowserList::RemoveObserver(this); + prompt_pending_ = false; + } + cleaner_controller_->RemoveObserver(this); delete this; }
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.h b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.h index 36274977..ef46c39 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.h +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_SAFE_BROWSING_CHROME_CLEANER_CHROME_CLEANER_DIALOG_CONTROLLER_IMPL_WIN_H_ #define CHROME_BROWSER_SAFE_BROWSING_CHROME_CLEANER_CHROME_CLEANER_DIALOG_CONTROLLER_IMPL_WIN_H_ +#include <memory> #include <set> #include "base/files/file_path.h" @@ -12,14 +13,25 @@ #include "base/time/time.h" #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h" #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_win.h" +#include "chrome/browser/ui/browser_list_observer.h" class Browser; namespace safe_browsing { +class ChromeCleanerPromptDelegate { + public: + virtual void ShowChromeCleanerPrompt( + Browser* browser, + safe_browsing::ChromeCleanerDialogController* dialog_controller, + safe_browsing::ChromeCleanerController* cleaner_controller) = 0; + virtual ~ChromeCleanerPromptDelegate(); +}; + class ChromeCleanerDialogControllerImpl : public ChromeCleanerDialogController, - public ChromeCleanerController::Observer { + public ChromeCleanerController::Observer, + public chrome::BrowserListObserver { public: // An instance should only be created when |cleaner_controller| is in the // kScanning state. @@ -43,16 +55,29 @@ void OnCleaning(const std::set<base::FilePath>& files_to_delete) override; void OnRebootRequired() override; + // chrome::BrowserListObserver overrides. + void OnBrowserSetLastActive(Browser* browser) override; + + // Test specific methods. + void SetPromptDelegateForTests(ChromeCleanerPromptDelegate* delegate); + protected: ~ChromeCleanerDialogControllerImpl() override; private: void OnInteractionDone(); + void ShowChromeCleanerPrompt(); ChromeCleanerController* cleaner_controller_ = nullptr; bool dialog_shown_ = false; + + // In case there is no browser available to prompt a user + // signal it, this way we can prompt it once a browser gets available.. + bool prompt_pending_ = false; base::Time time_dialog_shown_; // Used for reporting metrics. Browser* browser_ = nullptr; + std::unique_ptr<ChromeCleanerPromptDelegate> prompt_delegate_impl_; + ChromeCleanerPromptDelegate* prompt_delegate_ = nullptr; DISALLOW_COPY_AND_ASSIGN(ChromeCleanerDialogControllerImpl); };
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc index 4bcd0ae..40b155a 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc
@@ -37,9 +37,6 @@ "https://dl.google.com/dl" "/softwareremovaltool/win/c/chrome_cleanup_tool.exe?chrome-prompt=1"; -constexpr char kSoftwareReporterPromptShownMetricName[] = - "SoftwareReporter.PromptShown"; - } // namespace namespace safe_browsing { @@ -114,13 +111,13 @@ SRT_PROMPT_MAX); } -void RecordPromptShownHistogram() { - UMA_HISTOGRAM_BOOLEAN(kSoftwareReporterPromptShownMetricName, true); +void RecordPromptShownWithTypeHistogram(PromptTypeHistogramValue value) { + UMA_HISTOGRAM_ENUMERATION("SoftwareReporter.PromptShownWithType", value, + PROMPT_TYPE_MAX); } void RecordPromptNotShownWithReasonHistogram( NoPromptReasonHistogramValue value) { - UMA_HISTOGRAM_BOOLEAN(kSoftwareReporterPromptShownMetricName, false); UMA_HISTOGRAM_ENUMERATION("SoftwareReporter.NoPromptReason", value, NO_PROMPT_REASON_MAX); }
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h index ff3c316..d75cdaea6d 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h +++ b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h
@@ -37,10 +37,21 @@ NO_PROMPT_REASON_BROWSER_NOT_AVAILABLE = 5, NO_PROMPT_REASON_NOT_ON_IDLE_STATE = 6, NO_PROMPT_REASON_IPC_CONNECTION_BROKEN = 7, + NO_PROMPT_REASON_WAITING_FOR_BROWSER = 8, NO_PROMPT_REASON_MAX, }; +// These values are used to send UMA information about the histogram type +// and are replicated in the histograms.xml file, so the order MUST NOT CHANGE. +enum PromptTypeHistogramValue { + PROMPT_TYPE_LEGACY_PROMPT_SHOWN = 0, + PROMPT_TYPE_ON_TRANSITION_TO_INFECTED_STATE = 1, + PROMPT_TYPE_ON_BROWSER_WINDOW_AVAILABLE = 2, + + PROMPT_TYPE_MAX, +}; + // When enabled, all user interaction with the Chrome Cleaner will happen from // within Chrome. extern const base::Feature kInBrowserCleanerUIFeature; @@ -66,8 +77,8 @@ // Records a value for the SRT Prompt Histogram. void RecordSRTPromptHistogram(SRTPromptHistogramValue value); -// Records a SoftwareReporter.PromptShown histogram with value true. -void RecordPromptShownHistogram(); +// Records a value for SoftwareReporter.PromptShownWithType Histogram +void RecordPromptShownWithTypeHistogram(PromptTypeHistogramValue value); // Records a SoftwareReporter.PromptShown histogram with value false and // a SoftwareReporter.NoPromptReason histogram with the reason corresponding
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/srt_global_error_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/srt_global_error_win.cc index afc8a40..a46d7015 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/srt_global_error_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/srt_global_error_win.cc
@@ -137,7 +137,8 @@ void SRTGlobalError::ShowBubbleView(Browser* browser) { RecordSRTPromptHistogram(SRT_PROMPT_SHOWN); - RecordPromptShownHistogram(); + RecordPromptShownWithTypeHistogram( + PromptTypeHistogramValue::PROMPT_TYPE_LEGACY_PROMPT_SHOWN); GlobalErrorWithStandardBubble::ShowBubbleView(browser); }
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc index 01e155a..6f8096cb 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" +#include "chrome/browser/sync/user_event_service_factory.h" #include "chrome/common/pref_names.h" #include "components/browser_sync/profile_sync_service.h" #include "components/content_settings/core/browser/host_content_settings_map.h" @@ -27,12 +28,17 @@ #include "components/signin/core/browser/account_info.h" #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/signin_manager.h" +#include "components/sync/protocol/user_event_specifics.pb.h" +#include "components/sync/user_events/user_event_service.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" using content::BrowserThread; +using sync_pb::UserEventSpecifics; +using SafeBrowsingStatus = UserEventSpecifics::SyncPasswordReuseEvent:: + PasswordReuseDetected::SafeBrowsingStatus; namespace safe_browsing { @@ -45,6 +51,10 @@ // for 2 days. const int kOverrideVerdictCacheDurationSec = 2 * 24 * 60 * 60; +int64_t GetMicrosecondsSinceWindowsEpoch(base::Time time) { + return (time - base::Time()).InMicroseconds(); +} + } // namespace ChromePasswordProtectionService::ChromePasswordProtectionService( @@ -96,24 +106,27 @@ SafeBrowsingNavigationObserverManager::ATTRIBUTION_FAILURE_TYPE_MAX); } +PrefService* ChromePasswordProtectionService::GetPrefs() { + return profile_->GetPrefs(); +} + +bool ChromePasswordProtectionService::IsSafeBrowsingEnabled() { + return GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled); +} + bool ChromePasswordProtectionService::IsExtendedReporting() { - return IsExtendedReportingEnabled(*profile_->GetPrefs()); + return IsExtendedReportingEnabled(*GetPrefs()); } bool ChromePasswordProtectionService::IsIncognito() { - DCHECK(profile_); return profile_->IsOffTheRecord(); } bool ChromePasswordProtectionService::IsPingingEnabled( const base::Feature& feature, RequestOutcome* reason) { - // Don't start pinging on an invalid profile, or if user turns off Safe - // Browsing service. - if (!profile_ || - !profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) { + if (!IsSafeBrowsingEnabled()) return false; - } DCHECK(feature.name == kProtectedPasswordEntryPinging.name || feature.name == kPasswordFieldOnFocusPinging.name); @@ -146,6 +159,48 @@ sync->GetActiveDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES); } +void ChromePasswordProtectionService::MaybeLogPasswordReuseDetectedEvent( + content::WebContents* web_contents) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + if (!base::FeatureList::IsEnabled(safe_browsing::kSyncPasswordReuseEvent)) + return; + + syncer::UserEventService* user_event_service = + browser_sync::UserEventServiceFactory::GetForProfile(profile_); + content::NavigationEntry* navigation = + web_contents->GetController().GetLastCommittedEntry(); + if (!user_event_service || !navigation) + return; + + auto specifics = base::MakeUnique<UserEventSpecifics>(); + specifics->set_event_time_usec( + GetMicrosecondsSinceWindowsEpoch(base::Time::Now())); + specifics->set_navigation_id( + GetMicrosecondsSinceWindowsEpoch(navigation->GetTimestamp())); + auto* const status = specifics->mutable_sync_password_reuse_event() + ->mutable_reuse_detected() + ->mutable_status(); + + status->set_enabled(IsSafeBrowsingEnabled()); + + safe_browsing::ExtendedReportingLevel erl = + safe_browsing::GetExtendedReportingLevel(*GetPrefs()); + switch (erl) { + case safe_browsing::SBER_LEVEL_OFF: + status->set_safe_browsing_reporting_population(SafeBrowsingStatus::NONE); + break; + case safe_browsing::SBER_LEVEL_LEGACY: + status->set_safe_browsing_reporting_population( + SafeBrowsingStatus::EXTENDED_REPORTING); + break; + case safe_browsing::SBER_LEVEL_SCOUT: + status->set_safe_browsing_reporting_population(SafeBrowsingStatus::SCOUT); + break; + } + user_event_service->RecordUserEvent(std::move(specifics)); +} + PasswordProtectionService::SyncAccountType ChromePasswordProtectionService::GetSyncAccountType() { DCHECK(profile_);
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.h b/chrome/browser/safe_browsing/chrome_password_protection_service.h index d954a04..5a22f4a 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.h +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.h
@@ -7,6 +7,7 @@ #include "components/safe_browsing/password_protection/password_protection_service.h" +class PrefService; class Profile; namespace content { @@ -50,6 +51,9 @@ // If user enabled history syncing. bool IsHistorySyncEnabled() override; + void MaybeLogPasswordReuseDetectedEvent( + content::WebContents* web_contents) override; + void ShowPhishingInterstitial(const GURL& phishing_url, const std::string& token, content::WebContents* web_contents) override; @@ -67,11 +71,21 @@ FRIEND_TEST_ALL_PREFIXES(ChromePasswordProtectionServiceTest, VerifyUserPopulationForProtectedPasswordEntryPing); FRIEND_TEST_ALL_PREFIXES(ChromePasswordProtectionServiceTest, + VerifyPasswordReuseUserEventNotRecorded); + FRIEND_TEST_ALL_PREFIXES(ChromePasswordProtectionServiceTest, + VerifyPasswordReuseUserEventRecorded); + FRIEND_TEST_ALL_PREFIXES(ChromePasswordProtectionServiceTest, VerifyGetSyncAccountType); FRIEND_TEST_ALL_PREFIXES(ChromePasswordProtectionServiceTest, VerifyUpdateSecurityState); private: + // Gets prefs associated with |profile_|. + PrefService* GetPrefs(); + + // Returns whether the profile is valid and has safe browsing service enabled. + bool IsSafeBrowsingEnabled(); + friend class MockChromePasswordProtectionService; // Constructor used for tests only. ChromePasswordProtectionService(
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc index f669e21d7..0a02e37 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/test_signin_client_builder.h" +#include "chrome/browser/sync/user_event_service_factory.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" @@ -28,6 +29,7 @@ #include "components/signin/core/browser/fake_account_fetcher_service.h" #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/browser/signin_manager_base.h" +#include "components/sync/user_events/fake_user_event_service.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "components/variations/variations_params_manager.h" #include "content/public/browser/web_contents.h" @@ -43,6 +45,11 @@ const char kTestAccountID[] = "account_id"; const char kTestEmail[] = "foo@example.com"; +std::unique_ptr<KeyedService> BuildFakeUserEventService( + content::BrowserContext* context) { + return base::MakeUnique<syncer::FakeUserEventService>(); +} + } // namespace class MockSafeBrowsingUIManager : public SafeBrowsingUIManager { @@ -123,6 +130,10 @@ profile(), content_setting_map_, new testing::StrictMock<MockSafeBrowsingUIManager>( SafeBrowsingService::CreateSafeBrowsingService())); + fake_user_event_service_ = static_cast<syncer::FakeUserEventService*>( + browser_sync::UserEventServiceFactory::GetInstance() + ->SetTestingFactoryAndUse(browser_context(), + &BuildFakeUserEventService)); } void TearDown() override { @@ -146,6 +157,14 @@ return builder.Build().release(); } + void EnableSyncPasswordReuseEvent() { + scoped_feature_list_.InitAndEnableFeature(kSyncPasswordReuseEvent); + } + + syncer::FakeUserEventService* GetUserEventService() { + return fake_user_event_service_; + } + void InitializeRequest(LoginReputationClientRequest::TriggerType type) { request_ = new PasswordProtectionRequest(web_contents(), GURL(kPhishingURL), GURL(), GURL(), std::string(), @@ -183,6 +202,8 @@ std::unique_ptr<MockChromePasswordProtectionService> service_; scoped_refptr<PasswordProtectionRequest> request_; std::unique_ptr<LoginReputationClientResponse> verdict_; + // Owned by KeyedServiceFactory. + syncer::FakeUserEventService* fake_user_event_service_; }; TEST_F(ChromePasswordProtectionServiceTest, @@ -332,4 +353,44 @@ service_->GetCachedVerdict( url, LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &verdict)); } + +TEST_F(ChromePasswordProtectionServiceTest, + VerifyPasswordReuseUserEventNotRecorded) { + // Feature not enabled. + service_->MaybeLogPasswordReuseDetectedEvent(web_contents()); + EXPECT_TRUE(GetUserEventService()->GetRecordedUserEvents().empty()); + + EnableSyncPasswordReuseEvent(); + // Feature enabled but no committed navigation entry. + service_->MaybeLogPasswordReuseDetectedEvent(web_contents()); + EXPECT_TRUE(GetUserEventService()->GetRecordedUserEvents().empty()); +} + +TEST_F(ChromePasswordProtectionServiceTest, + VerifyPasswordReuseUserEventRecorded) { + EnableSyncPasswordReuseEvent(); + NavigateAndCommit(GURL("https://www.example.com/")); + + // Case 1: safe_browsing_enabled = true + profile()->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled, true); + service_->MaybeLogPasswordReuseDetectedEvent(web_contents()); + ASSERT_EQ(1ul, GetUserEventService()->GetRecordedUserEvents().size()); + sync_pb::UserEventSpecifics::SyncPasswordReuseEvent event = + GetUserEventService() + ->GetRecordedUserEvents()[0] + .sync_password_reuse_event(); + EXPECT_TRUE(event.reuse_detected().status().enabled()); + + // Case 2: safe_browsing_enabled = false + profile()->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled, false); + service_->MaybeLogPasswordReuseDetectedEvent(web_contents()); + ASSERT_EQ(2ul, GetUserEventService()->GetRecordedUserEvents().size()); + event = GetUserEventService() + ->GetRecordedUserEvents()[1] + .sync_password_reuse_event(); + EXPECT_FALSE(event.reuse_detected().status().enabled()); + + // Not checking for the extended_reporting_level since that requires setting + // multiple prefs and doesn't add much verification value. +} } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/sandboxed_zip_analyzer_unittest.cc b/chrome/browser/safe_browsing/sandboxed_zip_analyzer_unittest.cc index 4b4cbe4e..a1a6f98e 100644 --- a/chrome/browser/safe_browsing/sandboxed_zip_analyzer_unittest.cc +++ b/chrome/browser/safe_browsing/sandboxed_zip_analyzer_unittest.cc
@@ -12,14 +12,24 @@ #include "base/macros.h" #include "base/path_service.h" #include "base/run_loop.h" +#include "base/test/histogram_tester.h" #include "build/build_config.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/safe_browsing/archive_analyzer_results.h" #include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_utils.h" #include "crypto/sha2.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#if defined(OS_MACOSX) +namespace { + +const char kAppInZipHistogramName[] = + "SBClientDownload.ZipFileContainsAppDirectory"; +} +#endif // OS_MACOSX + namespace safe_browsing { class SandboxedZipAnalyzerTest : public ::testing::Test { @@ -351,11 +361,18 @@ #if defined(OS_MACOSX) TEST_F(SandboxedZipAnalyzerTest, ZippedAppWithUnsignedAndSignedExecutable) { + base::HistogramTester histograms; + histograms.ExpectTotalCount(kAppInZipHistogramName, 0); + ArchiveAnalyzerResults results; RunAnalyzer(dir_test_data_.AppendASCII( "mach_o/zipped-app-two-executables-one-signed.zip"), &results); - ASSERT_TRUE(results.success); + + EXPECT_THAT(histograms.GetAllSamples(kAppInZipHistogramName), + testing::ElementsAre(base::Bucket(/*bucket=*/true, /*count=*/1))); + + EXPECT_TRUE(results.success); EXPECT_TRUE(results.has_executable); EXPECT_FALSE(results.has_archive); ASSERT_EQ(2, results.archived_binary.size());
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index b7d83d3..d76ff2b 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -676,8 +676,8 @@ "apps/chrome_app_window_client.h", "apps/directory_access_confirmation_dialog.cc", "apps/directory_access_confirmation_dialog.h", - "blocked_content/app_modal_dialog_helper.cc", - "blocked_content/app_modal_dialog_helper.h", + "blocked_content/popunder_preventer.cc", + "blocked_content/popunder_preventer.h", "bluetooth/bluetooth_chooser_controller.cc", "bluetooth/bluetooth_chooser_controller.h", "bluetooth/bluetooth_chooser_desktop.cc",
diff --git a/chrome/browser/ui/ash/ash_init.cc b/chrome/browser/ui/ash/ash_init.cc index 8786dc4..692ea91 100644 --- a/chrome/browser/ui/ash/ash_init.cc +++ b/chrome/browser/ui/ash/ash_init.cc
@@ -116,6 +116,10 @@ ash::Shell* shell = ash::Shell::Get(); + // Under mash the local state pref service isn't available until after shell + // initialization. Make classic ash behave the same way. + shell->SetLocalStatePrefService(g_browser_process->local_state()); + ash::AcceleratorControllerDelegateClassic* accelerator_controller_delegate = nullptr; if (chromeos::GetAshConfig() == ash::Config::CLASSIC) {
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index f3ab97f..af9d1a5 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -552,10 +552,6 @@ return profile ? profile->GetPrefs() : nullptr; } -PrefService* ChromeShellDelegate::GetLocalStatePrefService() const { - return g_browser_process->local_state(); -} - bool ChromeShellDelegate::IsTouchscreenEnabledInPrefs( bool use_local_state) const { return chromeos::system::InputDeviceSettings::Get()
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.h b/chrome/browser/ui/ash/chrome_shell_delegate.h index cd09deb..4cae06d 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.h +++ b/chrome/browser/ui/ash/chrome_shell_delegate.h
@@ -55,7 +55,6 @@ void OpenKeyboardShortcutHelpPage() const override; gfx::Image GetDeprecatedAcceleratorImage() const override; PrefService* GetActiveUserPrefService() const override; - PrefService* GetLocalStatePrefService() const override; bool IsTouchscreenEnabledInPrefs(bool use_local_state) const override; void SetTouchscreenEnabledInPrefs(bool enabled, bool use_local_state) override;
diff --git a/chrome/browser/ui/blocked_content/app_modal_dialog_helper.h b/chrome/browser/ui/blocked_content/app_modal_dialog_helper.h deleted file mode 100644 index c085d9f..0000000 --- a/chrome/browser/ui/blocked_content/app_modal_dialog_helper.h +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_BLOCKED_CONTENT_APP_MODAL_DIALOG_HELPER_H_ -#define CHROME_BROWSER_UI_BLOCKED_CONTENT_APP_MODAL_DIALOG_HELPER_H_ - -#include "base/macros.h" -#include "content/public/browser/web_contents_observer.h" - -// A helper for app modal dialogs that blocks creation of pop-unders. -class AppModalDialogHelper : public content::WebContentsObserver { - public: - explicit AppModalDialogHelper(content::WebContents* dialog_host); - ~AppModalDialogHelper() override; - - private: - // Overridden from WebContentsObserver: - void WebContentsDestroyed() override; - - content::WebContents* popup_; - - DISALLOW_COPY_AND_ASSIGN(AppModalDialogHelper); -}; - -#endif // CHROME_BROWSER_UI_BLOCKED_CONTENT_APP_MODAL_DIALOG_HELPER_H_
diff --git a/chrome/browser/ui/blocked_content/app_modal_dialog_helper.cc b/chrome/browser/ui/blocked_content/popunder_preventer.cc similarity index 85% rename from chrome/browser/ui/blocked_content/app_modal_dialog_helper.cc rename to chrome/browser/ui/blocked_content/popunder_preventer.cc index 5bbf2888..7cc1b00 100644 --- a/chrome/browser/ui/blocked_content/app_modal_dialog_helper.cc +++ b/chrome/browser/ui/blocked_content/popunder_preventer.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/blocked_content/app_modal_dialog_helper.h" +#include "chrome/browser/ui/blocked_content/popunder_preventer.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" @@ -16,7 +16,7 @@ #include "components/guest_view/browser/guest_view_base.h" #endif -AppModalDialogHelper::AppModalDialogHelper(content::WebContents* dialog_host) +PopunderPreventer::PopunderPreventer(content::WebContents* activating_contents) : popup_(nullptr) { // If a popup is the active window, and the WebContents that is going to be // activated is in the opener chain of that popup, then we suspect that @@ -32,12 +32,12 @@ if (!active_popup) return; - content::WebContents* actual_host = dialog_host; + content::WebContents* actual_host = activating_contents; #if BUILDFLAG(ENABLE_EXTENSIONS) // If the dialog was triggered via an PDF, get the actual web contents that // embeds the PDF. guest_view::GuestViewBase* guest = - guest_view::GuestViewBase::FromWebContents(dialog_host); + guest_view::GuestViewBase::FromWebContents(activating_contents); if (guest) actual_host = guest->embedder_web_contents(); #endif @@ -59,7 +59,7 @@ } } -AppModalDialogHelper::~AppModalDialogHelper() { +PopunderPreventer::~PopunderPreventer() { if (!popup_) return; @@ -70,6 +70,6 @@ delegate->ActivateContents(popup_); } -void AppModalDialogHelper::WebContentsDestroyed() { +void PopunderPreventer::WebContentsDestroyed() { popup_ = nullptr; }
diff --git a/chrome/browser/ui/blocked_content/popunder_preventer.h b/chrome/browser/ui/blocked_content/popunder_preventer.h new file mode 100644 index 0000000..5d7a3fac --- /dev/null +++ b/chrome/browser/ui/blocked_content/popunder_preventer.h
@@ -0,0 +1,30 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_BLOCKED_CONTENT_POPUNDER_PREVENTER_H_ +#define CHROME_BROWSER_UI_BLOCKED_CONTENT_POPUNDER_PREVENTER_H_ + +#include "base/macros.h" +#include "content/public/browser/web_contents_observer.h" + +// An object to block creation of pop-unders. +// +// This must be used whenever a window is activated. To use it, simply +// create an instance of PopunderPreventer *before* a WebContents is activated, +// and pass to the constructor the WebContents that is about to be activated. +class PopunderPreventer : public content::WebContentsObserver { + public: + explicit PopunderPreventer(content::WebContents* activating_contents); + ~PopunderPreventer() override; + + private: + // Overridden from WebContentsObserver: + void WebContentsDestroyed() override; + + content::WebContents* popup_; + + DISALLOW_COPY_AND_ASSIGN(PopunderPreventer); +}; + +#endif // CHROME_BROWSER_UI_BLOCKED_CONTENT_POPUNDER_PREVENTER_H_
diff --git a/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.h b/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.h index f364484e..04a258a 100644 --- a/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.h +++ b/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.h
@@ -12,7 +12,7 @@ #include "base/macros.h" #include "components/app_modal/native_app_modal_dialog.h" -class AppModalDialogHelper; +class PopunderPreventer; namespace app_modal { class JavaScriptAppModalDialog; @@ -50,7 +50,7 @@ NSAlert* GetAlert() const; std::unique_ptr<app_modal::JavaScriptAppModalDialog> dialog_; - std::unique_ptr<AppModalDialogHelper> popup_helper_; + std::unique_ptr<PopunderPreventer> popunder_preventer_; // Created in the constructor and destroyed in the destructor. base::scoped_nsobject<JavaScriptAppModalDialogHelper> helper_;
diff --git a/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.mm b/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.mm index 0e56c98..5566c214 100644 --- a/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.mm +++ b/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.mm
@@ -14,7 +14,7 @@ #include "base/memory/ptr_util.h" #include "base/strings/sys_string_conversions.h" #import "chrome/browser/chrome_browser_application_mac.h" -#include "chrome/browser/ui/blocked_content/app_modal_dialog_helper.h" +#include "chrome/browser/ui/blocked_content/popunder_preventer.h" #include "chrome/browser/ui/javascript_dialogs/chrome_javascript_native_dialog_factory.h" #include "components/app_modal/javascript_app_modal_dialog.h" #include "components/app_modal/javascript_dialog_manager.h" @@ -229,7 +229,7 @@ JavaScriptAppModalDialogCocoa::JavaScriptAppModalDialogCocoa( app_modal::JavaScriptAppModalDialog* dialog) : dialog_(dialog), - popup_helper_(new AppModalDialogHelper(dialog->web_contents())), + popunder_preventer_(new PopunderPreventer(dialog->web_contents())), is_showing_(false) { // Determine the names of the dialog buttons based on the flags. "Default" // is the OK button. "Other" is the cancel button. We don't use the
diff --git a/chrome/browser/ui/extensions/extension_installed_notification.cc b/chrome/browser/ui/extensions/extension_installed_notification.cc index e424177..ddc513d 100644 --- a/chrome/browser/ui/extensions/extension_installed_notification.cc +++ b/chrome/browser/ui/extensions/extension_installed_notification.cc
@@ -12,13 +12,14 @@ #include "chrome/browser/ui/extensions/app_launch_params.h" #include "chrome/browser/ui/extensions/application_launch.h" #include "chrome/grit/generated_resources.h" -#include "chrome/grit/theme_resources.h" +#include "components/vector_icons/vector_icons.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" #include "extensions/common/extension_urls.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/color_palette.h" +#include "ui/gfx/paint_vector_icon.h" namespace { const char* kNotifierId = "app.downloaded-notification"; @@ -46,10 +47,10 @@ message_center::NOTIFICATION_TYPE_SIMPLE, base::UTF8ToUTF16(extension->name()), l10n_util::GetStringUTF16(IDS_EXTENSION_NOTIFICATION_INSTALLED), - ui::ResourceBundle::GetSharedInstance().GetImageNamed( - IDR_NOTIFICATION_EXTENSION_INSTALLED), - message_center::NotifierId( - message_center::NotifierId::SYSTEM_COMPONENT, kNotifierId), + gfx::Image(gfx::CreateVectorIcon(vector_icons::kCheckCircleIcon, 40, + gfx::kGoogleGreen700)), + message_center::NotifierId(message_center::NotifierId::SYSTEM_COMPONENT, + kNotifierId), base::string16() /* display_source */, GURL(extension_urls::kChromeWebstoreBaseURL) /* origin_url */, kNotificationId, optional_field, this));
diff --git a/chrome/browser/ui/javascript_dialogs/javascript_dialog.cc b/chrome/browser/ui/javascript_dialogs/javascript_dialog.cc index 4151a826..340a124 100644 --- a/chrome/browser/ui/javascript_dialogs/javascript_dialog.cc +++ b/chrome/browser/ui/javascript_dialogs/javascript_dialog.cc
@@ -4,13 +4,13 @@ #include "chrome/browser/ui/javascript_dialogs/javascript_dialog.h" -#include "chrome/browser/ui/blocked_content/app_modal_dialog_helper.h" +#include "chrome/browser/ui/blocked_content/popunder_preventer.h" #include "chrome/browser/ui/javascript_dialogs/javascript_dialog_views.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" JavaScriptDialog::JavaScriptDialog(content::WebContents* parent_web_contents) { - dialog_helper_.reset(new AppModalDialogHelper(parent_web_contents)); + popunder_preventer_.reset(new PopunderPreventer(parent_web_contents)); parent_web_contents->GetDelegate()->ActivateContents(parent_web_contents); }
diff --git a/chrome/browser/ui/javascript_dialogs/javascript_dialog.h b/chrome/browser/ui/javascript_dialogs/javascript_dialog.h index 684f550..53b5029 100644 --- a/chrome/browser/ui/javascript_dialogs/javascript_dialog.h +++ b/chrome/browser/ui/javascript_dialogs/javascript_dialog.h
@@ -10,7 +10,7 @@ #include "base/memory/weak_ptr.h" #include "content/public/browser/javascript_dialog_manager.h" -class AppModalDialogHelper; +class PopunderPreventer; class JavaScriptDialog { public: @@ -39,7 +39,7 @@ explicit JavaScriptDialog(content::WebContents* parent_web_contents); private: - std::unique_ptr<AppModalDialogHelper> dialog_helper_; + std::unique_ptr<PopunderPreventer> popunder_preventer_; }; #endif // CHROME_BROWSER_UI_JAVASCRIPT_DIALOGS_JAVASCRIPT_DIALOG_H_
diff --git a/chrome/browser/ui/javascript_dialogs/javascript_dialog_mac.cc b/chrome/browser/ui/javascript_dialogs/javascript_dialog_mac.cc index 3865f91a..1bc3cf1 100644 --- a/chrome/browser/ui/javascript_dialogs/javascript_dialog_mac.cc +++ b/chrome/browser/ui/javascript_dialogs/javascript_dialog_mac.cc
@@ -4,7 +4,7 @@ #include "chrome/browser/ui/javascript_dialogs/javascript_dialog.h" -#include "chrome/browser/ui/blocked_content/app_modal_dialog_helper.h" +#include "chrome/browser/ui/blocked_content/popunder_preventer.h" #include "chrome/browser/ui/javascript_dialogs/javascript_dialog_cocoa.h" #include "chrome/browser/ui/javascript_dialogs/javascript_dialog_views.h" #include "content/public/browser/web_contents.h" @@ -12,7 +12,7 @@ #include "ui/base/material_design/material_design_controller.h" JavaScriptDialog::JavaScriptDialog(content::WebContents* parent_web_contents) { - dialog_helper_.reset(new AppModalDialogHelper(parent_web_contents)); + popunder_preventer_.reset(new PopunderPreventer(parent_web_contents)); parent_web_contents->GetDelegate()->ActivateContents(parent_web_contents); }
diff --git a/chrome/browser/ui/login/login_handler.cc b/chrome/browser/ui/login/login_handler.cc index 18081f4..813f99f 100644 --- a/chrome/browser/ui/login/login_handler.cc +++ b/chrome/browser/ui/login/login_handler.cc
@@ -51,7 +51,7 @@ #endif #if !defined(OS_ANDROID) -#include "chrome/browser/ui/blocked_content/app_modal_dialog_helper.h" +#include "chrome/browser/ui/blocked_content/popunder_preventer.h" #endif using autofill::PasswordForm; @@ -338,7 +338,7 @@ #if !defined(OS_ANDROID) WebContents* requesting_contents = GetWebContentsForLogin(); if (requesting_contents) - dialog_helper_.reset(new AppModalDialogHelper(requesting_contents)); + popunder_preventer_.reset(new PopunderPreventer(requesting_contents)); #endif } @@ -449,7 +449,7 @@ if (interstitial_delegate_) interstitial_delegate_->Proceed(); #if !defined(OS_ANDROID) - dialog_helper_.reset(); + popunder_preventer_.reset(); #endif }
diff --git a/chrome/browser/ui/login/login_handler.h b/chrome/browser/ui/login/login_handler.h index 8d5973f9..4d3142c 100644 --- a/chrome/browser/ui/login/login_handler.h +++ b/chrome/browser/ui/login/login_handler.h
@@ -17,9 +17,9 @@ #include "content/public/browser/resource_dispatcher_host_login_delegate.h" #include "content/public/browser/resource_request_info.h" -class AppModalDialogHelper; class GURL; class LoginInterstitialDelegate; +class PopunderPreventer; namespace content { class NotificationRegistrar; @@ -247,7 +247,7 @@ base::WeakPtr<LoginInterstitialDelegate> interstitial_delegate_; #if !defined(OS_ANDROID) - std::unique_ptr<AppModalDialogHelper> dialog_helper_; + std::unique_ptr<PopunderPreventer> popunder_preventer_; #endif };
diff --git a/chrome/browser/ui/page_info/page_info_ui.cc b/chrome/browser/ui/page_info/page_info_ui.cc index ac53c088..45f7ea7 100644 --- a/chrome/browser/ui/page_info/page_info_ui.cc +++ b/chrome/browser/ui/page_info/page_info_ui.cc
@@ -305,7 +305,7 @@ return use_blocked ? info.blocked_icon_id : info.allowed_icon_id; } NOTREACHED(); - return IDR_INFO; + return 0; } // static
diff --git a/chrome/browser/ui/views/chrome_javascript_native_dialog_factory_views.cc b/chrome/browser/ui/views/chrome_javascript_native_dialog_factory_views.cc index 39adfd8d..46b25f5f 100644 --- a/chrome/browser/ui/views/chrome_javascript_native_dialog_factory_views.cc +++ b/chrome/browser/ui/views/chrome_javascript_native_dialog_factory_views.cc
@@ -16,7 +16,7 @@ #if defined(USE_X11) && !defined(OS_CHROMEOS) #include "chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.h" #else -#include "chrome/browser/ui/blocked_content/app_modal_dialog_helper.h" +#include "chrome/browser/ui/blocked_content/popunder_preventer.h" #include "components/app_modal/javascript_app_modal_dialog.h" #include "components/app_modal/views/javascript_app_modal_dialog_views.h" #endif @@ -34,11 +34,11 @@ explicit ChromeJavaScriptAppModalDialogViews( app_modal::JavaScriptAppModalDialog* parent) : app_modal::JavaScriptAppModalDialogViews(parent), - helper_(new AppModalDialogHelper(parent->web_contents())) {} + popunder_preventer_(new PopunderPreventer(parent->web_contents())) {} ~ChromeJavaScriptAppModalDialogViews() override {} private: - std::unique_ptr<AppModalDialogHelper> helper_; + std::unique_ptr<PopunderPreventer> popunder_preventer_; DISALLOW_COPY_AND_ASSIGN(ChromeJavaScriptAppModalDialogViews); };
diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc index 1f9e404..b45cd14 100644 --- a/chrome/browser/ui/views/collected_cookies_views.cc +++ b/chrome/browser/ui/views/collected_cookies_views.cc
@@ -25,20 +25,21 @@ #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" -#include "chrome/grit/theme_resources.h" #include "components/constrained_window/constrained_window_views.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/common/pref_names.h" #include "components/prefs/pref_service.h" #include "components/strings/grit/components_strings.h" +#include "components/vector_icons/vector_icons.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/web_contents.h" #include "net/cookies/canonical_cookie.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/color_palette.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/geometry/insets.h" +#include "ui/gfx/paint_vector_icon.h" #include "ui/views/border.h" #include "ui/views/controls/button/md_text_button.h" #include "ui/views/controls/image_view.h" @@ -99,9 +100,9 @@ content_->SetBorder( views::CreateSolidBorder(kInfobarBorderSize, border_color)); - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); info_image_ = new views::ImageView(); - info_image_->SetImage(rb.GetImageSkiaNamed(IDR_INFO)); + info_image_->SetImage(gfx::CreateVectorIcon(vector_icons::kInfoOutlineIcon, + 16, gfx::kChromeIconGrey)); label_ = new views::Label(); } ~InfobarView() override {}
diff --git a/chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.cc b/chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.cc index 3c447617..1f6beca 100644 --- a/chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.cc +++ b/chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.cc
@@ -4,7 +4,7 @@ #include "chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.h" -#include "chrome/browser/ui/blocked_content/app_modal_dialog_helper.h" +#include "chrome/browser/ui/blocked_content/popunder_preventer.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/views/javascript_app_modal_event_blocker_x11.h" #include "components/app_modal/javascript_app_modal_dialog.h" @@ -13,7 +13,7 @@ JavaScriptAppModalDialogViewsX11::JavaScriptAppModalDialogViewsX11( app_modal::JavaScriptAppModalDialog* parent) : app_modal::JavaScriptAppModalDialogViews(parent), - helper_(new AppModalDialogHelper(parent->web_contents())) { + popunder_preventer_(new PopunderPreventer(parent->web_contents())) { chrome::RecordDialogCreation( chrome::DialogIdentifier::JAVA_SCRIPT_APP_MODAL_X11); }
diff --git a/chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.h b/chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.h index 9dc99479..38da771 100644 --- a/chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.h +++ b/chrome/browser/ui/views/javascript_app_modal_dialog_views_x11.h
@@ -10,8 +10,8 @@ #include "base/macros.h" #include "components/app_modal/views/javascript_app_modal_dialog_views.h" -class AppModalDialogHelper; class JavascriptAppModalEventBlockerX11; +class PopunderPreventer; // JavaScriptAppModalDialog implmentation for linux desktop. class JavaScriptAppModalDialogViewsX11 @@ -31,7 +31,7 @@ // Blocks events to other browser windows while the dialog is open. std::unique_ptr<JavascriptAppModalEventBlockerX11> event_blocker_x11_; - std::unique_ptr<AppModalDialogHelper> helper_; + std::unique_ptr<PopunderPreventer> popunder_preventer_; DISALLOW_COPY_AND_ASSIGN(JavaScriptAppModalDialogViewsX11); };
diff --git a/chrome/browser/usb/web_usb_detector.cc b/chrome/browser/usb/web_usb_detector.cc index b084af60..193d6e0 100644 --- a/chrome/browser/usb/web_usb_detector.cc +++ b/chrome/browser/usb/web_usb_detector.cc
@@ -20,7 +20,7 @@ #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/grit/generated_resources.h" -#include "chrome/grit/theme_resources.h" +#include "components/vector_icons/vector_icons.h" #include "content/public/browser/web_contents.h" #include "content/public/common/origin_util.h" #include "device/base/device_client.h" @@ -29,9 +29,10 @@ #include "device/usb/usb_ids.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/page_transition_types.h" -#include "ui/base/resource/resource_bundle.h" #include "ui/base/window_open_disposition.h" +#include "ui/gfx/color_palette.h" #include "ui/gfx/image/image.h" +#include "ui/gfx/paint_vector_icon.h" #include "ui/message_center/message_center.h" #include "ui/message_center/notification.h" #include "ui/message_center/notification_delegate.h" @@ -212,7 +213,6 @@ std::string notification_id = device->guid(); - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); message_center::RichNotificationData rich_notification_data; std::unique_ptr<message_center::Notification> notification( new message_center::Notification( @@ -222,8 +222,9 @@ l10n_util::GetStringFUTF16( IDS_WEBUSB_DEVICE_DETECTED_NOTIFICATION, base::UTF8ToUTF16(landing_page.GetContent())), - rb.GetNativeImageNamed(IDR_USB_NOTIFICATION_ICON), base::string16(), - GURL(), + gfx::Image(gfx::CreateVectorIcon(vector_icons::kUsbIcon, 64, + gfx::kChromeIconGrey)), + base::string16(), GURL(), message_center::NotifierId( message_center::NotifierId::SYSTEM_COMPONENT, kNotifierWebUsb), rich_notification_data,
diff --git a/chrome/common/safe_browsing/zip_analyzer.cc b/chrome/common/safe_browsing/zip_analyzer.cc index 4c8707a..0d31d080 100644 --- a/chrome/common/safe_browsing/zip_analyzer.cc +++ b/chrome/common/safe_browsing/zip_analyzer.cc
@@ -13,6 +13,7 @@ #include "base/i18n/streaming_utf8_validator.h" #include "base/logging.h" #include "base/macros.h" +#include "base/metrics/histogram_macros.h" #include "build/build_config.h" #include "chrome/common/safe_browsing/archive_analyzer_results.h" #include "chrome/common/safe_browsing/binary_feature_extractor.h" @@ -127,6 +128,9 @@ } bool advanced = true; +#if defined(OS_MACOSX) + bool zip_has_app_directory = false; +#endif // OS_MACOSX for (; reader.HasMore(); advanced = reader.AdvanceToNextEntry()) { if (!advanced) { DVLOG(1) << "Could not advance to next entry, aborting zip scan."; @@ -167,6 +171,7 @@ // to fail. if (file.Extension().compare(".app") == 0) { DVLOG(2) << "Downloaded a zipped .app directory: " << file.value(); + zip_has_app_directory = true; } else { #endif // OS_MACOSX DVLOG(2) << "Downloaded a zipped executable: " << file.value(); @@ -180,6 +185,12 @@ DVLOG(3) << "Ignoring non-binary file: " << file.value(); } } +#if defined(OS_MACOSX) + UMA_HISTOGRAM_BOOLEAN( + "SBClientDownload." + "ZipFileContainsAppDirectory", + zip_has_app_directory); +#endif // OS_MACOSX results->archived_archive_filenames.assign(archived_archive_filenames.begin(), archived_archive_filenames.end()); results->success = true;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 7cf8adc..a28f42b9 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1998,6 +1998,7 @@ "../browser/extensions/webstore_reinstaller_browsertest.cc", "../browser/extensions/webstore_startup_installer_browsertest.cc", "../browser/extensions/window_open_apitest.cc", + "../browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_browsertest_win.cc", "../browser/safe_browsing/chrome_cleaner/settings_resetter_browsertest_win.cc", "../browser/safe_browsing/settings_reset_prompt/default_settings_fetcher_browsertest.cc", "../browser/safe_browsing/settings_reset_prompt/settings_reset_dependency_browsertest_win.cc",
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index 0b9f30b2..2249fbd 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -75,6 +75,11 @@ _VERSION_SPECIFIC_FILTER['HEAD'] = [ # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1819 'ChromeExtensionsCapabilityTest.testIFrameWithExtensionsSource', + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1918 + 'ChromeDriverTest.testWindowPosition', + 'ChromeDriverTest.testWindowSize', + 'ChromeLoggingCapabilityTest.testPerformanceLogger', + 'MobileEmulationCapabilityTest.testDeviceMetricsWithStandardWidth', ] _VERSION_SPECIFIC_FILTER['61'] = [ # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1819
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index abdc1fa..676754f 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -137,6 +137,16 @@ 'CombinedInputActionsTest.testMouseMovementWorksWhenNavigatingToAnotherPage', # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1138 'AlertsTest.testSettingTheValueOfAnAlertThrows', + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1910 + 'AlertsTest.testPromptShouldUseDefaultValueIfNoKeysSent', + 'UnexpectedAlertBehaviorTest.canAcceptUnhandledAlert', + 'UnexpectedAlertBehaviorTest.canSpecifyUnhandledAlertBehaviourUsingCapabilities', + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1918 + 'WindowTest.testGetsThePositionOfTheCurrentWindow', + 'WindowTest.testGetsTheSizeOfTheCurrentWindow', + 'WindowTest.testSetsThePositionOfTheCurrentWindow', + 'WindowTest.testSetsTheSizeOfTheCurrentWindowFromIframe', + 'WindowTest.testSetsTheSizeOfTheCurrentWindowFromFrame', ] _OS_NEGATIVE_FILTER = {}
diff --git a/chrome/test/data/webui/extensions/cr_extensions_browsertest.js b/chrome/test/data/webui/extensions/cr_extensions_browsertest.js index 5a20726..2fdd0337 100644 --- a/chrome/test/data/webui/extensions/cr_extensions_browsertest.js +++ b/chrome/test/data/webui/extensions/cr_extensions_browsertest.js
@@ -17,182 +17,148 @@ /** * Basic test fixture for the MD chrome://extensions page. Installs no * extensions. - * @constructor - * @extends {PolymerTest} */ -function CrExtensionsBrowserTest() {} - -CrExtensionsBrowserTest.prototype = { - __proto__: PolymerTest.prototype, +var CrExtensionsBrowserTest = class extends PolymerTest { + /** @override */ + get browsePreload() { + return 'chrome://extensions/'; + } /** @override */ - browsePreload: 'chrome://extensions/', + get commandLineSwitches() { + return [{ + switchName: 'enable-features', + switchValue: 'MaterialDesignExtensions', + }]; + } /** @override */ - commandLineSwitches: [{ - switchName: 'enable-features', - switchValue: 'MaterialDesignExtensions', - }], + get extraLibraries() { + return PolymerTest.getLibraries(ROOT_PATH).concat([ + ROOT_PATH + 'ui/webui/resources/js/assert.js', + 'extension_test_util.js', + '../mock_controller.js', + '../../../../../ui/webui/resources/js/promise_resolver.js', + '../../../../../ui/webui/resources/js/webui_resource_test.js', + ]); + } /** @override */ - extraLibraries: PolymerTest.getLibraries(ROOT_PATH).concat([ - ROOT_PATH + 'ui/webui/resources/js/assert.js', - 'extension_test_util.js', - '../mock_controller.js', - '../../../../../ui/webui/resources/js/promise_resolver.js', - '../../../../../ui/webui/resources/js/webui_resource_test.js', - ]), - - /** @override */ - typedefCppFixture: 'ExtensionSettingsUIBrowserTest', + get typedefCppFixture() { + return 'ExtensionSettingsUIBrowserTest'; + } }; /** * Test fixture with one installed extension. - * @constructor - * @extends {CrExtensionsBrowserTest} */ -function CrExtensionsBrowserTestWithInstalledExtension() {} - -CrExtensionsBrowserTestWithInstalledExtension.prototype = { - __proto__: CrExtensionsBrowserTest.prototype, - +var CrExtensionsBrowserTestWithInstalledExtension = + class extends CrExtensionsBrowserTest { /** @override */ - testGenPreamble: function() { + testGenPreamble() { GEN(' InstallGoodExtension();'); GEN(' SetAutoConfirmUninstall();'); - }, + } }; //////////////////////////////////////////////////////////////////////////////// // Extension Sidebar Tests -/** - * @constructor - * @extends {CrExtensionsBrowserTest} - */ -function CrExtensionsSidebarTest() {} - -CrExtensionsSidebarTest.prototype = { - __proto__: CrExtensionsBrowserTest.prototype, - +var CrExtensionsSidebarTest = class extends CrExtensionsBrowserTest { /** @override */ - extraLibraries: CrExtensionsBrowserTest.prototype.extraLibraries.concat([ - 'extension_sidebar_test.js', - ]), + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_sidebar_test.js', + ]); + } }; -TEST_F( - 'CrExtensionsSidebarTest', 'ExtensionSidebarLayoutAndClickHandlersTest', - function() { - mocha - .grep( - assert(extension_sidebar_tests.TestNames.LayoutAndClickHandlers)) - .run(); - }); +TEST_F('CrExtensionsSidebarTest', 'LayoutAndClickHandlers', function() { + mocha.grep(assert(extension_sidebar_tests.TestNames.LayoutAndClickHandlers)) + .run(); +}); //////////////////////////////////////////////////////////////////////////////// // Extension Toolbar Tests -/** - * @constructor - * @extends {CrExtensionsBrowserTest} - */ -function CrExtensionsToolbarTest() {} - -CrExtensionsToolbarTest.prototype = { - __proto__: CrExtensionsBrowserTest.prototype, - +var CrExtensionsToolbarTest = class extends CrExtensionsBrowserTest { /** @override */ - extraLibraries: CrExtensionsBrowserTest.prototype.extraLibraries.concat([ - 'extension_toolbar_test.js', - ]), + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_toolbar_test.js', + ]); + } }; -TEST_F('CrExtensionsToolbarTest', 'ExtensionToolbarLayoutTest', function() { +TEST_F('CrExtensionsToolbarTest', 'Layout', function() { mocha.grep(assert(extension_toolbar_tests.TestNames.Layout)).run(); }); -TEST_F( - 'CrExtensionsToolbarTest', 'ExtensionToolbarClickHandlersTest', function() { - mocha.grep(assert(extension_toolbar_tests.TestNames.ClickHandlers)).run(); - }); +TEST_F('CrExtensionsToolbarTest', 'ClickHandlers', function() { + mocha.grep(assert(extension_toolbar_tests.TestNames.ClickHandlers)).run(); +}); //////////////////////////////////////////////////////////////////////////////// // Extension Item Tests -/** - * @constructor - * @extends {CrExtensionsBrowserTest} - */ -function CrExtensionsItemsTest() {} - -CrExtensionsItemsTest.prototype = { - __proto__: CrExtensionsBrowserTest.prototype, - +var CrExtensionsItemsTest = class extends CrExtensionsBrowserTest { /** @override */ - extraLibraries: CrExtensionsBrowserTest.prototype.extraLibraries.concat([ - 'extension_item_test.js', - ]), + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_item_test.js', + ]); + } }; -TEST_F('CrExtensionsItemsTest', 'ExtensionItemNormalStateTest', function() { +TEST_F('CrExtensionsItemsTest', 'NormalState', function() { var TestNames = extension_item_tests.TestNames; mocha.grep(assert(TestNames.ElementVisibilityNormalState)).run(); }); -TEST_F('CrExtensionsItemsTest', 'ExtensionItemDeveloperStateTest', function() { +TEST_F('CrExtensionsItemsTest', 'DeveloperState', function() { var TestNames = extension_item_tests.TestNames; mocha.grep(assert(TestNames.ElementVisibilityDeveloperState)).run(); }); -TEST_F('CrExtensionsItemsTest', 'ExtensionItemClickableItemsTest', function() { +TEST_F('CrExtensionsItemsTest', 'ClickableItems', function() { var TestNames = extension_item_tests.TestNames; mocha.grep(assert(TestNames.ClickableItems)).run(); }); -TEST_F('CrExtensionsItemsTest', 'ExtensionItemWarningsTest', function() { +TEST_F('CrExtensionsItemsTest', 'Warnings', function() { mocha.grep(assert(extension_item_tests.TestNames.Warnings)).run(); }); -TEST_F('CrExtensionsItemsTest', 'ExtensionItemSourceIndicatorTest', function() { +TEST_F('CrExtensionsItemsTest', 'SourceIndicator', function() { mocha.grep(assert(extension_item_tests.TestNames.SourceIndicator)).run(); }); -TEST_F('CrExtensionsItemsTest', 'ExtensionItemEnableToggleTest', function() { +TEST_F('CrExtensionsItemsTest', 'EnableToggle', function() { mocha.grep(assert(extension_item_tests.TestNames.EnableToggle)).run(); }); -TEST_F('CrExtensionsItemsTest', 'ExtensionItemRemoveButtonTest', function() { +TEST_F('CrExtensionsItemsTest', 'RemoveButton', function() { mocha.grep(assert(extension_item_tests.TestNames.RemoveButton)).run(); }); //////////////////////////////////////////////////////////////////////////////// // Extension Detail View Tests -/** - * @constructor - * @extends {CrExtensionsBrowserTest} - */ -function CrExtensionsDetailViewTest() {} - -CrExtensionsDetailViewTest.prototype = { - __proto__: CrExtensionsBrowserTest.prototype, - +var CrExtensionsDetailViewTest = class extends CrExtensionsBrowserTest { /** @override */ - extraLibraries: CrExtensionsBrowserTest.prototype.extraLibraries.concat([ - 'extension_detail_view_test.js', - ]), + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_detail_view_test.js', + ]); + } }; -TEST_F( - 'CrExtensionsDetailViewTest', 'ExtensionDetailViewLayoutTest', function() { - mocha.grep(assert(extension_detail_view_tests.TestNames.Layout)).run(); - }); +TEST_F('CrExtensionsDetailViewTest', 'Layout', function() { + mocha.grep(assert(extension_detail_view_tests.TestNames.Layout)).run(); +}); TEST_F( - 'CrExtensionsDetailViewTest', 'ExtensionDetailViewClickableElementsTest', - function() { + 'CrExtensionsDetailViewTest', 'ClickableElements', function() { mocha .grep(assert(extension_detail_view_tests.TestNames.ClickableElements)) .run(); @@ -201,246 +167,183 @@ //////////////////////////////////////////////////////////////////////////////// // Extension Item List Tests -/** - * @constructor - * @extends {CrExtensionsBrowserTest} - */ -function CrExtensionsItemListTest() {} - -CrExtensionsItemListTest.prototype = { - __proto__: CrExtensionsBrowserTest.prototype, - +var CrExtensionsItemListTest = class extends CrExtensionsBrowserTest { /** @override */ - extraLibraries: CrExtensionsBrowserTest.prototype.extraLibraries.concat([ - 'extension_item_list_test.js', - ]), + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_item_list_test.js', + ]); + } }; -TEST_F('CrExtensionsItemListTest', 'ExtensionItemList', function() { - mocha.grep( - assert(extension_item_list_tests.TestNames.ItemListFiltering)).run(); +TEST_F('CrExtensionsItemListTest', 'Filtering', function() { + mocha.grep(assert(extension_item_list_tests.TestNames.Filtering)).run(); }); -TEST_F('CrExtensionsItemListTest', 'ExtensionItemListEmpty', function() { - mocha.grep(assert(extension_item_list_tests.TestNames.ItemListNoItemsMsg)) +TEST_F('CrExtensionsItemListTest', 'NoItems', function() { + mocha.grep(assert(extension_item_list_tests.TestNames.NoItemsMsg)).run(); +}); + +TEST_F('CrExtensionsItemListTest', 'NoSearchResults', function() { + mocha.grep(assert(extension_item_list_tests.TestNames.NoSearchResultsMsg)) .run(); }); -TEST_F( - 'CrExtensionsItemListTest', 'ExtensionItemListNoSearchResults', function() { - mocha - .grep(assert( - extension_item_list_tests.TestNames.ItemListNoSearchResultsMsg)) - .run(); - }); - //////////////////////////////////////////////////////////////////////////////// // Extension Load Error Tests -/** - * @constructor - * @extends {CrExtensionsBrowserTest} - */ -function CrExtensionsLoadErrorTest() {} - -CrExtensionsLoadErrorTest.prototype = { - __proto__: CrExtensionsBrowserTest.prototype, - +var CrExtensionsLoadErrorTest = class extends CrExtensionsBrowserTest { /** @override */ - extraLibraries: CrExtensionsBrowserTest.prototype.extraLibraries.concat([ - 'extension_load_error_test.js', - ]), + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_load_error_test.js', + ]); + } }; -TEST_F( - 'CrExtensionsLoadErrorTest', 'ExtensionLoadErrorInteractionTest', - function() { - mocha.grep(assert(extension_load_error_tests.TestNames.Interaction)) - .run(); - }); +TEST_F('CrExtensionsLoadErrorTest', 'Interaction', function() { + mocha.grep(assert(extension_load_error_tests.TestNames.Interaction)).run(); +}); -TEST_F( - 'CrExtensionsLoadErrorTest', 'ExtensionLoadErrorCodeSectionTest', - function() { - mocha.grep(assert(extension_load_error_tests.TestNames.CodeSection)) - .run(); - }); +TEST_F('CrExtensionsLoadErrorTest', 'CodeSection', function() { + mocha.grep(assert(extension_load_error_tests.TestNames.CodeSection)).run(); +}); //////////////////////////////////////////////////////////////////////////////// // Extension Service Tests -/** - * @constructor - * @extends {CrExtensionsBrowserTestWithInstalledExtension} - */ -function CrExtensionsServiceTest() {} - -CrExtensionsServiceTest.prototype = { - __proto__: CrExtensionsBrowserTestWithInstalledExtension.prototype, - +var CrExtensionsServiceTest = + class extends CrExtensionsBrowserTestWithInstalledExtension { /** @override */ - extraLibraries: CrExtensionsBrowserTestWithInstalledExtension.prototype - .extraLibraries.concat([ - 'extension_service_test.js', - ]), + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_service_test.js', + ]); + } }; -TEST_F( - 'CrExtensionsServiceTest', 'ExtensionServiceToggleEnableTest', function() { - mocha.grep(assert(extension_service_tests.TestNames.EnableAndDisable)) - .run(); - }); +TEST_F('CrExtensionsServiceTest', 'ToggleEnable', function() { + mocha.grep(assert(extension_service_tests.TestNames.EnableAndDisable)).run(); +}); TEST_F( - 'CrExtensionsServiceTest', 'ExtensionServiceToggleIncognitoTest', - function() { + 'CrExtensionsServiceTest', 'ToggleIncognito', function() { mocha.grep(assert(extension_service_tests.TestNames.ToggleIncognitoMode)) .run(); }); -TEST_F('CrExtensionsServiceTest', 'ExtensionServiceUninstallTest', function() { +TEST_F('CrExtensionsServiceTest', 'Uninstall', function() { mocha.grep(assert(extension_service_tests.TestNames.Uninstall)).run(); }); -TEST_F( - 'CrExtensionsServiceTest', 'ExtensionServiceProfileSettingsTest', - function() { - mocha.grep(assert(extension_service_tests.TestNames.ProfileSettings)) - .run(); - }); +TEST_F('CrExtensionsServiceTest', 'ProfileSettings', function() { + mocha.grep(assert(extension_service_tests.TestNames.ProfileSettings)).run(); +}); //////////////////////////////////////////////////////////////////////////////// // Extension Manager Tests -/** - * @constructor - * @extends {CrExtensionsBrowserTest} - */ -function CrExtensionsManagerTest() {} - -CrExtensionsManagerTest.prototype = { - __proto__: CrExtensionsBrowserTest.prototype, - +var CrExtensionsManagerTest = class extends CrExtensionsBrowserTest { /** @override */ - extraLibraries: CrExtensionsBrowserTest.prototype.extraLibraries.concat([ - 'extension_manager_test.js', - ]), + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_manager_test.js', + ]); + } }; -/** - * Test fixture with multiple installed extensions of different types. - * @constructor - * @extends {CrExtensionsBrowserTest} - */ -function CrExtensionsManagerTestWithMultipleExtensionTypesInstalled() {} - -CrExtensionsManagerTestWithMultipleExtensionTypesInstalled.prototype = { - __proto__: CrExtensionsBrowserTest.prototype, +var CrExtensionsManagerTestWithMultipleExtensionTypesInstalled = + class extends CrExtensionsBrowserTest { + /** @override */ + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_manager_test.js', + ]); + } /** @override */ - extraLibraries: CrExtensionsBrowserTest.prototype.extraLibraries.concat([ - 'extension_manager_test.js', - ]), - - /** @override */ - testGenPreamble: function() { + testGenPreamble() { GEN(' InstallGoodExtension();'); GEN(' InstallPackagedApp();'); GEN(' InstallHostedApp();'); GEN(' InstallPlatformApp();'); - }, + } }; -/** - * Test fixture that navigates to chrome://extensions/?id=<id>. - * @constructor - * @extends {CrExtensionsBrowserTestWithInstalledExtension} - */ -function CrExtensionsManagerTestWithIdQueryParam() {} - -CrExtensionsManagerTestWithIdQueryParam.prototype = { - __proto__: CrExtensionsBrowserTestWithInstalledExtension.prototype, +var CrExtensionsManagerTestWithIdQueryParam = + class extends CrExtensionsBrowserTestWithInstalledExtension { + /** @override */ + get browsePreload() { + return 'chrome://extensions/?id=ldnnhddmnhbkjipkidpdiheffobcpfmf'; + } /** @override */ - browsePreload: 'chrome://extensions/?id=ldnnhddmnhbkjipkidpdiheffobcpfmf', - - /** @override */ - extraLibraries: CrExtensionsBrowserTest.prototype.extraLibraries.concat([ - 'extension_manager_test.js', - ]), + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_manager_test.js', + ]); + } }; -TEST_F('CrExtensionsManagerTest', 'ExtensionManagerItemOrderTest', function() { +TEST_F('CrExtensionsManagerTest', 'ItemOrder', function() { mocha.grep(assert(extension_manager_tests.TestNames.ItemOrder)).run(); }); TEST_F( 'CrExtensionsManagerTestWithMultipleExtensionTypesInstalled', - 'ExtensionManagerItemListVisibilityTest', function() { + 'ItemListVisibility', function() { mocha.grep(assert(extension_manager_tests.TestNames.ItemListVisibility)) .run(); }); TEST_F( - 'CrExtensionsManagerTestWithMultipleExtensionTypesInstalled', - 'ExtensionManagerShowItemsTest', function() { + 'CrExtensionsManagerTestWithMultipleExtensionTypesInstalled', 'ShowItems', + function() { mocha.grep(assert(extension_manager_tests.TestNames.ShowItems)).run(); }); TEST_F( - 'CrExtensionsManagerTestWithMultipleExtensionTypesInstalled', - 'ExtensionManagerChangePagesTest', function() { + 'CrExtensionsManagerTestWithMultipleExtensionTypesInstalled', 'ChangePages', + function() { mocha.grep(assert(extension_manager_tests.TestNames.ChangePages)).run(); }); TEST_F( - 'CrExtensionsManagerTestWithIdQueryParam', - 'ExtensionManagerNavigationToDetailsTest', function() { + 'CrExtensionsManagerTestWithIdQueryParam', 'NavigationToDetails', + function() { mocha .grep( assert(extension_manager_tests.TestNames.UrlNavigationToDetails)) .run(); }); -TEST_F( - 'CrExtensionsManagerTest', 'ExtensionManagerUpdateItemDataTest', - function() { - mocha.grep(assert(extension_manager_tests.TestNames.UpdateItemData)) - .run(); - }); +TEST_F('CrExtensionsManagerTest', 'UpdateItemData', function() { + mocha.grep(assert(extension_manager_tests.TestNames.UpdateItemData)).run(); +}); //////////////////////////////////////////////////////////////////////////////// // Extension Keyboard Shortcuts Tests -/** - * @constructor - * @extends {CrExtensionsBrowserTest} - */ -function CrExtensionsShortcutTest() {} - -CrExtensionsShortcutTest.prototype = { - __proto__: CrExtensionsBrowserTest.prototype, - +var CrExtensionsShortcutTest = class extends CrExtensionsBrowserTest { /** @override */ - extraLibraries: CrExtensionsBrowserTest.prototype.extraLibraries.concat([ - 'extension_keyboard_shortcuts_test.js', - 'extension_shortcut_input_test.js', - ]), + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_keyboard_shortcuts_test.js', + 'extension_shortcut_input_test.js', + ]); + } }; -TEST_F( - 'CrExtensionsShortcutTest', 'ExtensionKeyboardShortcutsLayoutTest', - function() { - mocha.grep(assert(extension_keyboard_shortcut_tests.TestNames.Layout)) - .run(); - }); +TEST_F('CrExtensionsShortcutTest', 'Layout', function() { + mocha.grep(assert(extension_keyboard_shortcut_tests.TestNames.Layout)).run(); +}); -TEST_F('CrExtensionsShortcutTest', 'ExtensionShortcutUtilTest', function() { +TEST_F('CrExtensionsShortcutTest', 'Util', function() { mocha.grep( assert(extension_keyboard_shortcut_tests.TestNames.ShortcutUtil)).run(); }); -TEST_F('CrExtensionsShortcutTest', 'ExtensionShortcutInputTest', function() { +TEST_F('CrExtensionsShortcutTest', 'Basic', function() { mocha.grep( assert(extension_shortcut_input_tests.TestNames.Basic)).run(); }); @@ -448,166 +351,116 @@ //////////////////////////////////////////////////////////////////////////////// // Extension Pack Dialog Tests -/** - * @constructor - * @extends {CrExtensionsBrowserTest} - */ -function CrExtensionsPackDialogTest() {} - -CrExtensionsPackDialogTest.prototype = { - __proto__: CrExtensionsBrowserTest.prototype, - +var CrExtensionsPackDialogTest = class extends CrExtensionsBrowserTest { /** @override */ - extraLibraries: CrExtensionsBrowserTest.prototype.extraLibraries.concat([ - 'extension_pack_dialog_test.js', - ]), + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_pack_dialog_test.js', + ]); + } }; -TEST_F( - 'CrExtensionsPackDialogTest', 'ExtensionPackDialogInteractionTest', - function() { - mocha.grep(assert(extension_pack_dialog_tests.TestNames.Interaction)) - .run(); - }); +TEST_F('CrExtensionsPackDialogTest', 'Interaction', function() { + mocha.grep(assert(extension_pack_dialog_tests.TestNames.Interaction)).run(); +}); -TEST_F( - 'CrExtensionsPackDialogTest', 'ExtensionPackDialogPackSuccessTest', - function() { - mocha.grep(assert(extension_pack_dialog_tests.TestNames.PackSuccess)) - .run(); - }); +TEST_F('CrExtensionsPackDialogTest', 'PackSuccess', function() { + mocha.grep(assert(extension_pack_dialog_tests.TestNames.PackSuccess)).run(); +}); -TEST_F( - 'CrExtensionsPackDialogTest', 'ExtensionPackDialogPackErrorTest', - function() { - mocha.grep(assert(extension_pack_dialog_tests.TestNames.PackError)).run(); - }); +TEST_F('CrExtensionsPackDialogTest', 'PackError', function() { + mocha.grep(assert(extension_pack_dialog_tests.TestNames.PackError)).run(); +}); -TEST_F( - 'CrExtensionsPackDialogTest', 'ExtensionPackDialogPackWarningTest', - function() { - mocha.grep(assert(extension_pack_dialog_tests.TestNames.PackWarning)) - .run(); - }); +TEST_F('CrExtensionsPackDialogTest', 'PackWarning', function() { + mocha.grep(assert(extension_pack_dialog_tests.TestNames.PackWarning)).run(); +}); //////////////////////////////////////////////////////////////////////////////// // Extension Options Dialog Tests -/** - * @constructor - * @extends {CrExtensionsBrowserTest} - */ -function CrExtensionsOptionsDialogTest() {} - -CrExtensionsOptionsDialogTest.prototype = { - __proto__: CrExtensionsBrowserTest.prototype, - +var CrExtensionsOptionsDialogTest = class extends CrExtensionsBrowserTest { /** @override */ - extraLibraries: CrExtensionsBrowserTest.prototype.extraLibraries.concat([ - 'extension_options_dialog_test.js', - ]), + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_options_dialog_test.js', + ]); + } }; -TEST_F( - 'CrExtensionsOptionsDialogTest', 'ExtensionOptionsDialogInteractionTest', - function() { - mocha.grep(assert(extension_options_dialog_tests.TestNames.Layout)).run(); - }); +TEST_F('CrExtensionsOptionsDialogTest', 'Layout', function() { + mocha.grep(assert(extension_options_dialog_tests.TestNames.Layout)).run(); +}); //////////////////////////////////////////////////////////////////////////////// // Extension Error Page Tests -/** - * @constructor - * @extends {CrExtensionsBrowserTest} - */ -function CrExtensionsErrorPageTest() {} - -CrExtensionsErrorPageTest.prototype = { - __proto__: CrExtensionsBrowserTest.prototype, - +var CrExtensionsErrorPageTest = class extends CrExtensionsBrowserTest { /** @override */ - extraLibraries: CrExtensionsBrowserTest.prototype.extraLibraries.concat([ - 'extension_error_page_test.js', - ]), + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_error_page_test.js', + ]); + } }; -TEST_F('CrExtensionsErrorPageTest', 'ExtensionErrorPageLayoutTest', function() { +TEST_F('CrExtensionsErrorPageTest', 'Layout', function() { mocha.grep(assert(extension_error_page_tests.TestNames.Layout)).run(); }); -TEST_F( - 'CrExtensionsErrorPageTest', 'ExtensionErrorPageCodeSectionTest', - function() { - mocha.grep(assert(extension_error_page_tests.TestNames.CodeSection)) - .run(); - }); +TEST_F('CrExtensionsErrorPageTest', 'CodeSection', function() { + mocha.grep(assert(extension_error_page_tests.TestNames.CodeSection)).run(); +}); -TEST_F( - 'CrExtensionsErrorPageTest', 'ExtensionErrorPageErrorSelectionTest', - function() { - mocha.grep(assert(extension_error_page_tests.TestNames.ErrorSelection)) - .run(); - }); +TEST_F('CrExtensionsErrorPageTest', 'ErrorSelection', function() { + mocha.grep(assert(extension_error_page_tests.TestNames.ErrorSelection)).run(); +}); //////////////////////////////////////////////////////////////////////////////// // Extension Code Section Tests -/** - * @constructor - * @extends {CrExtensionsBrowserTest} - */ -function CrExtensionsCodeSectionTest() {} - -CrExtensionsCodeSectionTest.prototype = { - __proto__: CrExtensionsBrowserTest.prototype, - +var CrExtensionsCodeSectionTest = class extends CrExtensionsBrowserTest { /** @override */ - extraLibraries: CrExtensionsBrowserTest.prototype.extraLibraries.concat([ - 'extension_code_section_test.js', - ]), + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_code_section_test.js', + ]); + } }; -TEST_F( - 'CrExtensionsCodeSectionTest', 'ExtensionCodeSectionLayoutTest', - function() { - mocha.grep(assert(extension_code_section_tests.TestNames.Layout)).run(); - }); +TEST_F('CrExtensionsCodeSectionTest', 'Layout', function() { + mocha.grep(assert(extension_code_section_tests.TestNames.Layout)).run(); +}); //////////////////////////////////////////////////////////////////////////////// // Extension Navigation Helper Tests -function CrExtensionsNavigationHelperBrowserTest() {} - -// extensions.NavigationHelper observes window.location. In order to test this -// without the "real" NavigationHelper joining the party, we navigate to -// navigation_helper.html directly. -CrExtensionsNavigationHelperBrowserTest.prototype = { - __proto__: CrExtensionsBrowserTest.prototype, +var CrExtensionsNavigationHelperTest = class extends CrExtensionsBrowserTest { + /** @override */ + get browsePreload() { + return 'chrome://extensions/navigation_helper.html'; + } /** @override */ - browsePreload: 'chrome://extensions/navigation_helper.html', - - /** @override */ - extraLibraries: CrExtensionsBrowserTest.prototype.extraLibraries.concat([ - 'extension_navigation_helper_test.js', - ]), + get extraLibraries() { + return super.extraLibraries.concat([ + 'extension_navigation_helper_test.js', + ]); + } }; -TEST_F('CrExtensionsNavigationHelperBrowserTest', - 'ExtensionNavigationHelperBasicTest', function() { +TEST_F('CrExtensionsNavigationHelperTest', 'Basic', function() { mocha.grep(assert(extension_navigation_helper_tests.TestNames.Basic)).run(); }); -TEST_F('CrExtensionsNavigationHelperBrowserTest', - 'ExtensionNavigationHelperConversionTest', function() { +TEST_F('CrExtensionsNavigationHelperTest', 'Conversion', function() { mocha.grep( assert(extension_navigation_helper_tests.TestNames.Conversions)).run(); }); -TEST_F('CrExtensionsNavigationHelperBrowserTest', - 'ExtensionNavigationHelperPushAndReplaceStateTest', function() { - mocha.grep( - assert(extension_navigation_helper_tests.TestNames.PushAndReplaceState)) - .run(); +TEST_F('CrExtensionsNavigationHelperTest', 'PushAndReplaceState', function() { + mocha + .grep(assert( + extension_navigation_helper_tests.TestNames.PushAndReplaceState)) + .run(); });
diff --git a/chrome/test/data/webui/extensions/extension_item_list_test.js b/chrome/test/data/webui/extensions/extension_item_list_test.js index 20d398e..124e511 100644 --- a/chrome/test/data/webui/extensions/extension_item_list_test.js +++ b/chrome/test/data/webui/extensions/extension_item_list_test.js
@@ -6,9 +6,9 @@ cr.define('extension_item_list_tests', function() { /** @enum {string} */ var TestNames = { - ItemListFiltering: 'item list filtering', - ItemListNoItemsMsg: 'empty item list', - ItemListNoSearchResultsMsg: 'empty item list filtering results', + Filtering: 'item list filtering', + NoItemsMsg: 'empty item list', + NoSearchResultsMsg: 'empty item list filtering results', }; suite('ExtensionItemListTest', function() { @@ -37,7 +37,7 @@ document.body.appendChild(itemList); }); - test(assert(TestNames.ItemListFiltering), function() { + test(assert(TestNames.Filtering), function() { var ironList = itemList.$.list; assert(ironList); @@ -66,7 +66,7 @@ expectEquals(3, ironList.items.length); }); - test(assert(TestNames.ItemListNoItemsMsg), function() { + test(assert(TestNames.NoItemsMsg), function() { testVisible('#no-items', false); testVisible('#no-search-results', false); @@ -75,7 +75,7 @@ testVisible('#no-search-results', false); }); - test(assert(TestNames.ItemListNoSearchResultsMsg), function() { + test(assert(TestNames.NoSearchResultsMsg), function() { testVisible('#no-items', false); testVisible('#no-search-results', false);
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc index 617934a..d135f25a 100644 --- a/chromecast/browser/cast_browser_main_parts.cc +++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -79,7 +79,8 @@ #if defined(OS_ANDROID) #include "chromecast/app/android/crash_handler.h" -#include "components/crash/content/browser/crash_dump_manager_android.h" +#include "components/crash/content/browser/child_process_crash_observer_android.h" +#include "components/crash/content/browser/crash_dump_observer_android.h" #include "net/android/network_change_notifier_factory_android.h" #else #include "chromecast/net/network_change_notifier_factory_cast.h" @@ -409,16 +410,16 @@ int CastBrowserMainParts::PreCreateThreads() { #if defined(OS_ANDROID) - // GPU process is started immediately after threads are created, requiring - // CrashDumpManager to be initialized beforehand. + // GPU process is started immediately after threads are created, + // requiring ChildProcessCrashObserver to be initialized beforehand. base::FilePath crash_dumps_dir; if (!chromecast::CrashHandler::GetCrashDumpLocation(&crash_dumps_dir)) { LOG(ERROR) << "Could not find crash dump location."; } breakpad::CrashDumpObserver::Create(); breakpad::CrashDumpObserver::GetInstance()->RegisterClient( - base::MakeUnique<breakpad::CrashDumpManager>(crash_dumps_dir, - kAndroidMinidumpDescriptor)); + base::MakeUnique<breakpad::ChildProcessCrashObserver>( + crash_dumps_dir, kAndroidMinidumpDescriptor)); #else base::FilePath home_dir; CHECK(PathService::Get(DIR_CAST_HOME, &home_dir));
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index fd24a27..f66d5f96 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc
@@ -72,7 +72,7 @@ #if defined(OS_ANDROID) #include "components/cdm/browser/cdm_message_filter_android.h" -#include "components/crash/content/browser/crash_dump_manager_android.h" +#include "components/crash/content/browser/crash_dump_observer_android.h" #else #include "chromecast/browser/memory_pressure_controller_impl.h" #endif // defined(OS_ANDROID)
diff --git a/components/autofill/content/browser/content_autofill_driver.cc b/components/autofill/content/browser/content_autofill_driver.cc index 0d37b7c..f4e1ece 100644 --- a/components/autofill/content/browser/content_autofill_driver.cc +++ b/components/autofill/content/browser/content_autofill_driver.cc
@@ -247,12 +247,12 @@ autofill_handler_->OnSetDataList(values, labels); } -void ContentAutofillDriver::DidNavigateFrame( +void ContentAutofillDriver::DidNavigateMainFrame( content::NavigationHandle* navigation_handle) { - if (navigation_handle->IsInMainFrame() && - !navigation_handle->IsSameDocument()) { - autofill_handler_->Reset(); - } + if (navigation_handle->IsSameDocument()) + return; + + autofill_handler_->Reset(); } void ContentAutofillDriver::SetAutofillManager(
diff --git a/components/autofill/content/browser/content_autofill_driver.h b/components/autofill/content/browser/content_autofill_driver.h index f3592367..61684b5 100644 --- a/components/autofill/content/browser/content_autofill_driver.h +++ b/components/autofill/content/browser/content_autofill_driver.h
@@ -96,8 +96,9 @@ void SetDataList(const std::vector<base::string16>& values, const std::vector<base::string16>& labels) override; - // Called when the frame has navigated. - void DidNavigateFrame(content::NavigationHandle* navigation_handle); + // Called when the main frame has navigated. Explicitely will not trigger for + // subframe navigations. See navigation_handle.h for details. + void DidNavigateMainFrame(content::NavigationHandle* navigation_handle); AutofillExternalDelegate* autofill_external_delegate() { return autofill_external_delegate_.get();
diff --git a/components/autofill/content/browser/content_autofill_driver_factory.cc b/components/autofill/content/browser/content_autofill_driver_factory.cc index e3d822a1..b643b62 100644 --- a/components/autofill/content/browser/content_autofill_driver_factory.cc +++ b/components/autofill/content/browser/content_autofill_driver_factory.cc
@@ -134,12 +134,18 @@ void ContentAutofillDriverFactory::DidFinishNavigation( content::NavigationHandle* navigation_handle) { - if (!navigation_handle->HasCommitted()) + // For the purposes of this code, a navigation is not important if it has not + // committed yet or if it's in a subframe. + if (!navigation_handle->HasCommitted() || + !navigation_handle->IsInMainFrame()) { return; + } + // A main frame navigation has occured. We suppress the autofill popup and + // tell the autofill driver. NavigationFinished(); DriverForFrame(navigation_handle->GetRenderFrameHost()) - ->DidNavigateFrame(navigation_handle); + ->DidNavigateMainFrame(navigation_handle); } void ContentAutofillDriverFactory::WasHidden() {
diff --git a/components/autofill/content/browser/content_autofill_driver_unittest.cc b/components/autofill/content/browser/content_autofill_driver_unittest.cc index 3ae21b4..d12dd886 100644 --- a/components/autofill/content/browser/content_autofill_driver_unittest.cc +++ b/components/autofill/content/browser/content_autofill_driver_unittest.cc
@@ -29,6 +29,7 @@ #include "content/public/common/frame_navigate_params.h" #include "content/public/test/test_renderer_host.h" #include "mojo/public/cpp/bindings/binding_set.h" +#include "net/base/net_errors.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -264,7 +265,7 @@ return static_cast<MockAutofillManager*>(autofill_manager()); } - using ContentAutofillDriver::DidNavigateFrame; + using ContentAutofillDriver::DidNavigateMainFrame; }; class ContentAutofillDriverTest : public content::RenderViewHostTestHarness { @@ -294,16 +295,11 @@ content::RenderViewHostTestHarness::TearDown(); } - void Navigate(bool main_frame) { - content::RenderFrameHost* rfh = main_rfh(); - content::RenderFrameHostTester* rfh_tester = - content::RenderFrameHostTester::For(rfh); - if (!main_frame) - rfh = rfh_tester->AppendChild("subframe"); + void Navigate(bool same_document) { std::unique_ptr<content::NavigationHandle> navigation_handle = content::NavigationHandle::CreateNavigationHandleForTesting( - GURL(), rfh, true); - driver_->DidNavigateFrame(navigation_handle.get()); + GURL(), main_rfh(), /*committed=*/true, net::OK, same_document); + driver_->DidNavigateMainFrame(navigation_handle.get()); } protected: @@ -322,14 +318,14 @@ EXPECT_EQ(request_context, expected_request_context); } -TEST_F(ContentAutofillDriverTest, NavigatedToDifferentPage) { +TEST_F(ContentAutofillDriverTest, NavigatedMainFrameDifferentDocument) { EXPECT_CALL(*driver_->mock_autofill_manager(), Reset()); - Navigate(true); + Navigate(/*same_document=*/false); } -TEST_F(ContentAutofillDriverTest, NavigatedWithinSamePage) { +TEST_F(ContentAutofillDriverTest, NavigatedMainFrameSameDocument) { EXPECT_CALL(*driver_->mock_autofill_manager(), Reset()).Times(0); - Navigate(false); + Navigate(/*same_document=*/true); } TEST_F(ContentAutofillDriverTest, FormDataSentToRenderer_FillForm) {
diff --git a/components/autofill/core/browser/autofill_driver_factory.h b/components/autofill/core/browser/autofill_driver_factory.h index f5e21c6..cfb7d05b 100644 --- a/components/autofill/core/browser/autofill_driver_factory.h +++ b/components/autofill/core/browser/autofill_driver_factory.h
@@ -28,7 +28,7 @@ // null if there is none. AutofillDriver* DriverForKey(void* key); - // Handles finished navigation in any of the frames. + // Handles finished navigation in the main frame. void NavigationFinished(); // Handles hiding of the corresponding tab.
diff --git a/components/browser_watcher/stability_paths.cc b/components/browser_watcher/stability_paths.cc index 0bd5a4ac..70dc55ea 100644 --- a/components/browser_watcher/stability_paths.cc +++ b/components/browser_watcher/stability_paths.cc
@@ -72,7 +72,8 @@ int64_t creation_time_us = creation_time.tv_sec * kMicrosecondsPerSecond + creation_time.tv_usec; - std::string file_name = base::StringPrintf("%lu-%lld", pid, creation_time_us); + std::string file_name = + base::StringPrintf("%" CrPRIdPid "-%lld", pid, creation_time_us); return stability_dir.AppendASCII(file_name).AddExtension( base::PersistentMemoryAllocator::kFileExtension); }
diff --git a/components/content_settings/core/browser/content_settings_default_provider.cc b/components/content_settings/core/browser/content_settings_default_provider.cc index d0cb24cc..8636b48b 100644 --- a/components/content_settings/core/browser/content_settings_default_provider.cc +++ b/components/content_settings/core/browser/content_settings_default_provider.cc
@@ -382,6 +382,14 @@ prefs_->ClearPref(kObsoleteFullscreenDefaultPref); #if !defined(OS_ANDROID) prefs_->ClearPref(kObsoleteMouseLockDefaultPref); + + // ALLOW-by-default is an obsolete pref value for plugins (Flash). Erase that + // pref and fall back to the default behavior - but preserve other values. + const std::string& plugins_pref = GetPrefName(CONTENT_SETTINGS_TYPE_PLUGINS); + if (IntToContentSetting(prefs_->GetInteger(plugins_pref)) == + ContentSetting::CONTENT_SETTING_ALLOW) { + prefs_->ClearPref(plugins_pref); + } #endif // !defined(OS_ANDROID) #endif // !defined(OS_IOS) }
diff --git a/components/crash/content/browser/BUILD.gn b/components/crash/content/browser/BUILD.gn index 31fb1d1a..94e18cb 100644 --- a/components/crash/content/browser/BUILD.gn +++ b/components/crash/content/browser/BUILD.gn
@@ -8,6 +8,8 @@ source_set("browser") { sources = [ + "child_process_crash_observer_android.cc", + "child_process_crash_observer_android.h", "crash_dump_manager_android.cc", "crash_dump_manager_android.h", "crash_dump_observer_android.cc",
diff --git a/components/crash/content/browser/child_process_crash_observer_android.cc b/components/crash/content/browser/child_process_crash_observer_android.cc new file mode 100644 index 0000000..b9ae22bb --- /dev/null +++ b/components/crash/content/browser/child_process_crash_observer_android.cc
@@ -0,0 +1,52 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/crash/content/browser/child_process_crash_observer_android.h" + +#include "base/bind.h" +#include "base/files/file_util.h" +#include "base/task_scheduler/post_task.h" +#include "components/crash/content/app/breakpad_linux.h" +#include "components/crash/content/browser/crash_dump_manager_android.h" + +namespace breakpad { + +ChildProcessCrashObserver::ChildProcessCrashObserver( + const base::FilePath crash_dump_dir, + int descriptor_id) + : crash_dump_dir_(crash_dump_dir), descriptor_id_(descriptor_id) {} + +ChildProcessCrashObserver::~ChildProcessCrashObserver() {} + +void ChildProcessCrashObserver::OnChildStart( + int child_process_id, + content::PosixFileDescriptorInfo* mappings) { + if (!breakpad::IsCrashReporterEnabled()) + return; + + base::ScopedFD file( + CrashDumpManager::GetInstance()->CreateMinidumpFileForChild( + child_process_id)); + if (file.is_valid()) + mappings->Transfer(descriptor_id_, std::move(file)); +} + +void ChildProcessCrashObserver::OnChildExit( + int child_process_id, + base::ProcessHandle pid, + content::ProcessType process_type, + base::TerminationStatus termination_status, + base::android::ApplicationState app_state) { + // This might be called twice for a given child process, with a + // NOTIFICATION_RENDERER_PROCESS_TERMINATED and then with + // NOTIFICATION_RENDERER_PROCESS_CLOSED. + base::PostTaskWithTraits( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, + base::Bind(&CrashDumpManager::ProcessMinidumpFileFromChild, + base::Unretained(CrashDumpManager::GetInstance()), + crash_dump_dir_, pid, process_type, termination_status, + app_state)); +} + +} // namespace breakpad
diff --git a/components/crash/content/browser/child_process_crash_observer_android.h b/components/crash/content/browser/child_process_crash_observer_android.h new file mode 100644 index 0000000..fad32f2 --- /dev/null +++ b/components/crash/content/browser/child_process_crash_observer_android.h
@@ -0,0 +1,39 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_CRASH_CONTENT_BROWSER_CHILD_PROCESS_CRASH_OBSERVER_ANDROID_H_ +#define COMPONENTS_CRASH_CONTENT_BROWSER_CHILD_PROCESS_CRASH_OBSERVER_ANDROID_H_ + +#include "base/files/file_path.h" +#include "components/crash/content/browser/crash_dump_observer_android.h" + +namespace breakpad { + +class ChildProcessCrashObserver : public breakpad::CrashDumpObserver::Client { + public: + ChildProcessCrashObserver(const base::FilePath crash_dump_dir, + int descriptor_id); + ~ChildProcessCrashObserver() override; + + // breakpad::CrashDumpObserver::Client implementation: + void OnChildStart(int child_process_id, + content::PosixFileDescriptorInfo* mappings) override; + void OnChildExit(int child_process_id, + base::ProcessHandle pid, + content::ProcessType process_type, + base::TerminationStatus termination_status, + base::android::ApplicationState app_state) override; + + private: + base::FilePath crash_dump_dir_; + // The id used to identify the file descriptor in the set of file + // descriptor mappings passed to the child process. + int descriptor_id_; + + DISALLOW_COPY_AND_ASSIGN(ChildProcessCrashObserver); +}; + +} // namespace breakpad + +#endif // COMPONENTS_CRASH_CONTENT_BROWSER_CHILD_PROCESS_CRASH_OBSERVER_ANDROID_H_
diff --git a/components/crash/content/browser/crash_dump_manager_android.cc b/components/crash/content/browser/crash_dump_manager_android.cc index 24a00b4..d7cadd74 100644 --- a/components/crash/content/browser/crash_dump_manager_android.cc +++ b/components/crash/content/browser/crash_dump_manager_android.cc
@@ -11,41 +11,39 @@ #include "base/bind.h" #include "base/files/file_util.h" #include "base/format_macros.h" +#include "base/lazy_instance.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" -#include "base/posix/global_descriptors.h" #include "base/process/process.h" #include "base/rand_util.h" #include "base/stl_util.h" #include "base/strings/stringprintf.h" -#include "base/task_scheduler/post_task.h" #include "components/crash/content/app/breakpad_linux.h" -#include "content/public/browser/child_process_data.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" -#include "content/public/browser/posix_file_descriptor_info.h" -#include "content/public/browser/render_process_host.h" #include "jni/CrashDumpManager_jni.h" namespace breakpad { -CrashDumpManager::CrashDumpManager(const base::FilePath& crash_dump_dir, - int descriptor_id) - : crash_dump_dir_(crash_dump_dir), descriptor_id_(descriptor_id) {} - -CrashDumpManager::~CrashDumpManager() { +namespace { +base::LazyInstance<CrashDumpManager>::Leaky g_instance = + LAZY_INSTANCE_INITIALIZER; } -void CrashDumpManager::OnChildStart( - int child_process_id, - content::PosixFileDescriptorInfo* mappings) { - if (!breakpad::IsCrashReporterEnabled()) - return; +// static +CrashDumpManager* CrashDumpManager::GetInstance() { + return g_instance.Pointer(); +} +CrashDumpManager::CrashDumpManager() {} + +CrashDumpManager::~CrashDumpManager() {} + +base::ScopedFD CrashDumpManager::CreateMinidumpFileForChild( + int child_process_id) { + base::ThreadRestrictions::AssertIOAllowed(); base::FilePath minidump_path; if (!base::CreateTemporaryFile(&minidump_path)) { LOG(ERROR) << "Failed to create temporary file, crash won't be reported."; - return; + return base::ScopedFD(); } // We need read permission as the minidump is generated in several phases @@ -55,27 +53,26 @@ base::File minidump_file(minidump_path, flags); if (!minidump_file.IsValid()) { LOG(ERROR) << "Failed to open temporary file, crash won't be reported."; - return; + return base::ScopedFD(); } - { - base::AutoLock auto_lock(child_process_id_to_minidump_path_lock_); - DCHECK(!base::ContainsKey(child_process_id_to_minidump_path_, - child_process_id)); - child_process_id_to_minidump_path_[child_process_id] = minidump_path; - } - mappings->Transfer(descriptor_id_, - base::ScopedFD(minidump_file.TakePlatformFile())); + SetMinidumpPath(child_process_id, minidump_path); + return base::ScopedFD(minidump_file.TakePlatformFile()); } -// static -void CrashDumpManager::ProcessMinidump( - const base::FilePath& minidump_path, - const base::FilePath& crash_dump_dir, +void CrashDumpManager::ProcessMinidumpFileFromChild( + base::FilePath crash_dump_dir, base::ProcessHandle pid, content::ProcessType process_type, base::TerminationStatus termination_status, base::android::ApplicationState app_state) { + base::ThreadRestrictions::AssertIOAllowed(); + base::FilePath minidump_path; + // If the minidump for a given child process has already been + // processed, then there is no more work to do. + if (!GetMinidumpPath(pid, &minidump_path)) + return; + int64_t file_size = 0; int r = base::GetFileSize(minidump_path, &file_size); DCHECK(r) << "Failed to retrieve size for minidump " @@ -163,29 +160,25 @@ Java_CrashDumpManager_tryToUploadMinidump(env, j_dest_path); } -void CrashDumpManager::OnChildExit(int child_process_id, - base::ProcessHandle pid, - content::ProcessType process_type, - base::TerminationStatus termination_status, - base::android::ApplicationState app_state) { - base::FilePath minidump_path; - { - base::AutoLock auto_lock(child_process_id_to_minidump_path_lock_); - ChildProcessIDToMinidumpPath::iterator iter = - child_process_id_to_minidump_path_.find(child_process_id); - if (iter == child_process_id_to_minidump_path_.end()) { - // We might get a NOTIFICATION_RENDERER_PROCESS_TERMINATED and a - // NOTIFICATION_RENDERER_PROCESS_CLOSED. - return; - } - minidump_path = iter->second; - child_process_id_to_minidump_path_.erase(iter); +void CrashDumpManager::SetMinidumpPath(int child_process_id, + const base::FilePath& minidump_path) { + base::AutoLock auto_lock(child_process_id_to_minidump_path_lock_); + DCHECK( + !base::ContainsKey(child_process_id_to_minidump_path_, child_process_id)); + child_process_id_to_minidump_path_[child_process_id] = minidump_path; +} + +bool CrashDumpManager::GetMinidumpPath(int child_process_id, + base::FilePath* minidump_path) { + base::AutoLock auto_lock(child_process_id_to_minidump_path_lock_); + ChildProcessIDToMinidumpPath::iterator iter = + child_process_id_to_minidump_path_.find(child_process_id); + if (iter == child_process_id_to_minidump_path_.end()) { + return false; } - base::PostTaskWithTraits( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, - base::Bind(&CrashDumpManager::ProcessMinidump, minidump_path, - crash_dump_dir_, pid, process_type, termination_status, - app_state)); + *minidump_path = iter->second; + child_process_id_to_minidump_path_.erase(iter); + return true; } } // namespace breakpad
diff --git a/components/crash/content/browser/crash_dump_manager_android.h b/components/crash/content/browser/crash_dump_manager_android.h index dde3f6e2..6aa58857 100644 --- a/components/crash/content/browser/crash_dump_manager_android.h +++ b/components/crash/content/browser/crash_dump_manager_android.h
@@ -7,9 +7,13 @@ #include <map> +#include "base/android/application_status_listener.h" #include "base/files/file_path.h" +#include "base/files/platform_file.h" +#include "base/lazy_instance.h" +#include "base/process/kill.h" #include "base/synchronization/lock.h" -#include "components/crash/content/browser/crash_dump_observer_android.h" +#include "content/public/common/process_type.h" namespace breakpad { @@ -23,21 +27,24 @@ // This class creates these file descriptors and associates them with render // processes and takes the appropriate action when the render process // terminates. -class CrashDumpManager : public breakpad::CrashDumpObserver::Client { +class CrashDumpManager { public: - CrashDumpManager(const base::FilePath& crash_dump_dir, int descriptor_id); - ~CrashDumpManager() override; + static CrashDumpManager* GetInstance(); - // breakpad::CrashDumpObserver::Client implementation: - void OnChildStart(int child_process_id, - content::PosixFileDescriptorInfo* mappings) override; - void OnChildExit(int child_process_id, - base::ProcessHandle pid, - content::ProcessType process_type, - base::TerminationStatus termination_status, - base::android::ApplicationState app_state) override; + void ProcessMinidumpFileFromChild(base::FilePath crash_dump_dir, + base::ProcessHandle pid, + content::ProcessType process_type, + base::TerminationStatus termination_status, + base::android::ApplicationState app_state); + + base::ScopedFD CreateMinidumpFileForChild(int child_process_id); private: + friend struct base::LazyInstanceTraitsBase<CrashDumpManager>; + + CrashDumpManager(); + ~CrashDumpManager(); + typedef std::map<int, base::FilePath> ChildProcessIDToMinidumpPath; // This enum is used to back a UMA histogram, and must be treated as @@ -52,25 +59,15 @@ MINIDUMP_STATUS_COUNT }; - static void ProcessMinidump(const base::FilePath& minidump_path, - const base::FilePath& crash_dump_dir, - base::ProcessHandle pid, - content::ProcessType process_type, - base::TerminationStatus termination_status, - base::android::ApplicationState app_state); + void SetMinidumpPath(int child_process_id, + const base::FilePath& minidump_path); + bool GetMinidumpPath(int child_process_id, base::FilePath* minidump_path); // This map should only be accessed with its lock aquired as it is accessed // from the PROCESS_LAUNCHER and UI threads. base::Lock child_process_id_to_minidump_path_lock_; ChildProcessIDToMinidumpPath child_process_id_to_minidump_path_; - // The directory in which temporary minidump files should be created. - base::FilePath crash_dump_dir_; - - // The id used to identify the file descriptor in the set of file - // descriptor mappings passed to the child process. - int descriptor_id_; - DISALLOW_COPY_AND_ASSIGN(CrashDumpManager); };
diff --git a/components/metrics/call_stack_profile_metrics_provider.cc b/components/metrics/call_stack_profile_metrics_provider.cc index 3914b4c..a64816e8 100644 --- a/components/metrics/call_stack_profile_metrics_provider.cc +++ b/components/metrics/call_stack_profile_metrics_provider.cc
@@ -508,9 +508,22 @@ // calls base::FeatureList::IsEnabled() internally. While extremely unlikely, // it is possible that the profiler callback and therefore this function get // called before FeatureList initialization (e.g. if machine was suspended). - return base::FeatureList::GetInstance() != nullptr && - base::GetFieldTrialParamByFeatureAsBool(kEnableReporting, "periodic", - false); + // + // The result is cached in a static to avoid a shutdown hang calling into the + // API while FieldTrialList is being destroyed. See also the comment below in + // Init(). + static const bool is_enabled = base::FeatureList::GetInstance() != nullptr && + base::GetFieldTrialParamByFeatureAsBool( + kEnableReporting, "periodic", false); + return is_enabled; +} + +void CallStackProfileMetricsProvider::Init() { + // IsPeriodicSamplingEnabled() caches the result in a local static, so that + // future calls will return it directly. Calling it in Init() will cache the + // result, which will ensure we won't call into FieldTrialList during + // shutdown which can hang if it's in the middle of being destroyed. + CallStackProfileMetricsProvider::IsPeriodicSamplingEnabled(); } void CallStackProfileMetricsProvider::OnRecordingEnabled() {
diff --git a/components/metrics/call_stack_profile_metrics_provider.h b/components/metrics/call_stack_profile_metrics_provider.h index a8178bd..d778ad34 100644 --- a/components/metrics/call_stack_profile_metrics_provider.h +++ b/components/metrics/call_stack_profile_metrics_provider.h
@@ -71,6 +71,7 @@ static bool IsPeriodicSamplingEnabled(); // MetricsProvider: + void Init() override; void OnRecordingEnabled() override; void OnRecordingDisabled() override; void ProvideCurrentSessionData(
diff --git a/components/ntp_tiles/BUILD.gn b/components/ntp_tiles/BUILD.gn index d970418..300d475 100644 --- a/components/ntp_tiles/BUILD.gn +++ b/components/ntp_tiles/BUILD.gn
@@ -28,6 +28,7 @@ "popular_sites_impl.h", "pref_names.cc", "pref_names.h", + "section_type.h", "switches.cc", "switches.h", "tile_source.h", @@ -111,6 +112,7 @@ if (is_android) { java_cpp_enum("ntp_tiles_enums_java") { sources = [ + "section_type.h", "tile_source.h", "tile_visual_type.h", ]
diff --git a/components/ntp_tiles/constants.cc b/components/ntp_tiles/constants.cc index d9085ac..4eaafbb5 100644 --- a/components/ntp_tiles/constants.cc +++ b/components/ntp_tiles/constants.cc
@@ -21,6 +21,9 @@ extern const base::Feature kLowerResolutionFaviconsFeature{ "NTPTilesLowerResolutionFavicons", base::FEATURE_DISABLED_BY_DEFAULT}; +extern const base::Feature kSitesExplorationFeature{ + "SitesExplorationFeature", base::FEATURE_DISABLED_BY_DEFAULT}; + bool AreNtpMostLikelyFaviconsFromServerEnabled() { // Check if the experimental flag is forced on or off. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
diff --git a/components/ntp_tiles/constants.h b/components/ntp_tiles/constants.h index 7afb9f07..e81cb0a 100644 --- a/components/ntp_tiles/constants.h +++ b/components/ntp_tiles/constants.h
@@ -27,6 +27,9 @@ // Tab Page. extern const base::Feature kLowerResolutionFaviconsFeature; +// Feature to provide site exploration tiles in addition to personal tiles. +extern const base::Feature kSitesExplorationFeature; + // Use this to find out whether the kNtpMostLikelyFaviconsFromServerFeature is // enabled. This helper function abstracts iOS special way to override the // feature (via command-line params).
diff --git a/components/ntp_tiles/most_visited_sites.cc b/components/ntp_tiles/most_visited_sites.cc index 464f2c1..b41a0993 100644 --- a/components/ntp_tiles/most_visited_sites.cc +++ b/components/ntp_tiles/most_visited_sites.cc
@@ -361,7 +361,9 @@ // Collect non-blacklisted popular suggestions, skipping those already present // in the personal suggestions. NTPTilesVector popular_sites_tiles; - for (const PopularSites::Site& popular_site : popular_sites_->sites()) { + const PopularSites::SitesVector& popular_sites = + popular_sites_->sections().at(SectionType::PERSONALIZED); + for (const PopularSites::Site& popular_site : popular_sites) { if (popular_sites_tiles.size() + num_actual_tiles >= num_sites_) break; @@ -506,7 +508,9 @@ return; } - for (const PopularSites::Site& popular_site : popular_sites_->sites()) { + const PopularSites::SitesVector& popular_sites = + popular_sites_->sections().at(SectionType::PERSONALIZED); + for (const PopularSites::Site& popular_site : popular_sites) { // Ignore callback; these icons will be seen on the *next* NTP. icon_cacher_->StartFetchPopularSites(popular_site, base::Closure(), base::Closure());
diff --git a/components/ntp_tiles/most_visited_sites_unittest.cc b/components/ntp_tiles/most_visited_sites_unittest.cc index aae946e..5ba7f59 100644 --- a/components/ntp_tiles/most_visited_sites_unittest.cc +++ b/components/ntp_tiles/most_visited_sites_unittest.cc
@@ -273,10 +273,10 @@ PopularSitesImpl::RegisterProfilePrefs(pref_service->registry()); if (enabled) { prefs_->SetString(prefs::kPopularSitesOverrideCountry, "IN"); - prefs_->SetString(prefs::kPopularSitesOverrideVersion, "7"); + prefs_->SetString(prefs::kPopularSitesOverrideVersion, "5"); url_fetcher_factory_.SetFakeResponse( - GURL("https://www.gstatic.com/chrome/ntp/suggested_sites_IN_7.json"), + GURL("https://www.gstatic.com/chrome/ntp/suggested_sites_IN_5.json"), R"([{ "title": "PopularSite1", "url": "http://popularsite1/",
diff --git a/components/ntp_tiles/popular_sites.h b/components/ntp_tiles/popular_sites.h index f1e207f..407950a 100644 --- a/components/ntp_tiles/popular_sites.h +++ b/components/ntp_tiles/popular_sites.h
@@ -5,12 +5,14 @@ #ifndef COMPONENTS_NTP_TILES_POPULAR_SITES_H_ #define COMPONENTS_NTP_TILES_POPULAR_SITES_H_ +#include <map> #include <string> #include <vector> #include "base/callback.h" #include "base/macros.h" #include "base/strings/string16.h" +#include "components/ntp_tiles/section_type.h" #include "url/gurl.h" namespace base { @@ -60,8 +62,8 @@ virtual bool MaybeStartFetch(bool force_download, const FinishedCallback& callback) = 0; - // Returns the list of available sites. - virtual const SitesVector& sites() const = 0; + // Returns the cached list of available sections and their sites. + virtual const std::map<SectionType, SitesVector>& sections() const = 0; // Various internals exposed publicly for diagnostic pages only. virtual GURL GetLastURLFetched() const = 0;
diff --git a/components/ntp_tiles/popular_sites_impl.cc b/components/ntp_tiles/popular_sites_impl.cc index 7abdc92..903c8bf 100644 --- a/components/ntp_tiles/popular_sites_impl.cc +++ b/components/ntp_tiles/popular_sites_impl.cc
@@ -5,13 +5,16 @@ #include "components/ntp_tiles/popular_sites_impl.h" #include <stddef.h> +#include <map> #include <utility> #include "base/bind.h" #include "base/command_line.h" #include "base/feature_list.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "base/values.h" #include "build/build_config.h" @@ -53,12 +56,9 @@ const char kPopularSitesDefaultDirectory[] = "chrome/ntp/"; const char kPopularSitesDefaultCountryCode[] = "DEFAULT"; const char kPopularSitesDefaultVersion[] = "5"; +const int kSitesExplorationStartVersion = 6; const int kPopularSitesRedownloadIntervalHours = 24; -const char kPopularSitesLastDownloadPref[] = "popular_sites_last_download"; -const char kPopularSitesURLPref[] = "popular_sites_url"; -const char kPopularSitesJsonPref[] = "suggested_sites_json"; - GURL GetPopularSitesURL(const std::string& directory, const std::string& country, const std::string& version) { @@ -132,6 +132,60 @@ return sites; } +std::map<SectionType, PopularSites::SitesVector> ParseVersion5( + const base::ListValue& list) { + return {{SectionType::PERSONALIZED, ParseSiteList(list)}}; +} + +std::map<SectionType, PopularSites::SitesVector> ParseVersion6OrAbove( + const base::ListValue& list) { + // Valid lists would have contained at least the PERSONALIZED section. + std::map<SectionType, PopularSites::SitesVector> sections = { + std::make_pair(SectionType::PERSONALIZED, PopularSites::SitesVector{})}; + for (size_t i = 0; i < list.GetSize(); i++) { + const base::DictionaryValue* item; + if (!list.GetDictionary(i, &item)) { + LOG(WARNING) << "Parsed SitesExploration list contained an invalid " + << "section at position " << i << "."; + continue; + } + int section; + if (!item->GetInteger("section", §ion) || section < 0 || + section > static_cast<int>(SectionType::LAST)) { + LOG(WARNING) << "Parsed SitesExploration list contained a section with " + << "invalid ID (" << section << ")"; + continue; + } + SectionType section_type = static_cast<SectionType>(section); + if (section_type == SectionType::UNKNOWN) { + LOG(WARNING) << "Dropped an unknown section in SitesExploration list."; + continue; + } + const base::ListValue* sites_list; + if (!item->GetList("sites", &sites_list)) { + continue; + } + sections[section_type] = ParseSiteList(*sites_list); + } + if (!base::FeatureList::IsEnabled(kSitesExplorationFeature)) { + // New versions of popular sites that should act like old versions will + // mimic having only the personalized list. + return {std::make_pair(SectionType::PERSONALIZED, + std::move(sections[SectionType::PERSONALIZED]))}; + } + return sections; +} + +std::map<SectionType, PopularSites::SitesVector> ParseSites( + const base::ListValue& list, + int version) { + if (version >= kSitesExplorationStartVersion) { + return ParseVersion6OrAbove(list); + } else { + return ParseVersion5(list); + } +} + #if defined(GOOGLE_CHROME_BUILD) && (defined(OS_ANDROID) || defined(OS_IOS)) void SetDefaultResourceForSite(int index, int resource_id, @@ -201,7 +255,9 @@ download_context_(download_context), parse_json_(std::move(parse_json)), is_fallback_(false), - sites_(ParseSiteList(*prefs->GetList(kPopularSitesJsonPref))), + sections_( + ParseSites(*prefs->GetList(prefs::kPopularSitesJsonPref), + prefs_->GetInteger(prefs::kPopularSitesVersionPref))), weak_ptr_factory_(this) {} PopularSitesImpl::~PopularSitesImpl() {} @@ -212,7 +268,7 @@ callback_ = callback; const base::Time last_download_time = base::Time::FromInternalValue( - prefs_->GetInt64(kPopularSitesLastDownloadPref)); + prefs_->GetInt64(prefs::kPopularSitesLastDownloadPref)); const base::TimeDelta time_since_last_download = base::Time::Now() - last_download_time; const base::TimeDelta redownload_interval = @@ -221,7 +277,7 @@ pending_url_ = GetURLToFetch(); const bool url_changed = - pending_url_.spec() != prefs_->GetString(kPopularSitesURLPref); + pending_url_.spec() != prefs_->GetString(prefs::kPopularSitesURLPref); // Download forced, or we need to download a new file. if (force_download || download_time_is_future || @@ -232,18 +288,20 @@ return false; } -const PopularSites::SitesVector& PopularSitesImpl::sites() const { - return sites_; +const std::map<SectionType, PopularSitesImpl::SitesVector>& +PopularSitesImpl::sections() const { + return sections_; } GURL PopularSitesImpl::GetLastURLFetched() const { - return GURL(prefs_->GetString(kPopularSitesURLPref)); + return GURL(prefs_->GetString(prefs::kPopularSitesURLPref)); } GURL PopularSitesImpl::GetURLToFetch() { const std::string directory = GetDirectoryToFetch(); const std::string country = GetCountryToFetch(); const std::string version = GetVersionToFetch(); + base::StringToInt(version, &version_in_pending_url_); const GURL override_url = GURL(prefs_->GetString(ntp_tiles::prefs::kPopularSitesOverrideURL)); @@ -311,7 +369,7 @@ } const base::ListValue* PopularSitesImpl::GetCachedJson() { - return prefs_->GetList(kPopularSitesJsonPref); + return prefs_->GetList(prefs::kPopularSitesJsonPref); } // static @@ -326,9 +384,13 @@ user_prefs->RegisterStringPref(ntp_tiles::prefs::kPopularSitesOverrideVersion, std::string()); - user_prefs->RegisterInt64Pref(kPopularSitesLastDownloadPref, 0); - user_prefs->RegisterStringPref(kPopularSitesURLPref, std::string()); - user_prefs->RegisterListPref(kPopularSitesJsonPref, DefaultPopularSites()); + user_prefs->RegisterInt64Pref(prefs::kPopularSitesLastDownloadPref, 0); + user_prefs->RegisterStringPref(prefs::kPopularSitesURLPref, std::string()); + user_prefs->RegisterListPref(prefs::kPopularSitesJsonPref, + DefaultPopularSites()); + int version; + base::StringToInt(kPopularSitesDefaultVersion, &version); + user_prefs->RegisterIntegerPref(prefs::kPopularSitesVersionPref, version); } void PopularSitesImpl::FetchPopularSites() { @@ -390,13 +452,13 @@ OnDownloadFailed(); return; } - - prefs_->Set(kPopularSitesJsonPref, *list); - prefs_->SetInt64(kPopularSitesLastDownloadPref, + prefs_->Set(prefs::kPopularSitesJsonPref, *list); + prefs_->SetInt64(prefs::kPopularSitesLastDownloadPref, base::Time::Now().ToInternalValue()); - prefs_->SetString(kPopularSitesURLPref, pending_url_.spec()); + prefs_->SetInteger(prefs::kPopularSitesVersionPref, version_in_pending_url_); + prefs_->SetString(prefs::kPopularSitesURLPref, pending_url_.spec()); - sites_ = ParseSiteList(*list); + sections_ = ParseSites(*list, version_in_pending_url_); callback_.Run(true); }
diff --git a/components/ntp_tiles/popular_sites_impl.h b/components/ntp_tiles/popular_sites_impl.h index 1162973..c58dbf35 100644 --- a/components/ntp_tiles/popular_sites_impl.h +++ b/components/ntp_tiles/popular_sites_impl.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_NTP_TILES_POPULAR_SITES_IMPL_H_ #define COMPONENTS_NTP_TILES_POPULAR_SITES_IMPL_H_ +#include <map> #include <memory> #include <string> #include <vector> @@ -59,7 +60,7 @@ // PopularSites implementation. bool MaybeStartFetch(bool force_download, const FinishedCallback& callback) override; - const SitesVector& sites() const override; + const std::map<SectionType, SitesVector>& sections() const override; GURL GetLastURLFetched() const override; GURL GetURLToFetch() override; std::string GetDirectoryToFetch() override; @@ -95,8 +96,9 @@ std::unique_ptr<net::URLFetcher> fetcher_; bool is_fallback_; - SitesVector sites_; + std::map<SectionType, SitesVector> sections_; GURL pending_url_; + int version_in_pending_url_; base::WeakPtrFactory<PopularSitesImpl> weak_ptr_factory_;
diff --git a/components/ntp_tiles/popular_sites_impl_unittest.cc b/components/ntp_tiles/popular_sites_impl_unittest.cc index d29217f2..27cd087 100644 --- a/components/ntp_tiles/popular_sites_impl_unittest.cc +++ b/components/ntp_tiles/popular_sites_impl_unittest.cc
@@ -16,6 +16,7 @@ #include "base/message_loop/message_loop.h" #include "base/optional.h" #include "base/run_loop.h" +#include "base/strings/string_number_conversions.h" #include "base/test/scoped_feature_list.h" #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" @@ -33,9 +34,15 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using testing::_; +using testing::Contains; +using testing::ElementsAre; using testing::Eq; using testing::Gt; using testing::IsEmpty; +using testing::Not; +using testing::Pair; +using testing::SizeIs; namespace ntp_tiles { namespace { @@ -44,9 +51,13 @@ const char kUrl[] = "url"; const char kLargeIconUrl[] = "large_icon_url"; const char kFaviconUrl[] = "favicon_url"; +const char kSection[] = "section"; +const char kSites[] = "sites"; using TestPopularSite = std::map<std::string, std::string>; using TestPopularSiteVector = std::vector<TestPopularSite>; +using TestPopularSection = std::pair<SectionType, TestPopularSiteVector>; +using TestPopularSectionVector = std::vector<TestPopularSection>; ::testing::Matcher<const base::string16&> Str16Eq(const std::string& s) { return ::testing::Eq(base::UTF8ToUTF16(s)); @@ -95,18 +106,38 @@ prefs_->SetString(prefs::kPopularSitesOverrideVersion, version); } - void RespondWithJSON(const std::string& url, - const TestPopularSiteVector& sites) { - base::ListValue sites_value; + std::unique_ptr<base::ListValue> CreateListFromTestSites( + const TestPopularSiteVector& sites) { + auto sites_value = base::MakeUnique<base::ListValue>(); for (const TestPopularSite& site : sites) { auto site_value = base::MakeUnique<base::DictionaryValue>(); for (const std::pair<std::string, std::string>& kv : site) { site_value->SetString(kv.first, kv.second); } - sites_value.Append(std::move(site_value)); + sites_value->Append(std::move(site_value)); + } + return sites_value; + } + + void RespondWithV5JSON(const std::string& url, + const TestPopularSiteVector& sites) { + std::string sites_string; + base::JSONWriter::Write(*CreateListFromTestSites(sites), &sites_string); + url_fetcher_factory_.SetFakeResponse(GURL(url), sites_string, net::HTTP_OK, + net::URLRequestStatus::SUCCESS); + } + + void RespondWithV6JSON(const std::string& url, + const TestPopularSectionVector& sections) { + base::ListValue sections_value; + for (const TestPopularSection& section : sections) { + auto section_value = base::MakeUnique<base::DictionaryValue>(); + section_value->SetInteger(kSection, static_cast<int>(section.first)); + section_value->SetList(kSites, CreateListFromTestSites(section.second)); + sections_value.Append(std::move(section_value)); } std::string sites_string; - base::JSONWriter::Write(sites_value, &sites_string); + base::JSONWriter::Write(sections_value, &sites_string); url_fetcher_factory_.SetFakeResponse(GURL(url), sites_string, net::HTTP_OK, net::URLRequestStatus::SUCCESS); } @@ -130,6 +161,18 @@ // called at all, and if yes which was the returned bool value. base::Optional<bool> FetchPopularSites(bool force_download, PopularSites::SitesVector* sites) { + std::map<SectionType, PopularSites::SitesVector> sections; + base::Optional<bool> save_success = + FetchAllSections(force_download, §ions); + *sites = sections.at(SectionType::PERSONALIZED); + return save_success; + } + + // Returns an optional bool representing whether the completion callback was + // called at all, and if yes which was the returned bool value. + base::Optional<bool> FetchAllSections( + bool force_download, + std::map<SectionType, PopularSites::SitesVector>* sections) { scoped_refptr<net::TestURLRequestContextGetter> url_request_context( new net::TestURLRequestContextGetter( base::ThreadTaskRunnerHandle::Get())); @@ -148,7 +191,7 @@ &save_success, &loop))) { loop.Run(); } - *sites = popular_sites->sites(); + *sections = popular_sites->sections(); return save_success; } @@ -176,8 +219,10 @@ base::ThreadTaskRunnerHandle::Get())); auto popular_sites = CreatePopularSites(url_request_context.get()); - EXPECT_THAT(popular_sites->sites().size(), - Eq(GetNumberOfDefaultPopularSitesForPlatform())); + EXPECT_THAT( + popular_sites->sections(), + ElementsAre(Pair(SectionType::PERSONALIZED, + SizeIs(GetNumberOfDefaultPopularSitesForPlatform())))); } TEST_F(PopularSitesTest, IsEmptyOnConstructionIfDisabledByTrial) { @@ -190,17 +235,18 @@ base::ThreadTaskRunnerHandle::Get())); auto popular_sites = CreatePopularSites(url_request_context.get()); - EXPECT_THAT(popular_sites->sites().size(), Eq(0ul)); + EXPECT_THAT(popular_sites->sections(), + ElementsAre(Pair(SectionType::PERSONALIZED, IsEmpty()))); } TEST_F(PopularSitesTest, ShouldSucceedFetching) { - SetCountryAndVersion("ZZ", "9"); - RespondWithJSON( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json", + SetCountryAndVersion("ZZ", "5"); + RespondWithV5JSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json", {kWikipedia}); PopularSites::SitesVector sites; - EXPECT_THAT(FetchPopularSites(/*force_download=*/false, &sites), + EXPECT_THAT(FetchPopularSites(/*force_download=*/true, &sites), Eq(base::Optional<bool>(true))); ASSERT_THAT(sites.size(), Eq(1u)); @@ -212,10 +258,10 @@ } TEST_F(PopularSitesTest, Fallback) { - SetCountryAndVersion("ZZ", "9"); + SetCountryAndVersion("ZZ", "5"); RespondWith404( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json"); - RespondWithJSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json"); + RespondWithV5JSON( "https://www.gstatic.com/chrome/ntp/suggested_sites_DEFAULT_5.json", {kYouTube, kChromium}); @@ -237,9 +283,9 @@ } TEST_F(PopularSitesTest, PopulatesWithDefaultResoucesOnFailure) { - SetCountryAndVersion("ZZ", "9"); + SetCountryAndVersion("ZZ", "5"); RespondWith404( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json"); + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json"); RespondWith404( "https://www.gstatic.com/chrome/ntp/suggested_sites_DEFAULT_5.json"); @@ -257,17 +303,19 @@ CreatePopularSites(url_request_context.get()); #if defined(GOOGLE_CHROME_BUILD) && (defined(OS_ANDROID) || defined(OS_IOS)) - ASSERT_FALSE(popular_sites->sites().empty()); - for (const auto& site : popular_sites->sites()) { + const PopularSites::SitesVector& sites = + popular_sites->sections().at(SectionType::PERSONALIZED); + ASSERT_FALSE(sites.empty()); + for (const auto& site : sites) { EXPECT_THAT(site.default_icon_resource, Gt(0)); } #endif } TEST_F(PopularSitesTest, ProvidesDefaultSitesUntilCallbackReturns) { - SetCountryAndVersion("ZZ", "9"); - RespondWithJSON( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json", + SetCountryAndVersion("ZZ", "5"); + RespondWithV5JSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json", {kWikipedia}); scoped_refptr<net::TestURLRequestContextGetter> url_request_context( new net::TestURLRequestContextGetter( @@ -290,20 +338,21 @@ // Assert that callback was scheduled so we can wait for its completion. ASSERT_TRUE(callback_was_scheduled); // There should be 8 default sites as nothing was fetched yet. - EXPECT_THAT(popular_sites->sites().size(), + EXPECT_THAT(popular_sites->sections().at(SectionType::PERSONALIZED).size(), Eq(GetNumberOfDefaultPopularSitesForPlatform())); loop.Run(); // Wait for the fetch to finish and the callback to return. EXPECT_TRUE(save_success.value()); // The 1 fetched site should replace the default sites. - EXPECT_THAT(popular_sites->sites().size(), Eq(1ul)); + EXPECT_THAT(popular_sites->sections(), + ElementsAre(Pair(SectionType::PERSONALIZED, SizeIs(1ul)))); } TEST_F(PopularSitesTest, UsesCachedJson) { - SetCountryAndVersion("ZZ", "9"); - RespondWithJSON( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json", + SetCountryAndVersion("ZZ", "5"); + RespondWithV5JSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json", {kWikipedia}); // First request succeeds and gets cached. @@ -313,17 +362,17 @@ // File disappears from server, but we don't need it because it's cached. RespondWith404( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json"); + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json"); EXPECT_THAT(FetchPopularSites(/*force_download=*/false, &sites), Eq(base::nullopt)); EXPECT_THAT(sites[0].url, URLEq("https://zz.m.wikipedia.org/")); } TEST_F(PopularSitesTest, CachesEmptyFile) { - SetCountryAndVersion("ZZ", "9"); + SetCountryAndVersion("ZZ", "5"); RespondWithData( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json", "[]"); - RespondWithJSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json", "[]"); + RespondWithV5JSON( "https://www.gstatic.com/chrome/ntp/suggested_sites_DEFAULT_5.json", {kWikipedia}); @@ -334,8 +383,8 @@ EXPECT_THAT(sites, IsEmpty()); // File appears on server, but we continue to use our cached empty file. - RespondWithJSON( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json", + RespondWithV5JSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json", {kWikipedia}); EXPECT_THAT(FetchPopularSites(/*force_download=*/false, &sites), Eq(base::nullopt)); @@ -343,9 +392,9 @@ } TEST_F(PopularSitesTest, DoesntUseCachedFileIfDownloadForced) { - SetCountryAndVersion("ZZ", "9"); - RespondWithJSON( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json", + SetCountryAndVersion("ZZ", "5"); + RespondWithV5JSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json", {kWikipedia}); // First request succeeds and gets cached. @@ -355,41 +404,65 @@ EXPECT_THAT(sites[0].url, URLEq("https://zz.m.wikipedia.org/")); // File disappears from server. Download is forced, so we get the new file. - RespondWithJSON( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json", + RespondWithV5JSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json", {kChromium}); EXPECT_THAT(FetchPopularSites(/*force_download=*/true, &sites), Eq(base::Optional<bool>(true))); EXPECT_THAT(sites[0].url, URLEq("https://www.chromium.org/")); } -TEST_F(PopularSitesTest, RefetchesAfterCountryMoved) { - RespondWithJSON( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json", +TEST_F(PopularSitesTest, DoesntUseCacheWithDeprecatedVersion) { + SetCountryAndVersion("ZZ", "5"); + RespondWithV5JSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json", {kWikipedia}); - RespondWithJSON( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZX_9.json", + + // First request succeeds and gets cached. + PopularSites::SitesVector sites; + EXPECT_THAT(FetchPopularSites(/*force_download=*/false, &sites), + Eq(base::Optional<bool>(true))); + EXPECT_THAT(sites[0].url, URLEq("https://zz.m.wikipedia.org/")); + EXPECT_THAT(prefs_->GetInteger(prefs::kPopularSitesVersionPref), Eq(5)); + + // The client is updated to use V6. Drop old data and refetch. + SetCountryAndVersion("ZZ", "6"); + RespondWithV6JSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_6.json", + {{SectionType::PERSONALIZED, {kChromium}}}); + EXPECT_THAT(FetchPopularSites(/*force_download=*/false, &sites), + Eq(base::Optional<bool>(true))); + EXPECT_THAT(sites[0].url, URLEq("https://www.chromium.org/")); + EXPECT_THAT(prefs_->GetInteger(prefs::kPopularSitesVersionPref), Eq(6)); +} + +TEST_F(PopularSitesTest, RefetchesAfterCountryMoved) { + RespondWithV5JSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json", + {kWikipedia}); + RespondWithV5JSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZX_5.json", {kChromium}); PopularSites::SitesVector sites; // First request (in ZZ) saves Wikipedia. - SetCountryAndVersion("ZZ", "9"); + SetCountryAndVersion("ZZ", "5"); EXPECT_THAT(FetchPopularSites(/*force_download=*/false, &sites), Eq(base::Optional<bool>(true))); EXPECT_THAT(sites[0].url, URLEq("https://zz.m.wikipedia.org/")); // Second request (now in ZX) saves Chromium. - SetCountryAndVersion("ZX", "9"); + SetCountryAndVersion("ZX", "5"); EXPECT_THAT(FetchPopularSites(/*force_download=*/false, &sites), base::Optional<bool>(true)); EXPECT_THAT(sites[0].url, URLEq("https://www.chromium.org/")); } TEST_F(PopularSitesTest, DoesntCacheInvalidFile) { - SetCountryAndVersion("ZZ", "9"); + SetCountryAndVersion("ZZ", "5"); RespondWithData( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json", + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json", "ceci n'est pas un json"); RespondWith404( "https://www.gstatic.com/chrome/ntp/suggested_sites_DEFAULT_5.json"); @@ -400,8 +473,8 @@ Eq(base::Optional<bool>(false))); // Second request refetches ZZ_9, which now has data. - RespondWithJSON( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json", + RespondWithV5JSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json", {kChromium}); EXPECT_THAT(FetchPopularSites(/*force_download=*/false, &sites), Eq(base::Optional<bool>(true))); @@ -410,10 +483,10 @@ } TEST_F(PopularSitesTest, RefetchesAfterFallback) { - SetCountryAndVersion("ZZ", "9"); + SetCountryAndVersion("ZZ", "5"); RespondWith404( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json"); - RespondWithJSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json"); + RespondWithV5JSON( "https://www.gstatic.com/chrome/ntp/suggested_sites_DEFAULT_5.json", {kWikipedia}); @@ -425,8 +498,8 @@ EXPECT_THAT(sites[0].url, URLEq("https://zz.m.wikipedia.org/")); // Second request refetches ZZ_9, which now has data. - RespondWithJSON( - "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json", + RespondWithV5JSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_5.json", {kChromium}); EXPECT_THAT(FetchPopularSites(/*force_download=*/false, &sites), Eq(base::Optional<bool>(true))); @@ -435,10 +508,10 @@ } TEST_F(PopularSitesTest, ShouldOverrideDirectory) { - SetCountryAndVersion("ZZ", "9"); + SetCountryAndVersion("ZZ", "5"); prefs_->SetString(prefs::kPopularSitesOverrideDirectory, "foo/bar/"); - RespondWithJSON("https://www.gstatic.com/foo/bar/suggested_sites_ZZ_9.json", - {kWikipedia}); + RespondWithV5JSON("https://www.gstatic.com/foo/bar/suggested_sites_ZZ_5.json", + {kWikipedia}); PopularSites::SitesVector sites; EXPECT_THAT(FetchPopularSites(/*force_download=*/false, &sites), @@ -447,5 +520,64 @@ EXPECT_THAT(sites.size(), Eq(1u)); } +TEST_F(PopularSitesTest, DoesNotFetchExplorationSitesWithoutFeature) { + base::test::ScopedFeatureList override_features; + override_features.InitAndDisableFeature(kSitesExplorationFeature); + + SetCountryAndVersion("ZZ", "6"); + RespondWithV6JSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_6.json", + {{SectionType::PERSONALIZED, {kChromium}}, + {SectionType::NEWS, {kYouTube}}}); + + std::map<SectionType, PopularSites::SitesVector> sections; + EXPECT_THAT(FetchAllSections(/*force_download=*/false, §ions), + Eq(base::Optional<bool>(true))); + + // The fetched news section should not be propagated without enabled feature. + EXPECT_THAT(sections, Not(Contains(Pair(SectionType::NEWS, _)))); +} + +TEST_F(PopularSitesTest, FetchesExplorationSitesWithFeature) { + base::test::ScopedFeatureList override_features; + override_features.InitAndEnableFeature(kSitesExplorationFeature); + SetCountryAndVersion("ZZ", "6"); + RespondWithV6JSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_6.json", + {{SectionType::PERSONALIZED, {kChromium}}, + {SectionType::ENTERTAINMENT, {kWikipedia, kYouTube}}, + {SectionType::NEWS, {kYouTube}}, + {SectionType::TOOLS, TestPopularSiteVector{}}}); + + std::map<SectionType, PopularSites::SitesVector> sections; + EXPECT_THAT(FetchAllSections(/*force_download=*/false, §ions), + Eq(base::Optional<bool>(true))); + + EXPECT_THAT(sections, ElementsAre(Pair(SectionType::PERSONALIZED, SizeIs(1)), + Pair(SectionType::ENTERTAINMENT, SizeIs(2)), + Pair(SectionType::NEWS, SizeIs(1)), + Pair(SectionType::TOOLS, IsEmpty()))); +} + +TEST_F(PopularSitesTest, FetchesExplorationSitesIgnoreUnknownSections) { + base::test::ScopedFeatureList override_features; + override_features.InitAndEnableFeature(kSitesExplorationFeature); + + SetCountryAndVersion("ZZ", "6"); + RespondWithV6JSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_6.json", + {{SectionType::UNKNOWN, {kChromium}}, + {SectionType::NEWS, {kYouTube}}, + {SectionType::UNKNOWN, {kWikipedia, kYouTube}}}); + + std::map<SectionType, PopularSites::SitesVector> sections; + EXPECT_THAT(FetchAllSections(/*force_download=*/false, §ions), + Eq(base::Optional<bool>(true))); + + // Expect that there are four sections, none of which is empty. + EXPECT_THAT(sections, ElementsAre(Pair(SectionType::PERSONALIZED, SizeIs(0)), + Pair(SectionType::NEWS, SizeIs(1)))); +} + } // namespace } // namespace ntp_tiles
diff --git a/components/ntp_tiles/pref_names.cc b/components/ntp_tiles/pref_names.cc index c8839987..409de49b 100644 --- a/components/ntp_tiles/pref_names.cc +++ b/components/ntp_tiles/pref_names.cc
@@ -25,5 +25,11 @@ // If set, this will override the default file version for popular sites. const char kPopularSitesOverrideVersion[] = "popular_sites.override_version"; +// Prefs used to cache suggested sites and store caching meta data. +const char kPopularSitesLastDownloadPref[] = "popular_sites_last_download"; +const char kPopularSitesURLPref[] = "popular_sites_url"; +const char kPopularSitesJsonPref[] = "suggested_sites_json"; +const char kPopularSitesVersionPref[] = "suggested_sites_version"; + } // namespace prefs } // namespace ntp_tiles
diff --git a/components/ntp_tiles/pref_names.h b/components/ntp_tiles/pref_names.h index 9c4de063..687f5577 100644 --- a/components/ntp_tiles/pref_names.h +++ b/components/ntp_tiles/pref_names.h
@@ -15,6 +15,11 @@ extern const char kPopularSitesOverrideCountry[]; extern const char kPopularSitesOverrideVersion[]; +extern const char kPopularSitesLastDownloadPref[]; +extern const char kPopularSitesURLPref[]; +extern const char kPopularSitesJsonPref[]; +extern const char kPopularSitesVersionPref[]; + } // namespace prefs } // namespace ntp_tiles
diff --git a/components/ntp_tiles/section_type.h b/components/ntp_tiles/section_type.h new file mode 100644 index 0000000..f1f9f5c --- /dev/null +++ b/components/ntp_tiles/section_type.h
@@ -0,0 +1,30 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_NTP_TILES_SECTION_TYPE_H_ +#define COMPONENTS_NTP_TILES_SECTION_TYPE_H_ + +namespace ntp_tiles { + +// The type of a section means all its tiles originate here. Ranked descendingly +// from most important section to least important. +// A Java counterpart will be generated for this enum. +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.suggestions +// GENERATED_JAVA_CLASS_NAME_OVERRIDE: TileSectionType +enum class SectionType { + UNKNOWN, + PERSONALIZED, + SOCIAL, + ENTERTAINMENT, + NEWS, + ECOMMERCE, + TOOLS, + TRAVEL, + + LAST = TRAVEL +}; + +} // namespace ntp_tiles + +#endif // COMPONENTS_NTP_TILES_SECTION_TYPE_H_
diff --git a/components/password_manager/core/browser/password_manager_client.h b/components/password_manager/core/browser/password_manager_client.h index 58bc5ed..5f01d31 100644 --- a/components/password_manager/core/browser/password_manager_client.h +++ b/components/password_manager/core/browser/password_manager_client.h
@@ -215,6 +215,9 @@ virtual void CheckProtectedPasswordEntry( const std::string& password_saved_domain, bool password_field_exists) = 0; + + // Records a Chrome Sync event that sync password reuse was detected. + virtual void LogPasswordReuseDetectedEvent() = 0; #endif // Gets the UKM service associated with this client (for metrics).
diff --git a/components/password_manager/core/browser/password_reuse_detection_manager.cc b/components/password_manager/core/browser/password_reuse_detection_manager.cc index 27dd293..2dfc1df2 100644 --- a/components/password_manager/core/browser/password_reuse_detection_manager.cc +++ b/components/password_manager/core/browser/password_reuse_detection_manager.cc
@@ -94,6 +94,11 @@ #if defined(SAFE_BROWSING_DB_LOCAL) // TODO(jialiul): After CSD whitelist being added to Android, we should gate // this by either SAFE_BROWSING_DB_LOCAL or SAFE_BROWSING_DB_REMOTE. + if (!number_matches) { + // |number_matches| == 0 means sync password reuse was detected. + client_->LogPasswordReuseDetectedEvent(); + } + client_->CheckProtectedPasswordEntry(legitimate_domain, password_field_detected); #endif
diff --git a/components/password_manager/core/browser/stub_password_manager_client.cc b/components/password_manager/core/browser/stub_password_manager_client.cc index 14a3cbb..b351cc42 100644 --- a/components/password_manager/core/browser/stub_password_manager_client.cc +++ b/components/password_manager/core/browser/stub_password_manager_client.cc
@@ -80,6 +80,8 @@ void StubPasswordManagerClient::CheckProtectedPasswordEntry( const std::string& password_saved_domain, bool password_field_exists) {} + +void StubPasswordManagerClient::LogPasswordReuseDetectedEvent() {} #endif ukm::UkmRecorder* StubPasswordManagerClient::GetUkmRecorder() {
diff --git a/components/password_manager/core/browser/stub_password_manager_client.h b/components/password_manager/core/browser/stub_password_manager_client.h index a33c7b2c..7e6dbfe3 100644 --- a/components/password_manager/core/browser/stub_password_manager_client.h +++ b/components/password_manager/core/browser/stub_password_manager_client.h
@@ -52,6 +52,7 @@ const GURL& frame_url) override; void CheckProtectedPasswordEntry(const std::string& password_saved_domain, bool password_field_exists) override; + void LogPasswordReuseDetectedEvent() override; #endif ukm::UkmRecorder* GetUkmRecorder() override; ukm::SourceId GetUkmSourceId() override;
diff --git a/components/policy/core/common/policy_loader_win_unittest.cc b/components/policy/core/common/policy_loader_win_unittest.cc index e973049..ee83abf8 100644 --- a/components/policy/core/common/policy_loader_win_unittest.cc +++ b/components/policy/core/common/policy_loader_win_unittest.cc
@@ -311,7 +311,7 @@ // makes sure that tests executing in parallel won't delete each other's // key, at DeleteKeys(). key_name_ = base::ASCIIToUTF16(base::StringPrintf( - "SOFTWARE\\chromium unittest %d", base::GetCurrentProcId())); + "SOFTWARE\\chromium unittest %" CrPRIdPid, base::GetCurrentProcId())); std::wstring hklm_key_name = key_name_ + L"\\HKLM"; std::wstring hkcu_key_name = key_name_ + L"\\HKCU";
diff --git a/components/safe_browsing/features.cc b/components/safe_browsing/features.cc index 560dbc6..190d84f 100644 --- a/components/safe_browsing/features.cc +++ b/components/safe_browsing/features.cc
@@ -39,12 +39,9 @@ const base::Feature kProtectedPasswordEntryPinging{ "ProtectedPasswordEntryPinging", base::FEATURE_ENABLED_BY_DEFAULT}; -// Specifies which non-resource HTML Elements to collect based on their tag and -// attributes. It's a single param containing a comma-separated list of pairs. -// For example: "tag1,id,tag1,height,tag2,foo" - this will collect elements with -// tag "tag1" that have attribute "id" or "height" set, and elements of tag -// "tag2" if they have attribute "foo" set. All tag names and attributes should -// be lower case. +const base::Feature kSyncPasswordReuseEvent{"SyncPasswordReuseEvent", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kThreatDomDetailsTagAndAttributeFeature{ "ThreatDomDetailsTagAttributes", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -66,6 +63,7 @@ {&kPasswordFieldOnFocusPinging, true}, {&kPasswordProtectionInterstitial, false}, {&kProtectedPasswordEntryPinging, true}, + {&kSyncPasswordReuseEvent, true}, {&kThreatDomDetailsTagAndAttributeFeature, false}, {&kV4OnlyEnabled, true}, };
diff --git a/components/safe_browsing/features.h b/components/safe_browsing/features.h index 67f838a..dfd8a38c 100644 --- a/components/safe_browsing/features.h +++ b/components/safe_browsing/features.h
@@ -25,6 +25,14 @@ extern const base::Feature kPasswordFieldOnFocusPinging; extern const base::Feature kPasswordProtectionInterstitial; extern const base::Feature kProtectedPasswordEntryPinging; +// Gates registration for SyncPasswordReuseEvent events. +extern const base::Feature kSyncPasswordReuseEvent; +// Specifies which non-resource HTML Elements to collect based on their tag and +// attributes. It's a single param containing a comma-separated list of pairs. +// For example: "tag1,id,tag1,height,tag2,foo" - this will collect elements with +// tag "tag1" that have attribute "id" or "height" set, and elements of tag +// "tag2" if they have attribute "foo" set. All tag names and attributes should +// be lower case. extern const base::Feature kThreatDomDetailsTagAndAttributeFeature; extern const base::Feature kV4OnlyEnabled;
diff --git a/components/safe_browsing/password_protection/password_protection_service.h b/components/safe_browsing/password_protection/password_protection_service.h index bb841d0..28f79d5 100644 --- a/components/safe_browsing/password_protection/password_protection_service.h +++ b/components/safe_browsing/password_protection/password_protection_service.h
@@ -164,6 +164,10 @@ const std::string& saved_domain, bool password_field_exists); + // Records a Chrome Sync event that sync password reuse was detected. + virtual void MaybeLogPasswordReuseDetectedEvent( + content::WebContents* web_contents) = 0; + scoped_refptr<SafeBrowsingDatabaseManager> database_manager(); // Safe Browsing backend cannot get a reliable reputation of a URL if
diff --git a/components/safe_browsing/password_protection/password_protection_service_unittest.cc b/components/safe_browsing/password_protection/password_protection_service_unittest.cc index eb9a597..62a879b 100644 --- a/components/safe_browsing/password_protection/password_protection_service_unittest.cc +++ b/components/safe_browsing/password_protection/password_protection_service_unittest.cc
@@ -106,6 +106,9 @@ void set_incognito(bool enabled) { is_incognito_ = enabled; } + void MaybeLogPasswordReuseDetectedEvent( + content::WebContents* web_contents) override {} + bool IsPingingEnabled(const base::Feature& feature, RequestOutcome* reason) override { checked_feature_name_ = feature.name;
diff --git a/components/vector_icons/BUILD.gn b/components/vector_icons/BUILD.gn index 3d6eb013..1b8d75b4 100644 --- a/components/vector_icons/BUILD.gn +++ b/components/vector_icons/BUILD.gn
@@ -36,6 +36,7 @@ "reload.icon", "screen_share.icon", "search.icon", + "usb.icon", "videocam.icon", "warning.icon", ]
diff --git a/components/vector_icons/usb.icon b/components/vector_icons/usb.icon new file mode 100644 index 0000000..61d9679 --- /dev/null +++ b/components/vector_icons/usb.icon
@@ -0,0 +1,38 @@ +// Copyright 2018 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. + +MOVE_TO, 30, 14, +R_V_LINE_TO, 8, +R_H_LINE_TO, 2, +R_V_LINE_TO, 4, +R_H_LINE_TO, -6, +V_LINE_TO, 10, +R_H_LINE_TO, 4, +R_LINE_TO, -6, -8, +R_LINE_TO, -6, 8, +R_H_LINE_TO, 4, +R_V_LINE_TO, 16, +R_H_LINE_TO, -6, +R_V_LINE_TO, -4.14f, +R_CUBIC_TO, 1.41f, -0.73f, 2.4f, -2.16f, 2.4f, -3.86f, +R_CUBIC_TO, 0, -2.43f, -1.97f, -4.4f, -4.4f, -4.4f, +R_CUBIC_TO, -2.43f, 0, -4.4f, 1.97f, -4.4f, 4.4f, +R_CUBIC_TO, 0, 1.7f, 0.99f, 3.13f, 2.4f, 3.86f, +V_LINE_TO, 26, +R_CUBIC_TO, 0, 2.21f, 1.79f, 4, 4, 4, +R_H_LINE_TO, 6, +R_V_LINE_TO, 6.1f, +R_CUBIC_TO, -1.42f, 0.73f, -2.4f, 2.19f, -2.4f, 3.9f, +R_CUBIC_TO, 0, 2.43f, 1.97f, 4.4f, 4.4f, 4.4f, +R_CUBIC_TO, 2.43f, 0, 4.4f, -1.97f, 4.4f, -4.4f, +R_CUBIC_TO, 0, -1.71f, -0.98f, -3.17f, -2.4f, -3.9f, +V_LINE_TO, 30, +R_H_LINE_TO, 6, +R_CUBIC_TO, 2.21f, 0, 4, -1.79f, 4, -4, +R_V_LINE_TO, -4, +R_H_LINE_TO, 2, +R_V_LINE_TO, -8, +R_H_LINE_TO, -8, +CLOSE, +END
diff --git a/components/viz/host/host_frame_sink_client.h b/components/viz/host/host_frame_sink_client.h index bd9e8bd..d02f661 100644 --- a/components/viz/host/host_frame_sink_client.h +++ b/components/viz/host/host_frame_sink_client.h
@@ -11,9 +11,9 @@ class HostFrameSinkClient { public: - // Runs when a CompositorFrame is received for the given SurfaceInfo for the - // first time. - virtual void OnSurfaceCreated(const SurfaceInfo& surface_info) = 0; + // Called when a CompositorFrame with a new SurfaceId activates for the first + // time. + virtual void OnFirstSurfaceActivation(const SurfaceInfo& surface_info) = 0; protected: virtual ~HostFrameSinkClient() {}
diff --git a/components/viz/host/host_frame_sink_manager.cc b/components/viz/host/host_frame_sink_manager.cc index d8b5ed7..cc5fa91 100644 --- a/components/viz/host/host_frame_sink_manager.cc +++ b/components/viz/host/host_frame_sink_manager.cc
@@ -165,7 +165,8 @@ frame_sink_manager_->DropTemporaryReference(surface_id); } -void HostFrameSinkManager::OnSurfaceCreated(const SurfaceInfo& surface_info) { +void HostFrameSinkManager::OnFirstSurfaceActivation( + const SurfaceInfo& surface_info) { auto it = frame_sink_data_map_.find(surface_info.id().frame_sink_id()); // If we've received a bogus or stale SurfaceId from Viz then just ignore it. if (it == frame_sink_data_map_.end()) { @@ -177,7 +178,7 @@ FrameSinkData& frame_sink_data = it->second; if (frame_sink_data.client) - frame_sink_data.client->OnSurfaceCreated(surface_info); + frame_sink_data.client->OnFirstSurfaceActivation(surface_info); if (frame_sink_manager_impl_ && frame_sink_manager_impl_->surface_manager()->using_surface_references()) {
diff --git a/components/viz/host/host_frame_sink_manager.h b/components/viz/host/host_frame_sink_manager.h index 0633903..1c8fbe5 100644 --- a/components/viz/host/host_frame_sink_manager.h +++ b/components/viz/host/host_frame_sink_manager.h
@@ -139,7 +139,7 @@ void PerformAssignTemporaryReference(const SurfaceId& surface_id); // mojom::FrameSinkManagerClient: - void OnSurfaceCreated(const SurfaceInfo& surface_info) override; + void OnFirstSurfaceActivation(const SurfaceInfo& surface_info) override; void OnClientConnectionClosed(const FrameSinkId& frame_sink_id) override; void OnAggregatedHitTestRegionListUpdated( const FrameSinkId& frame_sink_id,
diff --git a/components/viz/host/host_frame_sink_manager_unittests.cc b/components/viz/host/host_frame_sink_manager_unittests.cc index b21ba8ab..ba9d3df 100644 --- a/components/viz/host/host_frame_sink_manager_unittests.cc +++ b/components/viz/host/host_frame_sink_manager_unittests.cc
@@ -46,7 +46,7 @@ ~FakeHostFrameSinkClient() override = default; // HostFrameSinkClient implementation. - void OnSurfaceCreated(const SurfaceInfo& surface_info) override {} + void OnFirstSurfaceActivation(const SurfaceInfo& surface_info) override {} private: DISALLOW_COPY_AND_ASSIGN(FakeHostFrameSinkClient); @@ -217,11 +217,12 @@ host_manager().RegisterFrameSinkHierarchy(kParentFrameSinkId, surface_id.frame_sink_id()); - // When HostFrameSinkManager gets OnSurfaceCreated() it should assign the - // temporary reference to the registered parent |kParentFrameSinkId|. + // When HostFrameSinkManager gets OnFirstSurfaceActivation() it should assign + // the temporary reference to the registered parent |kParentFrameSinkId|. EXPECT_CALL(manager_impl(), AssignTemporaryReference(surface_id, kParentFrameSinkId)); - GetFrameSinkManagerClient()->OnSurfaceCreated(MakeSurfaceInfo(surface_id)); + GetFrameSinkManagerClient()->OnFirstSurfaceActivation( + MakeSurfaceInfo(surface_id)); } TEST_F(HostFrameSinkManagerTest, DropTemporaryReference) { @@ -229,10 +230,11 @@ auto support = CreateCompositorFrameSinkSupport(surface_id.frame_sink_id(), false /* is_root */); - // When HostFrameSinkManager gets OnSurfaceCreated() it should find no + // When HostFrameSinkManager gets OnFirstSurfaceActivation() it should find no // registered parent and drop the temporary reference. EXPECT_CALL(manager_impl(), DropTemporaryReference(surface_id)); - GetFrameSinkManagerClient()->OnSurfaceCreated(MakeSurfaceInfo(surface_id)); + GetFrameSinkManagerClient()->OnFirstSurfaceActivation( + MakeSurfaceInfo(surface_id)); } TEST_F(HostFrameSinkManagerTest, DropTemporaryReferenceForStaleClient) { @@ -258,7 +260,7 @@ .Times(0); EXPECT_CALL(manager_impl(), AssignTemporaryReference(client_surface_id, _)) .Times(1); - GetFrameSinkManagerClient()->OnSurfaceCreated( + GetFrameSinkManagerClient()->OnFirstSurfaceActivation( MakeSurfaceInfo(client_surface_id)); testing::Mock::VerifyAndClearExpectations(&manager_impl()); @@ -269,7 +271,7 @@ const SurfaceId client_surface_id2 = MakeSurfaceId(kClientFrameSinkId, 2); EXPECT_CALL(manager_impl(), DropTemporaryReference(client_surface_id2)) .Times(1); - GetFrameSinkManagerClient()->OnSurfaceCreated( + GetFrameSinkManagerClient()->OnFirstSurfaceActivation( MakeSurfaceInfo(client_surface_id2)); support_parent.reset(); @@ -281,11 +283,12 @@ auto support = CreateCompositorFrameSinkSupport(surface_id.frame_sink_id(), true /* is_root */); - // When HostFrameSinkManager gets OnSurfaceCreated() it should do nothing - // since |kParentFrameSinkId| is a display root. + // When HostFrameSinkManager gets OnFirstSurfaceActivation() it should do + // nothing since |kParentFrameSinkId| is a display root. EXPECT_CALL(manager_impl(), DropTemporaryReference(surface_id)).Times(0); EXPECT_CALL(manager_impl(), AssignTemporaryReference(surface_id, _)).Times(0); - GetFrameSinkManagerClient()->OnSurfaceCreated(MakeSurfaceInfo(surface_id)); + GetFrameSinkManagerClient()->OnFirstSurfaceActivation( + MakeSurfaceInfo(surface_id)); } } // namespace test
diff --git a/components/viz/service/display/display_scheduler.cc b/components/viz/service/display/display_scheduler.cc index 3894115..2b52e82 100644 --- a/components/viz/service/display/display_scheduler.cc +++ b/components/viz/service/display/display_scheduler.cc
@@ -277,7 +277,8 @@ NOTIMPLEMENTED(); } -void DisplayScheduler::OnSurfaceCreated(const SurfaceInfo& surface_info) {} +void DisplayScheduler::OnFirstSurfaceActivation( + const SurfaceInfo& surface_info) {} void DisplayScheduler::OnSurfaceDestroyed(const SurfaceId& surface_id) { auto it = surface_states_.find(surface_id);
diff --git a/components/viz/service/display/display_scheduler.h b/components/viz/service/display/display_scheduler.h index 9be510e..d341df0 100644 --- a/components/viz/service/display/display_scheduler.h +++ b/components/viz/service/display/display_scheduler.h
@@ -65,7 +65,7 @@ void OnBeginFrameSourcePausedChanged(bool paused) override; // SurfaceObserver implementation. - void OnSurfaceCreated(const SurfaceInfo& surface_info) override; + void OnFirstSurfaceActivation(const SurfaceInfo& surface_info) override; void OnSurfaceDestroyed(const SurfaceId& surface_id) override; bool OnSurfaceDamaged(const SurfaceId& surface_id, const BeginFrameAck& ack) override;
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc index a451d023..cdddcca 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -60,16 +60,6 @@ void CompositorFrameSinkSupport::OnSurfaceActivated(Surface* surface) { DCHECK(surface->HasActiveFrame()); const cc::CompositorFrame& frame = surface->GetActiveFrame(); - if (!seen_first_frame_activation_) { - // SurfaceCreated only applies for the first Surface activation. - seen_first_frame_activation_ = true; - - gfx::Size frame_size = frame.render_pass_list.back()->output_rect.size(); - surface_manager_->SurfaceCreated(SurfaceInfo( - surface->surface_id(), frame.metadata.device_scale_factor, frame_size)); - } - // Fire SurfaceCreated first so that a temporary reference is added before - // it is potentially transformed into a real reference by the client. DCHECK(surface->active_referenced_surfaces()); UpdateSurfaceReferences(surface->surface_id().local_surface_id(), *surface->active_referenced_surfaces()); @@ -345,7 +335,6 @@ Surface* CompositorFrameSinkSupport::CreateSurface( const SurfaceInfo& surface_info) { - seen_first_frame_activation_ = false; return surface_manager_->CreateSurface( weak_factory_.GetWeakPtr(), surface_info, frame_sink_manager_->GetPrimaryBeginFrameSource(), needs_sync_tokens_);
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.h b/components/viz/service/frame_sinks/compositor_frame_sink_support.h index 0148854..70d13c4 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.h +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.h
@@ -144,7 +144,6 @@ const bool is_root_; const bool needs_sync_tokens_; - bool seen_first_frame_activation_ = false; // A callback that will be run at the start of the destructor if set. base::OnceCallback<void()> destruction_callback_;
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc index 10a10a6..0e07c38 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -320,7 +320,8 @@ return false; } -void FrameSinkManagerImpl::OnSurfaceCreated(const SurfaceInfo& surface_info) { +void FrameSinkManagerImpl::OnFirstSurfaceActivation( + const SurfaceInfo& surface_info) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_GT(surface_info.device_scale_factor(), 0.0f); @@ -330,7 +331,7 @@ // temporary reference was created. It could be useful to let |client_| know // if it should find an owner. if (client_) - client_->OnSurfaceCreated(surface_info); + client_->OnFirstSurfaceActivation(surface_info); } bool FrameSinkManagerImpl::OnSurfaceDamaged(const SurfaceId& surface_id,
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.h b/components/viz/service/frame_sinks/frame_sink_manager_impl.h index 87f7ffe..dae82bf 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.h +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
@@ -112,7 +112,7 @@ SurfaceManager* surface_manager() { return &surface_manager_; } // SurfaceObserver implementation. - void OnSurfaceCreated(const SurfaceInfo& surface_info) override; + void OnFirstSurfaceActivation(const SurfaceInfo& surface_info) override; bool OnSurfaceDamaged(const SurfaceId& surface_id, const BeginFrameAck& ack) override; void OnSurfaceDiscarded(const SurfaceId& surface_id) override;
diff --git a/components/viz/service/hit_test/hit_test_aggregator.h b/components/viz/service/hit_test/hit_test_aggregator.h index b556fa78..b5d68146 100644 --- a/components/viz/service/hit_test/hit_test_aggregator.h +++ b/components/viz/service/hit_test/hit_test_aggregator.h
@@ -48,7 +48,7 @@ protected: // SurfaceObserver: - void OnSurfaceCreated(const SurfaceInfo& surface_info) override {} + void OnFirstSurfaceActivation(const SurfaceInfo& surface_info) override {} void OnSurfaceDestroyed(const SurfaceId& surface_id) override {} bool OnSurfaceDamaged(const SurfaceId& surface_id, const BeginFrameAck& ack) override;
diff --git a/components/viz/service/surfaces/surface.cc b/components/viz/service/surfaces/surface.cc index 78d5b965..4218298 100644 --- a/components/viz/service/surfaces/surface.cc +++ b/components/viz/service/surfaces/surface.cc
@@ -253,6 +253,11 @@ UnrefFrameResourcesAndRunDrawCallback(std::move(previous_frame_data)); + if (!seen_first_frame_activation_) { + seen_first_frame_activation_ = true; + surface_manager_->FirstSurfaceActivation(surface_info_); + } + // TODO(fsamuel): If |surface_client_| is not available then we will not // immediately generate a display frame once the cc::CompositorFrame here // activates. This isn't a major issue though because this would only
diff --git a/components/viz/service/surfaces/surface.h b/components/viz/service/surfaces/surface.h index c8e6405..a75fb8bf3 100644 --- a/components/viz/service/surfaces/surface.h +++ b/components/viz/service/surfaces/surface.h
@@ -251,6 +251,7 @@ base::Optional<FrameData> pending_frame_data_; base::Optional<FrameData> active_frame_data_; bool closed_ = false; + bool seen_first_frame_activation_ = false; const bool needs_sync_tokens_; std::vector<SurfaceSequence> destruction_dependencies_;
diff --git a/components/viz/service/surfaces/surface_manager.cc b/components/viz/service/surfaces/surface_manager.cc index f56ba6ba..3504721 100644 --- a/components/viz/service/surfaces/surface_manager.cc +++ b/components/viz/service/surfaces/surface_manager.cc
@@ -431,11 +431,11 @@ return changed; } -void SurfaceManager::SurfaceCreated(const SurfaceInfo& surface_info) { +void SurfaceManager::FirstSurfaceActivation(const SurfaceInfo& surface_info) { CHECK(thread_checker_.CalledOnValidThread()); for (auto& observer : observer_list_) - observer.OnSurfaceCreated(surface_info); + observer.OnFirstSurfaceActivation(surface_info); } void SurfaceManager::SurfaceActivated(Surface* surface) {
diff --git a/components/viz/service/surfaces/surface_manager.h b/components/viz/service/surfaces/surface_manager.h index 33cb19b..71160b4d 100644 --- a/components/viz/service/surfaces/surface_manager.h +++ b/components/viz/service/surfaces/surface_manager.h
@@ -96,8 +96,7 @@ bool SurfaceModified(const SurfaceId& surface_id, const BeginFrameAck& ack); // Called when a surface has an active frame for the first time. - // TODO(fsamuel,samans): Rename to OnFirstSurfaceActivation. - void SurfaceCreated(const SurfaceInfo& surface_info); + void FirstSurfaceActivation(const SurfaceInfo& surface_info); // Called when a CompositorFrame within |surface| has activated. void SurfaceActivated(Surface* surface);
diff --git a/components/viz/service/surfaces/surface_observer.h b/components/viz/service/surfaces/surface_observer.h index 44fd41d..30e144bb 100644 --- a/components/viz/service/surfaces/surface_observer.h +++ b/components/viz/service/surfaces/surface_observer.h
@@ -14,9 +14,9 @@ class SurfaceObserver { public: - // Runs when a CompositorFrame is activated for the given SurfaceInfo for the - // first time. - virtual void OnSurfaceCreated(const SurfaceInfo& surface_info) = 0; + // Runs when a CompositorFrame with a new SurfaceId activates for the first + // time. + virtual void OnFirstSurfaceActivation(const SurfaceInfo& surface_info) = 0; // Runs when a Surface was marked to be destroyed. virtual void OnSurfaceDestroyed(const SurfaceId& surface_id) = 0;
diff --git a/components/viz/test/fake_surface_observer.cc b/components/viz/test/fake_surface_observer.cc index 44a9b8ae..8b959d3 100644 --- a/components/viz/test/fake_surface_observer.cc +++ b/components/viz/test/fake_surface_observer.cc
@@ -40,7 +40,8 @@ will_draw_surfaces_.insert(surface_id); } -void FakeSurfaceObserver::OnSurfaceCreated(const SurfaceInfo& surface_info) { +void FakeSurfaceObserver::OnFirstSurfaceActivation( + const SurfaceInfo& surface_info) { last_created_surface_id_ = surface_info.id(); last_surface_info_ = surface_info; }
diff --git a/components/viz/test/fake_surface_observer.h b/components/viz/test/fake_surface_observer.h index 3c0a21f..5fc19690 100644 --- a/components/viz/test/fake_surface_observer.h +++ b/components/viz/test/fake_surface_observer.h
@@ -38,7 +38,7 @@ // SurfaceObserver implementation: bool OnSurfaceDamaged(const SurfaceId& surface_id, const BeginFrameAck& ack) override; - void OnSurfaceCreated(const SurfaceInfo& surface_info) override; + void OnFirstSurfaceActivation(const SurfaceInfo& surface_info) override; void OnSurfaceDiscarded(const SurfaceId& surface_id) override {} void OnSurfaceDestroyed(const SurfaceId& surface_id) override {} void OnSurfaceDamageExpected(const SurfaceId& surface_id,
diff --git a/content/browser/accessibility/accessibility_event_recorder_win.cc b/content/browser/accessibility/accessibility_event_recorder_win.cc index 77f6715a6..7f3e626 100644 --- a/content/browser/accessibility/accessibility_event_recorder_win.cc +++ b/content/browser/accessibility/accessibility_event_recorder_win.cc
@@ -250,19 +250,17 @@ if (event == IA2_EVENT_TEXT_REMOVED) { IA2TextSegment old_text; if (SUCCEEDED(accessible_text->get_oldText(&old_text))) { - log += base::StringPrintf(" old_text={'%s' start=%d end=%d}", + log += base::StringPrintf(" old_text={'%s' start=%ld end=%ld}", BstrToUTF8(old_text.text).c_str(), - old_text.start, - old_text.end); + old_text.start, old_text.end); } } if (event == IA2_EVENT_TEXT_INSERTED) { IA2TextSegment new_text; if (SUCCEEDED(accessible_text->get_newText(&new_text))) { - log += base::StringPrintf(" new_text={'%s' start=%d end=%d}", + log += base::StringPrintf(" new_text={'%s' start=%ld end=%ld}", BstrToUTF8(new_text.text).c_str(), - new_text.start, - new_text.end); + new_text.start, new_text.end); } } }
diff --git a/content/browser/devtools/service_worker_devtools_agent_host.cc b/content/browser/devtools/service_worker_devtools_agent_host.cc index 5b8aef5..7e068d9 100644 --- a/content/browser/devtools/service_worker_devtools_agent_host.cc +++ b/content/browser/devtools/service_worker_devtools_agent_host.cc
@@ -68,7 +68,7 @@ std::string ServiceWorkerDevToolsAgentHost::GetTitle() { if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id().first)) { - return base::StringPrintf("Worker pid:%d", + return base::StringPrintf("Worker pid:%" CrPRIdPid, base::GetProcId(host->GetHandle())); } return "";
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index 2ee1738..1129e675 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -420,12 +420,6 @@ pending_entry_ = entry; pending_entry_index_ = current_index; - // The title of the page being reloaded might have been removed in the - // meanwhile, so we need to revert to the default title upon reload and - // invalidate the previously cached title (SetTitle will do both). - // See Chromium issue 96041. - pending_entry_->SetTitle(base::string16()); - pending_entry_->SetTransitionType(ui::PAGE_TRANSITION_RELOAD); }
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc index 44ec4d70..9e3ff07e 100644 --- a/content/browser/frame_host/navigation_controller_impl_unittest.cc +++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -1399,7 +1399,6 @@ EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; ASSERT_TRUE(controller.GetVisibleEntry()); - controller.GetVisibleEntry()->SetTitle(base::ASCIIToUTF16("Title")); entry_id = controller.GetLastCommittedEntry()->GetUniqueID(); controller.Reload(ReloadType::NORMAL, true); @@ -1416,10 +1415,6 @@ EXPECT_TRUE(controller.GetPendingEntry()); EXPECT_FALSE(controller.CanGoBack()); EXPECT_FALSE(controller.CanGoForward()); - // Make sure the title has been cleared (will be redrawn just after reload). - // Avoids a stale cached title when the new page being reloaded has no title. - // See http://crbug.com/96041. - EXPECT_TRUE(controller.GetVisibleEntry()->GetTitle().empty()); main_test_rfh()->PrepareForCommit(); main_test_rfh()->SendNavigate(entry_id, false, url1); @@ -1544,7 +1539,6 @@ EXPECT_EQ(final_url, controller.GetVisibleEntry()->GetURL()); // Reload using the original URL. - controller.GetVisibleEntry()->SetTitle(base::ASCIIToUTF16("Title")); controller.Reload(ReloadType::ORIGINAL_REQUEST_URL, false); EXPECT_EQ(0U, notifications.size()); @@ -1558,11 +1552,6 @@ EXPECT_FALSE(controller.CanGoBack()); EXPECT_FALSE(controller.CanGoForward()); - // Make sure the title has been cleared (will be redrawn just after reload). - // Avoids a stale cached title when the new page being reloaded has no title. - // See http://crbug.com/96041. - EXPECT_TRUE(controller.GetVisibleEntry()->GetTitle().empty()); - // Send that the navigation has proceeded; say it got redirected again. main_test_rfh()->PrepareForCommitWithServerRedirect(final_url); main_test_rfh()->SendNavigate(entry_id, false, final_url);
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc index 712a37d..9a8a794 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.cc +++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -782,7 +782,7 @@ renderer_compositor_frame_sink_->OnBeginFramePausedChanged(paused); } -void RenderWidgetHostViewChildFrame::OnSurfaceCreated( +void RenderWidgetHostViewChildFrame::OnFirstSurfaceActivation( const viz::SurfaceInfo& surface_info) { // TODO(fsamuel): Once surface synchronization is turned on, the fallback // surface should be set here.
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.h b/content/browser/frame_host/render_widget_host_view_child_frame.h index 29abd318..f5a48b1c 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.h +++ b/content/browser/frame_host/render_widget_host_view_child_frame.h
@@ -184,7 +184,7 @@ void OnBeginFramePausedChanged(bool paused) override; // viz::HostFrameSinkClient implementation. - void OnSurfaceCreated(const viz::SurfaceInfo& surface_info) override; + void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override; // Exposed for tests. bool IsChildFrameForTesting() const override;
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 172e1ae..4a6de58 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -938,7 +938,8 @@ frame_sink_id); } -void CompositorImpl::OnSurfaceCreated(const viz::SurfaceInfo& surface_info) { +void CompositorImpl::OnFirstSurfaceActivation( + const viz::SurfaceInfo& surface_info) { // TODO(fsamuel): Once surface synchronization is turned on, the fallback // surface should be set here. }
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h index e601d4d..3e35d57 100644 --- a/content/browser/renderer_host/compositor_impl_android.h +++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -124,7 +124,7 @@ void RemoveChildFrameSink(const viz::FrameSinkId& frame_sink_id) override; // viz::HostFrameSinkClient implementation. - void OnSurfaceCreated(const viz::SurfaceInfo& surface_info) override; + void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override; void SetVisible(bool visible); void CreateLayerTreeHost();
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc index 40577a71..8c0c5a55 100644 --- a/content/browser/renderer_host/delegated_frame_host.cc +++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -513,7 +513,7 @@ renderer_compositor_frame_sink_->OnBeginFramePausedChanged(paused); } -void DelegatedFrameHost::OnSurfaceCreated( +void DelegatedFrameHost::OnFirstSurfaceActivation( const viz::SurfaceInfo& surface_info) { // TODO(fsamuel): Once surface synchronization is turned on, the fallback // surface should be set here.
diff --git a/content/browser/renderer_host/delegated_frame_host.h b/content/browser/renderer_host/delegated_frame_host.h index 5b50b0b..b771339 100644 --- a/content/browser/renderer_host/delegated_frame_host.h +++ b/content/browser/renderer_host/delegated_frame_host.h
@@ -118,7 +118,7 @@ void OnBeginFramePausedChanged(bool paused) override; // viz::HostFrameSinkClient implementation. - void OnSurfaceCreated(const viz::SurfaceInfo& surface_info) override; + void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override; // Public interface exposed to RenderWidgetHostView.
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc index 3641d17..4f422e6 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -284,7 +284,9 @@ mojom::MediaStreamDispatcherPtr dispatcher = mojo::MakeProxy(std::move(dispatcher_info)); - DCHECK(dispatcher.is_bound()); + if (!dispatcher || !dispatcher.is_bound()) + return; + dispatcher->OnStreamGenerated(page_request_id, label, audio_devices, video_devices); dispatchers_[render_frame_id] = std::move(dispatcher); @@ -299,7 +301,9 @@ mojom::MediaStreamDispatcherPtr dispatcher = mojo::MakeProxy(std::move(dispatcher_info)); - DCHECK(dispatcher.is_bound()); + if (!dispatcher || !dispatcher.is_bound()) + return; + dispatcher->OnStreamGenerationFailed(page_request_id, result); dispatchers_[render_frame_id] = std::move(dispatcher); } @@ -314,7 +318,9 @@ mojom::MediaStreamDispatcherPtr dispatcher = mojo::MakeProxy(std::move(dispatcher_info)); - DCHECK(dispatcher.is_bound()); + if (!dispatcher || !dispatcher.is_bound()) + return; + dispatcher->OnDeviceOpened(page_request_id, label, video_device); dispatchers_[render_frame_id] = std::move(dispatcher); } @@ -327,7 +333,9 @@ mojom::MediaStreamDispatcherPtr dispatcher = mojo::MakeProxy(std::move(dispatcher_info)); - DCHECK(dispatcher.is_bound()); + if (!dispatcher || !dispatcher.is_bound()) + return; + dispatcher->OnDeviceOpenFailed(page_request_id); dispatchers_[render_frame_id] = std::move(dispatcher); } @@ -341,7 +349,9 @@ mojom::MediaStreamDispatcherPtr dispatcher = mojo::MakeProxy(std::move(dispatcher_info)); - DCHECK(dispatcher.is_bound()); + if (!dispatcher || !dispatcher.is_bound()) + return; + dispatcher->OnDeviceStopped(label, device); dispatchers_[render_frame_id] = std::move(dispatcher); }
diff --git a/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc b/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc index ba00169d..ed5d7440 100644 --- a/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc +++ b/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc
@@ -55,7 +55,7 @@ private: // blink::mojom::OffscreenCanvasSurfaceClient: - void OnSurfaceCreated(const viz::SurfaceInfo& surface_info) override { + void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override { last_surface_info_ = surface_info; }
diff --git a/content/browser/renderer_host/offscreen_canvas_surface_impl.cc b/content/browser/renderer_host/offscreen_canvas_surface_impl.cc index 233ba348..a23e2fc 100644 --- a/content/browser/renderer_host/offscreen_canvas_surface_impl.cc +++ b/content/browser/renderer_host/offscreen_canvas_surface_impl.cc
@@ -58,13 +58,13 @@ has_created_compositor_frame_sink_ = true; } -void OffscreenCanvasSurfaceImpl::OnSurfaceCreated( +void OffscreenCanvasSurfaceImpl::OnFirstSurfaceActivation( const viz::SurfaceInfo& surface_info) { DCHECK_EQ(surface_info.id().frame_sink_id(), frame_sink_id_); local_surface_id_ = surface_info.id().local_surface_id(); if (client_) - client_->OnSurfaceCreated(surface_info); + client_->OnFirstSurfaceActivation(surface_info); } void OffscreenCanvasSurfaceImpl::Require(const viz::SurfaceId& surface_id,
diff --git a/content/browser/renderer_host/offscreen_canvas_surface_impl.h b/content/browser/renderer_host/offscreen_canvas_surface_impl.h index 5498b76..7845e636 100644 --- a/content/browser/renderer_host/offscreen_canvas_surface_impl.h +++ b/content/browser/renderer_host/offscreen_canvas_surface_impl.h
@@ -53,7 +53,7 @@ viz::mojom::CompositorFrameSinkRequest request); // viz::HostFrameSinkClient implementation. - void OnSurfaceCreated(const viz::SurfaceInfo& surface_info) override; + void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override; // blink::mojom::OffscreenCanvasSurface implementation. void Require(const viz::SurfaceId& surface_id,
diff --git a/content/browser/websockets/websocket_impl.cc b/content/browser/websockets/websocket_impl.cc index 7019bc5..a6eba4d 100644 --- a/content/browser/websockets/websocket_impl.cc +++ b/content/browser/websockets/websocket_impl.cc
@@ -514,14 +514,10 @@ DCHECK(!channel_); - StoragePartition* partition = delegate_->GetStoragePartition(); - std::unique_ptr<net::WebSocketEventInterface> event_interface( new WebSocketEventHandler(this)); - channel_.reset( - new net::WebSocketChannel( - std::move(event_interface), - partition->GetURLRequestContext()->GetURLRequestContext())); + channel_.reset(new net::WebSocketChannel(std::move(event_interface), + delegate_->GetURLRequestContext())); int64_t quota = pending_flow_control_quota_; pending_flow_control_quota_ = 0;
diff --git a/content/browser/websockets/websocket_impl.h b/content/browser/websockets/websocket_impl.h index c6da1316..a64863c 100644 --- a/content/browser/websockets/websocket_impl.h +++ b/content/browser/websockets/websocket_impl.h
@@ -25,11 +25,11 @@ } // namespace url namespace net { +class URLRequestContext; class WebSocketChannel; } // namespace net namespace content { -class StoragePartition; // Host of net::WebSocketChannel. class CONTENT_EXPORT WebSocketImpl @@ -39,7 +39,7 @@ public: virtual ~Delegate() {} virtual int GetClientProcessId() = 0; - virtual StoragePartition* GetStoragePartition() = 0; + virtual net::URLRequestContext* GetURLRequestContext() = 0; virtual void OnReceivedResponseFromServer(WebSocketImpl* impl) = 0; virtual void OnLostConnectionToClient(WebSocketImpl* impl) = 0; };
diff --git a/content/browser/websockets/websocket_manager.cc b/content/browser/websockets/websocket_manager.cc index 081c482..faf4c55 100644 --- a/content/browser/websockets/websocket_manager.cc +++ b/content/browser/websockets/websocket_manager.cc
@@ -90,15 +90,14 @@ WebSocketManager::WebSocketManager(int process_id, StoragePartition* storage_partition) : process_id_(process_id), - storage_partition_(storage_partition), num_pending_connections_(0), num_current_succeeded_connections_(0), num_previous_succeeded_connections_(0), num_current_failed_connections_(0), num_previous_failed_connections_(0), context_destroyed_(false) { - if (storage_partition_) { - url_request_context_getter_ = storage_partition_->GetURLRequestContext(); + if (storage_partition) { + url_request_context_getter_ = storage_partition->GetURLRequestContext(); // This unretained pointer is safe because we destruct a WebSocketManager // only via WebSocketManager::Handle::RenderProcessHostDestroyed which // posts a deletion task to the IO thread. @@ -199,8 +198,8 @@ return process_id_; } -StoragePartition* WebSocketManager::GetStoragePartition() { - return storage_partition_; +net::URLRequestContext* WebSocketManager::GetURLRequestContext() { + return url_request_context_getter_->GetURLRequestContext(); } void WebSocketManager::OnReceivedResponseFromServer(WebSocketImpl* impl) {
diff --git a/content/browser/websockets/websocket_manager.h b/content/browser/websockets/websocket_manager.h index 3e76c99..e42bc17 100644 --- a/content/browser/websockets/websocket_manager.h +++ b/content/browser/websockets/websocket_manager.h
@@ -60,14 +60,13 @@ // WebSocketImpl::Delegate methods: int GetClientProcessId() override; - StoragePartition* GetStoragePartition() override; + net::URLRequestContext* GetURLRequestContext() override; void OnReceivedResponseFromServer(WebSocketImpl* impl) override; void OnLostConnectionToClient(WebSocketImpl* impl) override; void ObserveURLRequestContextGetter(); int process_id_; - StoragePartition* storage_partition_; scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; std::set<WebSocketImpl*> impls_;
diff --git a/content/renderer/pepper/pepper_webplugin_impl.cc b/content/renderer/pepper/pepper_webplugin_impl.cc index e714045..b620da7 100644 --- a/content/renderer/pepper/pepper_webplugin_impl.cc +++ b/content/renderer/pepper/pepper_webplugin_impl.cc
@@ -310,6 +310,17 @@ instance_->ReplaceSelection(""); return true; } + if (name == "Paste") { + if (!CanEditText()) + return false; + + blink::WebString text = + blink::Platform::Current()->Clipboard()->ReadPlainText( + blink::WebClipboard::kBufferStandard); + + instance_->ReplaceSelection(text.Utf8()); + return true; + } return false; }
diff --git a/content/shell/browser/layout_test/blink_test_controller.cc b/content/shell/browser/layout_test/blink_test_controller.cc index 8496853..a4365f0 100644 --- a/content/shell/browser/layout_test/blink_test_controller.cc +++ b/content/shell/browser/layout_test/blink_test_controller.cc
@@ -531,7 +531,7 @@ base::ProcessId plugin_pid) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); printer_->AddErrorMessage( - base::StringPrintf("#CRASHED - plugin (pid %d)", plugin_pid)); + base::StringPrintf("#CRASHED - plugin (pid %" CrPRIdPid ")", plugin_pid)); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(base::IgnoreResult(&BlinkTestController::DiscardMainWindow),
diff --git a/content/shell/browser/shell_browser_main_parts.cc b/content/shell/browser/shell_browser_main_parts.cc index 4928be3..32524409 100644 --- a/content/shell/browser/shell_browser_main_parts.cc +++ b/content/shell/browser/shell_browser_main_parts.cc
@@ -37,7 +37,7 @@ #if defined(OS_ANDROID) #include "base/message_loop/message_loop.h" -#include "components/crash/content/browser/crash_dump_manager_android.h" +#include "components/crash/content/browser/child_process_crash_observer_android.h" #include "components/crash/content/browser/crash_dump_observer_android.h" #include "net/android/network_change_notifier_factory_android.h" #include "net/base/network_change_notifier.h" @@ -174,7 +174,7 @@ base::CommandLine::ForCurrentProcess()->GetSwitchValuePath( switches::kCrashDumpsDir); breakpad::CrashDumpObserver::GetInstance()->RegisterClient( - base::MakeUnique<breakpad::CrashDumpManager>( + base::MakeUnique<breakpad::ChildProcessCrashObserver>( crash_dumps_dir, kAndroidMinidumpDescriptor)); }
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index 33bbcd7..421fe84 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -52,7 +52,7 @@ #if defined(OS_ANDROID) #include "base/android/apk_assets.h" #include "base/android/path_utils.h" -#include "components/crash/content/browser/crash_dump_manager_android.h" +#include "components/crash/content/browser/crash_dump_observer_android.h" #include "content/shell/android/shell_descriptors.h" #endif
diff --git a/content/test/test_render_view_host.cc b/content/test/test_render_view_host.cc index e79f5225..3919f426 100644 --- a/content/test/test_render_view_host.cc +++ b/content/test/test_render_view_host.cc
@@ -220,7 +220,7 @@ return frame_sink_id_; } -void TestRenderWidgetHostView::OnSurfaceCreated( +void TestRenderWidgetHostView::OnFirstSurfaceActivation( const viz::SurfaceInfo& surface_info) { // TODO(fsamuel): Once surface synchronization is turned on, the fallback // surface should be set here.
diff --git a/content/test/test_render_view_host.h b/content/test/test_render_view_host.h index 7a4d22c..1aa6354 100644 --- a/content/test/test_render_view_host.h +++ b/content/test/test_render_view_host.h
@@ -132,7 +132,7 @@ } // viz::HostFrameSinkClient implementation. - void OnSurfaceCreated(const viz::SurfaceInfo& surface_info) override; + void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override; protected: RenderWidgetHostImpl* rwh_;
diff --git a/device/test/usb_test_gadget_impl.cc b/device/test/usb_test_gadget_impl.cc index 4c1c479..2324cd6 100644 --- a/device/test/usb_test_gadget_impl.cc +++ b/device/test/usb_test_gadget_impl.cc
@@ -209,7 +209,8 @@ static uint32_t next_session_id; base::ProcessId process_id = base::GetCurrentProcId(); - session_id_ = base::StringPrintf("%d-%d", process_id, next_session_id++); + session_id_ = + base::StringPrintf("%" CrPRIdPid "-%d", process_id, next_session_id++); observer_.Add(usb_service_); }
diff --git a/extensions/browser/api/BUILD.gn b/extensions/browser/api/BUILD.gn index f2a23a15..6f7f982 100644 --- a/extensions/browser/api/BUILD.gn +++ b/extensions/browser/api/BUILD.gn
@@ -56,6 +56,7 @@ "//extensions/browser/api/display_source", "//extensions/browser/api/dns", "//extensions/browser/api/document_scan", + "//extensions/browser/api/feedback_private", "//extensions/browser/api/file_handlers", "//extensions/browser/api/file_system", "//extensions/browser/api/hid",
diff --git a/extensions/browser/api/extensions_api_client.cc b/extensions/browser/api/extensions_api_client.cc index 7f2c985..89a6b4ca 100644 --- a/extensions/browser/api/extensions_api_client.cc +++ b/extensions/browser/api/extensions_api_client.cc
@@ -116,6 +116,10 @@ return nullptr; } +FeedbackPrivateDelegate* ExtensionsAPIClient::GetFeedbackPrivateDelegate() { + return nullptr; +} + #if defined(OS_CHROMEOS) NonNativeFileSystemDelegate* ExtensionsAPIClient::GetNonNativeFileSystemDelegate() {
diff --git a/extensions/browser/api/extensions_api_client.h b/extensions/browser/api/extensions_api_client.h index 1bc0fdae..133a014 100644 --- a/extensions/browser/api/extensions_api_client.h +++ b/extensions/browser/api/extensions_api_client.h
@@ -35,6 +35,7 @@ class DevicePermissionsPrompt; class ExtensionOptionsGuest; class ExtensionOptionsGuestDelegate; +class FeedbackPrivateDelegate; class FileSystemDelegate; class ManagementAPIDelegate; class MessagingDelegate; @@ -145,6 +146,9 @@ // Returns a delegate for embedder-specific extension messaging. virtual MessagingDelegate* GetMessagingDelegate(); + // Returns a delegate for the chrome.feedbackPrivate API. + virtual FeedbackPrivateDelegate* GetFeedbackPrivateDelegate(); + #if defined(OS_CHROMEOS) // If supported by the embedder, returns a delegate for querying non-native // file systems.
diff --git a/extensions/browser/api/feedback_private/BUILD.gn b/extensions/browser/api/feedback_private/BUILD.gn new file mode 100644 index 0000000..e35051bb --- /dev/null +++ b/extensions/browser/api/feedback_private/BUILD.gn
@@ -0,0 +1,14 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//extensions/features/features.gni") + +assert(enable_extensions, + "Cannot depend on extensions because enable_extensions=false.") + +source_set("feedback_private") { + sources = [ + "feedback_private_delegate.h", + ] +}
diff --git a/extensions/browser/api/feedback_private/OWNERS b/extensions/browser/api/feedback_private/OWNERS new file mode 100644 index 0000000..806a1ce --- /dev/null +++ b/extensions/browser/api/feedback_private/OWNERS
@@ -0,0 +1,4 @@ +afakhry@chromium.org +rkc@chromium.org + +# COMPONENT: Platform>Apps>Feedback
diff --git a/extensions/browser/api/feedback_private/feedback_private_delegate.h b/extensions/browser/api/feedback_private/feedback_private_delegate.h new file mode 100644 index 0000000..feb1f066 --- /dev/null +++ b/extensions/browser/api/feedback_private/feedback_private_delegate.h
@@ -0,0 +1,36 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_BROWSER_API_FEEDBACK_PRIVATE_FEEDBACK_PRIVATE_DELEGATE_H_ +#define EXTENSIONS_BROWSER_API_FEEDBACK_PRIVATE_FEEDBACK_PRIVATE_DELEGATE_H_ + +#include <memory> + +namespace base { +class DictionaryValue; +} // namespace base + +namespace content { +class BrowserContext; +} // namespace content + +namespace extensions { + +// Delegate class for embedder-specific chrome.feedbackPrivate behavior. +class FeedbackPrivateDelegate { + public: + virtual ~FeedbackPrivateDelegate() = default; + + // Returns a dictionary of localized strings for the feedback component + // extension. + // Set |from_crash| to customize strings when the feedback UI was initiated + // from a "sad tab" crash. + virtual std::unique_ptr<base::DictionaryValue> GetStrings( + content::BrowserContext* browser_context, + bool from_crash) const = 0; +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_API_FEEDBACK_PRIVATE_FEEDBACK_PRIVATE_DELEGATE_H_
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index e993a1dc..b4f08d75 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1748,9 +1748,12 @@ void GL_APIENTRY GLES2OverlayPromotionHintCHROMIUM(GLuint texture, GLboolean promotion_hint, GLint display_x, - GLint display_y) { - gles2::GetGLContext()->OverlayPromotionHintCHROMIUM(texture, promotion_hint, - display_x, display_y); + GLint display_y, + GLint display_width, + GLint display_height) { + gles2::GetGLContext()->OverlayPromotionHintCHROMIUM( + texture, promotion_hint, display_x, display_y, display_width, + display_height); } void GL_APIENTRY GLES2SwapBuffersWithBoundsCHROMIUM(GLsizei count, const GLint* rects) {
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index d01ff052..adf0baa 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -3225,11 +3225,14 @@ void OverlayPromotionHintCHROMIUM(GLuint texture, GLboolean promotion_hint, GLint display_x, - GLint display_y) { + GLint display_y, + GLint display_width, + GLint display_height) { gles2::cmds::OverlayPromotionHintCHROMIUM* c = GetCmdSpace<gles2::cmds::OverlayPromotionHintCHROMIUM>(); if (c) { - c->Init(texture, promotion_hint, display_x, display_y); + c->Init(texture, promotion_hint, display_x, display_y, display_width, + display_height); } }
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 83c311a1..220e26d 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1225,7 +1225,9 @@ void OverlayPromotionHintCHROMIUM(GLuint texture, GLboolean promotion_hint, GLint display_x, - GLint display_y) override; + GLint display_y, + GLint display_width, + GLint display_height) override; void SwapBuffersWithBoundsCHROMIUM(GLsizei count, const GLint* rects) override;
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index 2be26ed..055575a 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -3512,14 +3512,18 @@ void GLES2Implementation::OverlayPromotionHintCHROMIUM(GLuint texture, GLboolean promotion_hint, GLint display_x, - GLint display_y) { + GLint display_y, + GLint display_width, + GLint display_height) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glOverlayPromotionHintCHROMIUM(" << texture << ", " << GLES2Util::GetStringBool(promotion_hint) << ", " - << display_x << ", " << display_y << ")"); + << display_x << ", " << display_y << ", " << display_width + << ", " << display_height << ")"); helper_->OverlayPromotionHintCHROMIUM(texture, promotion_hint, display_x, - display_y); + display_y, display_width, + display_height); CheckGLError(); }
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index abb8788..6c2a551 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -909,7 +909,9 @@ virtual void OverlayPromotionHintCHROMIUM(GLuint texture, GLboolean promotion_hint, GLint display_x, - GLint display_y) = 0; + GLint display_y, + GLint display_width, + GLint display_height) = 0; virtual void SwapBuffersWithBoundsCHROMIUM(GLsizei count, const GLint* rects) = 0; virtual void SetDrawRectangleCHROMIUM(GLint x,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 512aa16..dbe13d1 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -883,7 +883,9 @@ void OverlayPromotionHintCHROMIUM(GLuint texture, GLboolean promotion_hint, GLint display_x, - GLint display_y) override; + GLint display_y, + GLint display_width, + GLint display_height) override; void SwapBuffersWithBoundsCHROMIUM(GLsizei count, const GLint* rects) override; void SetDrawRectangleCHROMIUM(GLint x, GLint y,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index fc8d4f7..abdbd078 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -1188,7 +1188,9 @@ GLuint /* texture */, GLboolean /* promotion_hint */, GLint /* display_x */, - GLint /* display_y */) {} + GLint /* display_y */, + GLint /* display_width */, + GLint /* display_height */) {} void GLES2InterfaceStub::SwapBuffersWithBoundsCHROMIUM( GLsizei /* count */, const GLint* /* rects */) {}
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index b529546..bdcc2ef 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -883,7 +883,9 @@ void OverlayPromotionHintCHROMIUM(GLuint texture, GLboolean promotion_hint, GLint display_x, - GLint display_y) override; + GLint display_y, + GLint display_width, + GLint display_height) override; void SwapBuffersWithBoundsCHROMIUM(GLsizei count, const GLint* rects) override; void SetDrawRectangleCHROMIUM(GLint x, GLint y,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 12d3986..b0cf7a8b 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -2533,11 +2533,13 @@ GLuint texture, GLboolean promotion_hint, GLint display_x, - GLint display_y) { + GLint display_y, + GLint display_width, + GLint display_height) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::OverlayPromotionHintCHROMIUM"); gl_->OverlayPromotionHintCHROMIUM(texture, promotion_hint, display_x, - display_y); + display_y, display_width, display_height); } void GLES2TraceImplementation::SwapBuffersWithBoundsCHROMIUM(
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index 56890d3..d285480d 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -364,7 +364,7 @@ // Extension CHROMIUM_stream_texture_matrix GL_APICALL void GL_APIENTRY glUniformMatrix4fvStreamTextureMatrixCHROMIUM (GLintUniformLocation location, GLbooleanFalseOnly transpose, const GLfloat* transform); -GL_APICALL void GL_APIENTRY glOverlayPromotionHintCHROMIUM (GLidBindTexture texture, GLboolean promotion_hint, GLint display_x, GLint display_y); +GL_APICALL void GL_APIENTRY glOverlayPromotionHintCHROMIUM (GLidBindTexture texture, GLboolean promotion_hint, GLint display_x, GLint display_y, GLint display_width, GLint display_height); GL_APICALL void GL_APIENTRY glSwapBuffersWithBoundsCHROMIUM (GLsizei count, const GLint* rects);
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index b01d1fa..8ea10c5 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -15846,21 +15846,28 @@ void Init(GLuint _texture, GLboolean _promotion_hint, GLint _display_x, - GLint _display_y) { + GLint _display_y, + GLint _display_width, + GLint _display_height) { SetHeader(); texture = _texture; promotion_hint = _promotion_hint; display_x = _display_x; display_y = _display_y; + display_width = _display_width; + display_height = _display_height; } void* Set(void* cmd, GLuint _texture, GLboolean _promotion_hint, GLint _display_x, - GLint _display_y) { + GLint _display_y, + GLint _display_width, + GLint _display_height) { static_cast<ValueType*>(cmd)->Init(_texture, _promotion_hint, _display_x, - _display_y); + _display_y, _display_width, + _display_height); return NextCmdAddress<ValueType>(cmd); } @@ -15869,10 +15876,12 @@ uint32_t promotion_hint; int32_t display_x; int32_t display_y; + int32_t display_width; + int32_t display_height; }; -static_assert(sizeof(OverlayPromotionHintCHROMIUM) == 20, - "size of OverlayPromotionHintCHROMIUM should be 20"); +static_assert(sizeof(OverlayPromotionHintCHROMIUM) == 28, + "size of OverlayPromotionHintCHROMIUM should be 28"); static_assert(offsetof(OverlayPromotionHintCHROMIUM, header) == 0, "offset of OverlayPromotionHintCHROMIUM header should be 0"); static_assert(offsetof(OverlayPromotionHintCHROMIUM, texture) == 4, @@ -15884,6 +15893,12 @@ "offset of OverlayPromotionHintCHROMIUM display_x should be 12"); static_assert(offsetof(OverlayPromotionHintCHROMIUM, display_y) == 16, "offset of OverlayPromotionHintCHROMIUM display_y should be 16"); +static_assert( + offsetof(OverlayPromotionHintCHROMIUM, display_width) == 20, + "offset of OverlayPromotionHintCHROMIUM display_width should be 20"); +static_assert( + offsetof(OverlayPromotionHintCHROMIUM, display_height) == 24, + "offset of OverlayPromotionHintCHROMIUM display_height should be 24"); struct SwapBuffersWithBoundsCHROMIUMImmediate { typedef SwapBuffersWithBoundsCHROMIUMImmediate ValueType;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index 3a06ce1e..8e1d11c 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -5297,7 +5297,8 @@ *GetBufferAs<cmds::OverlayPromotionHintCHROMIUM>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLboolean>(12), - static_cast<GLint>(13), static_cast<GLint>(14)); + static_cast<GLint>(13), static_cast<GLint>(14), + static_cast<GLint>(15), static_cast<GLint>(16)); EXPECT_EQ(static_cast<uint32_t>(cmds::OverlayPromotionHintCHROMIUM::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); @@ -5305,6 +5306,8 @@ EXPECT_EQ(static_cast<GLboolean>(12), cmd.promotion_hint); EXPECT_EQ(static_cast<GLint>(13), cmd.display_x); EXPECT_EQ(static_cast<GLint>(14), cmd.display_y); + EXPECT_EQ(static_cast<GLint>(15), cmd.display_width); + EXPECT_EQ(static_cast<GLint>(16), cmd.display_height); CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); }
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index 246090b1..b6a91d8 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -1915,6 +1915,18 @@ 0x8AF0, "GL_TEXTURE_FILTERING_HINT_CHROMIUM", }, { + 0x8AF1, "GL_COLOR_SPACE_UNSPECIFIED_CHROMIUM", + }, + { + 0x8AF2, "GL_COLOR_SPACE_SCRGB_LINEAR_CHROMIUM", + }, + { + 0x8AF3, "GL_COLOR_SPACE_SRGB_CHROMIUM", + }, + { + 0x8AF4, "GL_COLOR_SPACE_DISPLAY_P3_CHROMIUM", + }, + { 0x8B30, "GL_FRAGMENT_SHADER", }, {
diff --git a/gpu/command_buffer/service/gl_stream_texture_image.h b/gpu/command_buffer/service/gl_stream_texture_image.h index 5ab4f75..b040da8 100644 --- a/gpu/command_buffer/service/gl_stream_texture_image.h +++ b/gpu/command_buffer/service/gl_stream_texture_image.h
@@ -27,7 +27,9 @@ virtual void NotifyPromotionHint(bool promotion_hint, int display_x, - int display_y) {} + int display_y, + int display_width, + int display_height) {} protected: ~GLStreamTextureImage() override {}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 0df37b0..f525b24 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1711,7 +1711,9 @@ void DoOverlayPromotionHintCHROMIUM(GLuint client_id, GLboolean promotion_hint, GLint display_x, - GLint display_y); + GLint display_y, + GLint display_width, + GLint display_height); // Wrapper for glSetDrawRectangleCHROMIUM void DoSetDrawRectangleCHROMIUM(GLint x, GLint y, GLint width, GLint height); @@ -8825,7 +8827,9 @@ void GLES2DecoderImpl::DoOverlayPromotionHintCHROMIUM(GLuint client_id, GLboolean promotion_hint, GLint display_x, - GLint display_y) { + GLint display_y, + GLint display_width, + GLint display_height) { if (client_id == 0) return; @@ -8844,7 +8848,8 @@ return; } - image->NotifyPromotionHint(promotion_hint != GL_FALSE, display_x, display_y); + image->NotifyPromotionHint(promotion_hint != GL_FALSE, display_x, display_y, + display_width, display_height); } void GLES2DecoderImpl::DoSetDrawRectangleCHROMIUM(GLint x,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index fef99fa..8cd6cd21 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -5129,7 +5129,10 @@ GLboolean promotion_hint = static_cast<GLboolean>(c.promotion_hint); GLint display_x = static_cast<GLint>(c.display_x); GLint display_y = static_cast<GLint>(c.display_y); - DoOverlayPromotionHintCHROMIUM(texture, promotion_hint, display_x, display_y); + GLint display_width = static_cast<GLint>(c.display_width); + GLint display_height = static_cast<GLint>(c.display_height); + DoOverlayPromotionHintCHROMIUM(texture, promotion_hint, display_x, display_y, + display_width, display_height); return error::kNoError; }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h index 17d0a0a..9c4d670 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
@@ -980,7 +980,9 @@ error::Error DoOverlayPromotionHintCHROMIUM(GLuint texture, GLboolean promotion_hint, GLint display_x, - GLint display_y); + GLint display_y, + GLint display_width, + GLint display_height); error::Error DoSetDrawRectangleCHROMIUM(GLint x, GLint y, GLint width,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc index e6994df..bd0656e 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -4216,7 +4216,9 @@ GLuint texture, GLboolean promotion_hint, GLint display_x, - GLint display_y) { + GLint display_y, + GLint display_width, + GLint display_height) { NOTIMPLEMENTED(); return error::kNoError; }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc index 8a2d17d..2256a806 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
@@ -4336,8 +4336,11 @@ GLboolean promotion_hint = static_cast<GLboolean>(c.promotion_hint); GLint display_x = static_cast<GLint>(c.display_x); GLint display_y = static_cast<GLint>(c.display_y); - error::Error error = DoOverlayPromotionHintCHROMIUM(texture, promotion_hint, - display_x, display_y); + GLint display_width = static_cast<GLint>(c.display_width); + GLint display_height = static_cast<GLint>(c.display_height); + error::Error error = + DoOverlayPromotionHintCHROMIUM(texture, promotion_hint, display_x, + display_y, display_width, display_height); if (error != error::kNoError) { return error; }
diff --git a/headless/BUILD.gn b/headless/BUILD.gn index 0b15edd..b27bf3b 100644 --- a/headless/BUILD.gn +++ b/headless/BUILD.gn
@@ -223,7 +223,7 @@ extra_deps = [ ":gen_devtools_client_api" ] } -if (headless_fontconfig_utils && !is_fuchsia) { +if (headless_fontconfig_utils) { static_library("headless_fontconfig_utils") { sources = [ "public/util/fontconfig.cc",
diff --git a/headless/public/util/generic_url_request_job.cc b/headless/public/util/generic_url_request_job.cc index fbf5490..73162804 100644 --- a/headless/public/util/generic_url_request_job.cc +++ b/headless/public/util/generic_url_request_job.cc
@@ -280,6 +280,13 @@ return true; } +namespace { +void CompletionCallback(int* dest, base::Closure* quit_closure, int value) { + *dest = value; + quit_closure->Run(); +} +} // namespace + std::string GenericURLRequestJob::GetPostData() const { if (!request_->has_upload()) return ""; @@ -292,11 +299,80 @@ return ""; DCHECK_EQ(1u, stream->GetElementReaders()->size()); - const net::UploadBytesElementReader* reader = - (*stream->GetElementReaders())[0]->AsBytesReader(); - if (!reader) - return ""; - return std::string(reader->bytes(), reader->length()); + const std::unique_ptr<net::UploadElementReader>& reader = + (*stream->GetElementReaders())[0]; + // If |reader| is actually an UploadBytesElementReader we can get the data + // directly (should be faster than the horrible stuff below). + const net::UploadBytesElementReader* bytes_reader = reader->AsBytesReader(); + if (bytes_reader) + return std::string(bytes_reader->bytes(), bytes_reader->length()); + + // TODO(alexclarke): Consider changing the interface of + // GenericURLRequestJob::GetPostData to use a callback which would let us + // avoid the nested run loops below. + + // Initialize the reader. + { + base::Closure quit_closure; + int init_result = reader->Init( + base::Bind(&CompletionCallback, &init_result, &quit_closure)); + if (init_result == net::ERR_IO_PENDING) { + base::RunLoop nested_run_loop; + base::MessageLoop::ScopedNestableTaskAllower allow_nested( + base::MessageLoop::current()); + quit_closure = nested_run_loop.QuitClosure(); + nested_run_loop.Run(); + } + + if (init_result != net::OK) + return ""; + } + + // Read the POST bytes. + uint64_t content_length = reader->GetContentLength(); + std::string post_data; + post_data.reserve(content_length); + const size_t block_size = 1024; + scoped_refptr<net::IOBuffer> read_buffer(new net::IOBuffer(block_size)); + while (post_data.size() < content_length) { + base::Closure quit_closure; + int bytes_read = reader->Read( + read_buffer.get(), block_size, + base::Bind(&CompletionCallback, &bytes_read, &quit_closure)); + + if (bytes_read == net::ERR_IO_PENDING) { + base::MessageLoop::ScopedNestableTaskAllower allow_nested( + base::MessageLoop::current()); + base::RunLoop nested_run_loop; + quit_closure = nested_run_loop.QuitClosure(); + nested_run_loop.Run(); + } + + // Bail out if an error occured. + if (bytes_read < 0) + return ""; + + post_data.append(read_buffer->data(), bytes_read); + } + + return post_data; +} + +uint64_t GenericURLRequestJob::GetPostDataSize() const { + if (!request_->has_upload()) + return 0; + + const net::UploadDataStream* stream = request_->get_upload(); + if (!stream->GetElementReaders()) + return 0; + + if (stream->GetElementReaders()->size() == 0) + return 0; + + DCHECK_EQ(1u, stream->GetElementReaders()->size()); + const std::unique_ptr<net::UploadElementReader>& reader = + (*stream->GetElementReaders())[0]; + return reader->GetContentLength(); } const Request* GenericURLRequestJob::GetRequest() const {
diff --git a/headless/public/util/generic_url_request_job.h b/headless/public/util/generic_url_request_job.h index 3a66ca6..59be8b8 100644 --- a/headless/public/util/generic_url_request_job.h +++ b/headless/public/util/generic_url_request_job.h
@@ -51,6 +51,9 @@ // Gets the POST data, if any, from the net::URLRequest. virtual std::string GetPostData() const = 0; + // Returns the size of the POST data, if any, from the net::URLRequest. + virtual uint64_t GetPostDataSize() const = 0; + enum class ResourceType { MAIN_FRAME = 0, SUB_FRAME = 1, @@ -192,6 +195,7 @@ int GetFrameTreeNodeId() const override; std::string GetDevToolsAgentHostId() const override; std::string GetPostData() const override; + uint64_t GetPostDataSize() const override; ResourceType GetResourceType() const override; bool IsAsync() const override;
diff --git a/headless/public/util/generic_url_request_job_test.cc b/headless/public/util/generic_url_request_job_test.cc index d2d9879..e14a20d 100644 --- a/headless/public/util/generic_url_request_job_test.cc +++ b/headless/public/util/generic_url_request_job_test.cc
@@ -664,16 +664,107 @@ })"; std::string post_data; + uint64_t post_data_size; job_delegate_.SetPolicy(base::Bind( - [](std::string* post_data, PendingRequest* pending_request) { + [](std::string* post_data, uint64_t* post_data_size, + PendingRequest* pending_request) { *post_data = pending_request->GetRequest()->GetPostData(); + *post_data_size = pending_request->GetRequest()->GetPostDataSize(); pending_request->AllowRequest(); }, - &post_data)); + &post_data, &post_data_size)); CreateAndCompletePostJob(GURL("https://example.com"), "payload", reply); EXPECT_EQ("payload", post_data); + EXPECT_EQ(post_data_size, post_data.size()); +} + +namespace { +class ByteAtATimeUploadElementReader : public net::UploadElementReader { + public: + explicit ByteAtATimeUploadElementReader(const std::string& content) + : content_(content) {} + + // net::UploadElementReader implementation: + int Init(const net::CompletionCallback& callback) override { + offset_ = 0; + return net::OK; + } + + uint64_t GetContentLength() const override { return content_.size(); } + + uint64_t BytesRemaining() const override { return content_.size() - offset_; } + + bool IsInMemory() const override { return false; } + + int Read(net::IOBuffer* buf, + int buf_length, + const net::CompletionCallback& callback) override { + if (!BytesRemaining()) + return net::OK; + + base::MessageLoop::current()->task_runner()->PostTask( + FROM_HERE, base::Bind(&ByteAtATimeUploadElementReader::ReadImpl, + base::Unretained(this), make_scoped_refptr(buf), + buf_length, callback)); + return net::ERR_IO_PENDING; + } + + private: + void ReadImpl(scoped_refptr<net::IOBuffer> buf, + int buf_length, + const net::CompletionCallback callback) { + if (BytesRemaining()) { + *buf->data() = content_[offset_++]; + callback.Run(1u); + } else { + callback.Run(0u); + } + } + + std::string content_; + uint64_t offset_ = 0; +}; +} // namespace + +TEST_F(GenericURLRequestJobTest, GetPostDataAsync) { + std::string json_reply = R"( + { + "url": "https://example.com", + "http_response_code": 200, + "data": "Reply", + "headers": { + "Content-Type": "text/html; charset=UTF-8" + } + })"; + + std::string post_data; + uint64_t post_data_size; + job_delegate_.SetPolicy(base::Bind( + [](std::string* post_data, uint64_t* post_data_size, + PendingRequest* pending_request) { + *post_data = pending_request->GetRequest()->GetPostData(); + *post_data_size = pending_request->GetRequest()->GetPostDataSize(); + pending_request->AllowRequest(); + }, + &post_data, &post_data_size)); + + GURL url("https://example.com"); + std::unique_ptr<net::URLRequest> request(url_request_context_.CreateRequest( + url, net::DEFAULT_PRIORITY, &request_delegate_, + TRAFFIC_ANNOTATION_FOR_TESTS)); + request->set_method("POST"); + + json_fetch_reply_map_[url.spec()] = json_reply; + + request->set_upload(net::ElementsUploadDataStream::CreateWithReader( + base::MakeUnique<ByteAtATimeUploadElementReader>("payload"), 0)); + request->Start(); + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ("payload", post_data); + EXPECT_EQ(post_data_size, post_data.size()); } } // namespace headless
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm index 62ba5f74..876dbe43 100644 --- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
@@ -65,9 +65,6 @@ LAYOUT_COMPACT, }; -// Alpha threshold upon which a view is considered hidden. -const CGFloat kHiddenAlphaThreshold = 0.1; - // Minimum duration of the pending state in milliseconds. const int64_t kMinimunPendingStateDurationMs = 300; @@ -109,20 +106,6 @@ DONE_STATE, }; -// Fades in |button| on screen if not already visible. -void ShowButton(UIButton* button) { - if (button.alpha > kHiddenAlphaThreshold) - return; - button.alpha = 1.0; -} - -// Fades out |button| on screen if not already hidden. -void HideButton(UIButton* button) { - if (button.alpha < kHiddenAlphaThreshold) - return; - button.alpha = 0.0; -} - } // namespace @interface ChromeSigninViewController ()< @@ -504,14 +487,22 @@ [_secondaryButton setTitle:self.skipSigninButtonTitle forState:UIControlStateNormal]; [self.view setNeedsLayout]; - - HideButton(_primaryButton); - HideButton(_secondaryButton); - [UIView animateWithDuration:kAnimationDuration - animations:^{ - ShowButton(_primaryButton); - ShowButton(_secondaryButton); - }]; + _primaryButton.hidden = YES; + _secondaryButton.hidden = YES; + [UIView transitionWithView:_primaryButton + duration:kAnimationDuration + options:UIViewAnimationOptionTransitionCrossDissolve + animations:^{ + _primaryButton.hidden = NO; + } + completion:nil]; + [UIView transitionWithView:_secondaryButton + duration:kAnimationDuration + options:UIViewAnimationOptionTransitionCrossDissolve + animations:^{ + _secondaryButton.hidden = NO; + } + completion:nil]; } - (void)reloadIdentityPickerState { @@ -522,10 +513,18 @@ } - (void)leaveIdentityPickerState:(AuthenticationState)nextState { - [UIView animateWithDuration:kAnimationDuration + [UIView transitionWithView:_primaryButton + duration:kAnimationDuration + options:UIViewAnimationOptionTransitionCrossDissolve + animations:^{ + _primaryButton.hidden = YES; + } + completion:nil]; + [UIView transitionWithView:_secondaryButton + duration:kAnimationDuration + options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ - HideButton(_primaryButton); - HideButton(_secondaryButton); + _secondaryButton.hidden = YES; } completion:^(BOOL finished) { [_accountSelectorVC willMoveToParentViewController:nil]; @@ -544,7 +543,7 @@ [self.view setNeedsLayout]; _pendingStateTimer.reset(new base::ElapsedTimer()); - ShowButton(_secondaryButton); + _secondaryButton.hidden = NO; [_activityIndicator startAnimating]; [self signIntoIdentity:self.selectedIdentity]; @@ -621,15 +620,22 @@ [_secondaryButton setTitle:secondaryButtonTitle forState:UIControlStateNormal]; [self.view setNeedsLayout]; - - HideButton(_primaryButton); - HideButton(_secondaryButton); - [UIView animateWithDuration:kAnimationDuration - animations:^{ - ShowButton(_primaryButton); - ShowButton(_secondaryButton); - } - completion:nil]; + _primaryButton.hidden = YES; + _secondaryButton.hidden = YES; + [UIView transitionWithView:_primaryButton + duration:kAnimationDuration + options:UIViewAnimationOptionTransitionCrossDissolve + animations:^{ + _primaryButton.hidden = NO; + } + completion:nil]; + [UIView transitionWithView:_secondaryButton + duration:kAnimationDuration + options:UIViewAnimationOptionTransitionCrossDissolve + animations:^{ + _secondaryButton.hidden = NO; + } + completion:nil]; } - (void)reloadIdentitySelectedState { @@ -648,8 +654,8 @@ [_confirmationVC removeFromParentViewController]; _confirmationVC = nil; [self setPrimaryButtonStyling:_primaryButton]; - HideButton(_primaryButton); - HideButton(_secondaryButton); + _primaryButton.hidden = YES; + _secondaryButton.hidden = YES; [self undoSignIn]; [self enterState:nextState]; } @@ -665,7 +671,7 @@ [_primaryButton addTarget:self action:@selector(onPrimaryButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; - HideButton(_primaryButton); + _primaryButton.hidden = YES; [self.view addSubview:_primaryButton]; _secondaryButton = [[MDCFlatButton alloc] init]; @@ -674,7 +680,7 @@ action:@selector(onSecondaryButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; [_secondaryButton setAccessibilityIdentifier:@"ic_close"]; - HideButton(_secondaryButton); + _secondaryButton.hidden = YES; [self.view addSubview:_secondaryButton]; _activityIndicator = [[MDCActivityIndicator alloc] initWithFrame:CGRectZero];
diff --git a/ios/chrome/browser/ui/history/history_ui_egtest.mm b/ios/chrome/browser/ui/history/history_ui_egtest.mm index 2723762a..51b4feed 100644 --- a/ios/chrome/browser/ui/history/history_ui_egtest.mm +++ b/ios/chrome/browser/ui/history/history_ui_egtest.mm
@@ -133,36 +133,6 @@ id<GREYMatcher> ConfirmClearBrowsingDataButton() { return ButtonWithAccessibilityLabelId(IDS_IOS_CONFIRM_CLEAR_BUTTON); } - -// Sign in with a mock identity. -void MockSignIn() { - // Set up a mock identity. - ChromeIdentity* identity = - [FakeChromeIdentity identityWithEmail:@"foo@gmail.com" - gaiaID:@"fooID" - name:@"Fake Foo"]; - ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()->AddIdentity( - identity); - - [ChromeEarlGreyUI openSettingsMenu]; - [[EarlGrey - selectElementWithMatcher:grey_accessibilityID(kSettingsSignInCellId)] - performAction:grey_tap()]; - [[EarlGrey - selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabel( - identity.userEmail)] - performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher: - chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_SIGNIN_BUTTON)] - performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher: - chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OK_BUTTON)] - performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:NavigationBarDoneButton()] - performAction:grey_tap()]; -} } // namespace // History UI tests. @@ -276,12 +246,6 @@ // in, and that tapping on the link in the message opens a new tab with the sync // help page. - (void)testHistoryEntriesStatusCell { - // TODO(crbug.com/747445): Re-enable this test on iOS 11 once the sign in UI - // is fixed. - if (base::ios::IsRunningOnIOS11OrLater()) { - EARL_GREY_TEST_DISABLED(@"Disabled on iOS 11."); - } - [self loadTestURLs]; [self openHistoryPanel]; // Assert that no message is shown when the user is not signed in. @@ -293,9 +257,21 @@ [[EarlGrey selectElementWithMatcher:NavigationBarDoneButton()] performAction:grey_tap()]; - // Sign in and assert that the page indicates what type of history entries - // are shown. - MockSignIn(); + // Mock sign in and assert that the page indicates what type of history + // entries are shown. + ChromeIdentity* identity = + [FakeChromeIdentity identityWithEmail:@"foo@gmail.com" + gaiaID:@"fooID" + name:@"Fake Foo"]; + ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()->AddIdentity( + identity); + [ChromeEarlGreyUI openSettingsMenu]; + [ChromeEarlGreyUI tapSettingsMenuButton:chrome_test_util::SignInMenuButton()]; + [ChromeEarlGreyUI signInToIdentityByEmail:identity.userEmail]; + [ChromeEarlGreyUI confirmSigninConfirmationDialog]; + [[EarlGrey selectElementWithMatcher:NavigationBarDoneButton()] + performAction:grey_tap()]; + [self openHistoryPanel]; // Assert that message about entries is shown. The "history is showing local // entries" message will be shown because sync is not set up for this test.
diff --git a/ios/chrome/browser/ui/ntp/ntp_tile.h b/ios/chrome/browser/ui/ntp/ntp_tile.h index 4bd2784..b65e609 100644 --- a/ios/chrome/browser/ui/ntp/ntp_tile.h +++ b/ios/chrome/browser/ui/ntp/ntp_tile.h
@@ -16,7 +16,7 @@ // The most visited site's URL. @property(readonly, atomic) NSURL* URL; // The filename of the most visited site's favicon on disk, if it exists. -@property(strong, atomic) NSString* faviconPath; +@property(strong, atomic) NSString* faviconFileName; // The fallback text color for the most visited site, if it exists. @property(strong, atomic) UIColor* fallbackTextColor; // The fallback background color for the most visited site, if it exists. @@ -24,18 +24,26 @@ // Whether the fallback background color for the most visited site is the // default color. @property(assign, atomic) BOOL fallbackIsDefaultColor; +// The monogram to use on the fallback icon. +@property(strong, atomic) NSString* fallbackMonogram; // Whether the favicon has been fetched for the most visited site. This can be // YES with no fallback values or favicon path. @property(assign, atomic) BOOL faviconFetched; +// Index of the site's position in the most visited list. +@property(assign, atomic) NSUInteger position; -- (instancetype)initWithTitle:(NSString*)title URL:(NSURL*)URL; - (instancetype)initWithTitle:(NSString*)title URL:(NSURL*)URL - faviconPath:(NSString*)faviconPath + position:(NSUInteger)position; +- (instancetype)initWithTitle:(NSString*)title + URL:(NSURL*)URL + faviconFileName:(NSString*)faviconFileName fallbackTextColor:(UIColor*)fallbackTextColor fallbackBackgroundColor:(UIColor*)fallbackTextColor fallbackIsDefaultColor:(BOOL)fallbackIsDefaultColor - faviconFetched:(BOOL)faviconFetched; + fallbackMonogram:(NSString*)fallbackMonogram + faviconFetched:(BOOL)faviconFetched + position:(NSUInteger)position; @end #endif // IOS_CHROME_BROWSER_UI_NTP_NTP_TILE_H_
diff --git a/ios/chrome/browser/ui/ntp/ntp_tile.mm b/ios/chrome/browser/ui/ntp/ntp_tile.mm index 2686e49..d319a1bc 100644 --- a/ios/chrome/browser/ui/ntp/ntp_tile.mm +++ b/ios/chrome/browser/ui/ntp/ntp_tile.mm
@@ -7,48 +7,59 @@ namespace { NSString* kTitleKey = @"title"; NSString* kURLKey = @"URL"; -NSString* kFaviconPathKey = @"faviconPath"; +NSString* kfaviconFileNameKey = @"faviconFileName"; NSString* kFallbackTextColorKey = @"fallbackTextColor"; NSString* kFallbackBackgroundColorKey = @"fallbackBackgroundColor"; NSString* kFallbackIsDefaultColorKey = @"fallbackIsDefaultColor"; +NSString* kFallbackMonogram = @"fallbackMonogram"; NSString* kFaviconFetched = @"faviconFetched"; +NSString* kPosition = @"position"; } @implementation NTPTile @synthesize title = _title; @synthesize URL = _URL; -@synthesize faviconPath = _faviconPath; +@synthesize faviconFileName = _faviconFileName; @synthesize fallbackTextColor = _fallbackTextColor; @synthesize fallbackBackgroundColor = _fallbackBackgroundColor; @synthesize fallbackIsDefaultColor = _fallbackIsDefaultColor; +@synthesize fallbackMonogram = _fallbackMonogram; @synthesize faviconFetched = _faviconFetched; +@synthesize position = _position; -- (instancetype)initWithTitle:(NSString*)title URL:(NSURL*)URL { +- (instancetype)initWithTitle:(NSString*)title + URL:(NSURL*)URL + position:(NSUInteger)position { self = [super init]; if (self) { _title = title; _URL = URL; + _position = position; } return self; } - (instancetype)initWithTitle:(NSString*)title URL:(NSURL*)URL - faviconPath:(NSString*)faviconPath + faviconFileName:(NSString*)faviconFileName fallbackTextColor:(UIColor*)fallbackTextColor fallbackBackgroundColor:(UIColor*)fallbackBackgroundColor fallbackIsDefaultColor:(BOOL)fallbackIsDefaultColor - faviconFetched:(BOOL)faviconFetched { + fallbackMonogram:(NSString*)fallbackMonogram + faviconFetched:(BOOL)faviconFetched + position:(NSUInteger)position { self = [super init]; if (self) { _title = title; _URL = URL; - _faviconPath = faviconPath; + _faviconFileName = faviconFileName; _fallbackTextColor = fallbackTextColor; _fallbackBackgroundColor = fallbackBackgroundColor; _fallbackIsDefaultColor = fallbackIsDefaultColor; + _fallbackMonogram = fallbackMonogram; _faviconFetched = faviconFetched; + _position = position; } return self; } @@ -56,26 +67,32 @@ - (instancetype)initWithCoder:(NSCoder*)aDecoder { return [self initWithTitle:[aDecoder decodeObjectForKey:kTitleKey] URL:[aDecoder decodeObjectForKey:kURLKey] - faviconPath:[aDecoder decodeObjectForKey:kFaviconPathKey] + faviconFileName:[aDecoder decodeObjectForKey:kfaviconFileNameKey] fallbackTextColor:[aDecoder decodeObjectForKey:kFallbackTextColorKey] fallbackBackgroundColor: [aDecoder decodeObjectForKey:kFallbackBackgroundColorKey] fallbackIsDefaultColor:[aDecoder decodeBoolForKey:kFallbackIsDefaultColorKey] - faviconFetched:[aDecoder decodeBoolForKey:kFaviconFetched]]; + fallbackMonogram:[aDecoder decodeObjectForKey:kFallbackMonogram] + faviconFetched:[aDecoder decodeBoolForKey:kFaviconFetched] + position:[[aDecoder decodeObjectForKey:kPosition] + unsignedIntegerValue]]; } - (void)encodeWithCoder:(NSCoder*)aCoder { [aCoder encodeObject:self.title forKey:kTitleKey]; [aCoder encodeObject:self.URL forKey:kURLKey]; - [aCoder encodeObject:self.faviconPath forKey:kFaviconPathKey]; + [aCoder encodeObject:self.faviconFileName forKey:kfaviconFileNameKey]; [aCoder encodeObject:self.fallbackTextColor forKey:kFallbackTextColorKey]; [aCoder encodeObject:self.fallbackBackgroundColor forKey:kFallbackBackgroundColorKey]; [aCoder encodeBool:self.fallbackIsDefaultColor forKey:kFallbackIsDefaultColorKey]; + [aCoder encodeObject:self.fallbackMonogram forKey:kFallbackMonogram]; [aCoder encodeBool:self.faviconFetched forKey:kFaviconFetched]; + [aCoder encodeObject:[NSNumber numberWithUnsignedInteger:self.position] + forKey:kPosition]; } @end
diff --git a/ios/chrome/browser/ui/ntp/ntp_tile_saver.mm b/ios/chrome/browser/ui/ntp/ntp_tile_saver.mm index 9d18aa87..37b88113 100644 --- a/ios/chrome/browser/ui/ntp/ntp_tile_saver.mm +++ b/ios/chrome/browser/ui/ntp/ntp_tile_saver.mm
@@ -6,6 +6,7 @@ #include "base/md5.h" #include "base/strings/sys_string_conversions.h" +#include "components/favicon/core/fallback_url_util.h" #include "components/ntp_tiles/ntp_tile.h" #import "ios/chrome/browser/ui/ntp/google_landing_data_source.h" #import "ios/chrome/browser/ui/ntp/ntp_tile.h" @@ -52,6 +53,12 @@ if ([[NSFileManager defaultManager] fileExistsAtPath:[TmpFaviconFolderPath() path]]) { + [[NSFileManager defaultManager] + createDirectoryAtURL:faviconsURL.URLByDeletingLastPathComponent + withIntermediateDirectories:YES + attributes:nil + error:nil]; + [[NSFileManager defaultManager] moveItemAtURL:TmpFaviconFolderPath() toURL:faviconsURL error:nil]; @@ -82,6 +89,7 @@ if (faviconsURL == nil) { return; } + NSMutableDictionary<NSURL*, NTPTile*>* tiles = [[NSMutableDictionary alloc] init]; @@ -100,14 +108,16 @@ // WriteToDiskIfComplete after each callback execution. // All the sites are added first to the list so that the WriteToDiskIfComplete // command is not passed an incomplete list. - for (const ntp_tiles::NTPTile& ntpTile : mostVisitedData) { + for (size_t i = 0; i < mostVisitedData.size(); i++) { + const ntp_tiles::NTPTile& ntpTile = mostVisitedData[i]; NTPTile* tile = [[NTPTile alloc] initWithTitle:base::SysUTF16ToNSString(ntpTile.title) - URL:net::NSURLWithGURL(ntpTile.url)]; + URL:net::NSURLWithGURL(ntpTile.url) + position:i]; [tiles setObject:tile forKey:tile.URL]; } - for (NTPTile* tile : [tiles objectEnumerator]) { + for (__block NTPTile* tile : [tiles objectEnumerator]) { const GURL& gurl = net::GURLWithNSURL(tile.URL); NSString* faviconFileName = GetFaviconFileName(gurl); NSURL* fileURL = @@ -117,7 +127,7 @@ tile.faviconFetched = YES; NSData* imageData = UIImagePNGRepresentation(favicon); if ([imageData writeToURL:fileURL atomically:YES]) { - tile.faviconPath = faviconFileName; + tile.faviconFileName = faviconFileName; } WriteToDiskIfComplete(tiles, faviconsURL); }; @@ -128,6 +138,8 @@ tile.fallbackTextColor = textColor; tile.fallbackBackgroundColor = backgroundColor; tile.fallbackIsDefaultColor = isDefaultColor; + tile.fallbackMonogram = base::SysUTF16ToNSString( + favicon::GetFallbackIconText(net::GURLWithNSURL(tile.URL))); WriteToDiskIfComplete(tiles, faviconsURL); }; @@ -150,8 +162,7 @@ void WriteSavedMostVisited(NSDictionary<NSURL*, NTPTile*>* mostVisitedSites) { NSData* data = [NSKeyedArchiver archivedDataWithRootObject:mostVisitedSites]; - NSUserDefaults* sharedDefaults = - [[NSUserDefaults alloc] initWithSuiteName:app_group::ApplicationGroup()]; + NSUserDefaults* sharedDefaults = app_group::GetGroupUserDefaults(); [sharedDefaults setObject:data forKey:app_group::kSuggestedItems]; // TODO(crbug.com/750673): Update the widget's visibility depending on @@ -159,8 +170,7 @@ } NSDictionary* ReadSavedMostVisited() { - NSUserDefaults* sharedDefaults = - [[NSUserDefaults alloc] initWithSuiteName:app_group::ApplicationGroup()]; + NSUserDefaults* sharedDefaults = app_group::GetGroupUserDefaults(); return [NSKeyedUnarchiver unarchiveObjectWithData:[sharedDefaults @@ -181,20 +191,25 @@ tile.fallbackTextColor = nil; tile.fallbackBackgroundColor = nil; tile.faviconFetched = NO; - NSString* faviconPath = tile.faviconPath; - tile.faviconPath = nil; + NSString* previousFaviconFileName = tile.faviconFileName; + tile.faviconFileName = nil; // Fetch favicon and update saved defaults. NSString* faviconFileName = GetFaviconFileName(siteURL); NSURL* fileURL = [faviconsURL URLByAppendingPathComponent:faviconFileName]; + NSURL* previousFileURL = + previousFaviconFileName + ? [faviconsURL URLByAppendingPathComponent:previousFaviconFileName] + : nil; + NSString* monogram = + base::SysUTF16ToNSString(favicon::GetFallbackIconText(siteURL)); void (^faviconImageBlock)(UIImage*) = ^(UIImage* favicon) { tile.faviconFetched = YES; NSData* imageData = UIImagePNGRepresentation(favicon); + [[NSFileManager defaultManager] removeItemAtURL:previousFileURL error:nil]; if ([imageData writeToURL:fileURL atomically:YES]) { - tile.faviconPath = faviconFileName; - } else { - [[NSFileManager defaultManager] removeItemAtPath:faviconPath error:nil]; + tile.faviconFileName = faviconFileName; } WriteSingleUpdatedTileToDisk(tile); }; @@ -205,7 +220,9 @@ tile.fallbackTextColor = textColor; tile.fallbackBackgroundColor = backgroundColor; tile.fallbackIsDefaultColor = isDefaultColor; - [[NSFileManager defaultManager] removeItemAtPath:faviconPath error:nil]; + tile.fallbackMonogram = monogram; + [[NSFileManager defaultManager] removeItemAtURL:previousFileURL + error:nil]; WriteSingleUpdatedTileToDisk(tile); };
diff --git a/ios/chrome/browser/ui/ntp/ntp_tile_saver_unittest.mm b/ios/chrome/browser/ui/ntp/ntp_tile_saver_unittest.mm index 8e5ea62..4ba1ad7 100644 --- a/ios/chrome/browser/ui/ntp/ntp_tile_saver_unittest.mm +++ b/ios/chrome/browser/ui/ntp/ntp_tile_saver_unittest.mm
@@ -79,12 +79,12 @@ EXPECT_NSEQ(tile.title, expectedTitle); EXPECT_NSEQ(tile.URL, expectedURL); EXPECT_TRUE(tile.faviconFetched); - EXPECT_NSNE(tile.faviconPath, nil); + EXPECT_NSNE(tile.faviconFileName, nil); EXPECT_NSEQ(tile.fallbackTextColor, nil); EXPECT_NSEQ(tile.fallbackBackgroundColor, nil); EXPECT_TRUE([[NSFileManager defaultManager] fileExistsAtPath:[[testFaviconDirectory() - URLByAppendingPathComponent:tile.faviconPath] + URLByAppendingPathComponent:tile.faviconFileName] path]]); } @@ -95,7 +95,7 @@ EXPECT_NSEQ(tile.title, expectedTitle); EXPECT_NSEQ(tile.URL, expectedURL); EXPECT_TRUE(tile.faviconFetched); - EXPECT_NSEQ(tile.faviconPath, nil); + EXPECT_NSEQ(tile.faviconFileName, nil); EXPECT_NSEQ(tile.fallbackTextColor, UIColor.whiteColor); EXPECT_NSEQ(tile.fallbackBackgroundColor, UIColor.blueColor); EXPECT_EQ(tile.fallbackIsDefaultColor, NO);
diff --git a/ios/chrome/browser/web/progress_indicator_egtest.mm b/ios/chrome/browser/web/progress_indicator_egtest.mm index f3205a0..dc18070 100644 --- a/ios/chrome/browser/web/progress_indicator_egtest.mm +++ b/ios/chrome/browser/web/progress_indicator_egtest.mm
@@ -4,7 +4,6 @@ #import <EarlGrey/EarlGrey.h> -#include "base/ios/ios_util.h" #include "base/mac/foundation_util.h" #include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" @@ -166,11 +165,6 @@ EARL_GREY_TEST_SKIPPED(@"Skipped for iPad (no progress view in tablet)"); } - // TODO(crbug.com/747442): Re-enable this test once the bug is fixed. - if (base::ios::IsRunningOnIOS11OrLater()) { - EARL_GREY_TEST_DISABLED(@"Disabled on iOS 11."); - } - const GURL formURL = web::test::HttpServer::MakeUrl(kFormURL); const GURL infinitePendingURL = web::test::HttpServer::MakeUrl(kInfinitePendingPageURL); @@ -206,11 +200,6 @@ EARL_GREY_TEST_SKIPPED(@"Skipped for iPad (no progress view in tablet)"); } - // TODO(crbug.com/747442): Re-enable this test once the bug is fixed. - if (base::ios::IsRunningOnIOS11OrLater()) { - EARL_GREY_TEST_DISABLED(@"Disabled on iOS 11."); - } - const GURL formURL = web::test::HttpServer::MakeUrl(kFormURL); const GURL simplePageURL = web::test::HttpServer::MakeUrl(kSimplePageURL);
diff --git a/ios/chrome/content_widget_extension/content_widget_view.h b/ios/chrome/content_widget_extension/content_widget_view.h index 450bdd35..f9de690 100644 --- a/ios/chrome/content_widget_extension/content_widget_view.h +++ b/ios/chrome/content_widget_extension/content_widget_view.h
@@ -7,6 +7,18 @@ #import <UIKit/UIKit.h> +@class MostVisitedTileView; +@class NTPTile; + +// Protocol to be implemented by targets for user actions coming from the +// content widget view. +@protocol ContentWidgetViewDelegate + +// Called when tapping a tile to open |URL|. +- (void)openURL:(NSURL*)URL; + +@end + // View for the content widget. Shows 1 (compact view) or 2 (full size view) // rows of 4 most visited tiles (favicon or fallback + title), if there are // enough tiles to show. If there are fewer than 4 tiles, always displays a @@ -16,11 +28,12 @@ // The height of the widget in expanded mode. @property(nonatomic, readonly) CGFloat widgetExpandedHeight; -// Designated initializer, creates the widget view. |compactHeight| indicates -// the size to use in compact display. |initiallyCompact| indicates which mode -// to display on initialization. -- (instancetype)initWithCompactHeight:(CGFloat)compactHeight - initiallyCompact:(BOOL)compact NS_DESIGNATED_INITIALIZER; +// Designated initializer, creates the widget view with a |delegate| for user +// actions. |compactHeight| indicates the size to use in compact display. +// |initiallyCompact| indicates which mode to display on initialization. +- (instancetype)initWithDelegate:(id<ContentWidgetViewDelegate>)delegate + compactHeight:(CGFloat)compactHeight + initiallyCompact:(BOOL)compact NS_DESIGNATED_INITIALIZER; - (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; - (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE; @@ -31,6 +44,10 @@ // within the |compactHeight| passed in the constructor. - (void)showMode:(BOOL)compact; +// Updates the displayed sites. |sites| should contain NTPTiles with continuous +// positions starting at 0. +- (void)updateSites:(NSDictionary<NSURL*, NTPTile*>*)sites; + @end #endif // IOS_CHROME_CONTENT_WIDGET_EXTENSION_CONTENT_WIDGET_VIEW_H_
diff --git a/ios/chrome/content_widget_extension/content_widget_view.mm b/ios/chrome/content_widget_extension/content_widget_view.mm index dab4fab6..ae7f9313 100644 --- a/ios/chrome/content_widget_extension/content_widget_view.mm +++ b/ios/chrome/content_widget_extension/content_widget_view.mm
@@ -4,8 +4,11 @@ #import "ios/chrome/content_widget_extension/content_widget_view.h" +#include "base/logging.h" #import "ios/chrome/browser/ui/favicon/favicon_view.h" +#import "ios/chrome/browser/ui/ntp/ntp_tile.h" #import "ios/chrome/browser/ui/util/constraints_ui_util.h" +#include "ios/chrome/common/app_group/app_group_constants.h" #import "ios/chrome/content_widget_extension/most_visited_tile_view.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -19,6 +22,9 @@ const CGFloat kTileHeight = 100; // Icons to show per row. const int kIconsPerRow = 4; +// Number of rows in the widget. Note that modifying this value will not add +// extra rows and will break functionality unless additional changes are made. +const int kRows = 2; } @interface ContentWidgetView () @@ -37,13 +43,17 @@ @property(nonatomic, readonly) BOOL shouldShowSecondRow; // The number of sites to display. @property(nonatomic, assign) int siteCount; +// The most visited tile views; tiles remain in this array even when hidden. +@property(nonatomic, strong) NSArray<MostVisitedTileView*>* mostVisitedTiles; +// The delegate for actions in the view. +@property(nonatomic, weak) id<ContentWidgetViewDelegate> delegate; // Sets up the widget UI for an expanded or compact appearance based on // |compact|. - (void)createUI:(BOOL)compact; -// Creates the view for a row of 4 sites. -- (UIView*)createRowOfSites; +// Arranges |tiles| horizontally in a view and returns the view. +- (UIView*)createRowFromTiles:(NSArray<MostVisitedTileView*>*)tiles; // Returns the height to use for the first row, depending on the display mode. - (CGFloat)firstRowHeight:(BOOL)compact; @@ -52,6 +62,9 @@ // be shown). - (CGFloat)secondRowHeight; +// Opens the |mostVisitedTile|'s url, using the delegate. +- (void)openURLFromMostVisited:(MostVisitedTileView*)mostVisitedTile; + @end @implementation ContentWidgetView @@ -61,11 +74,16 @@ @synthesize compactHeight = _compactHeight; @synthesize firstRowHeightConstraint = _firstRowHeightConstraint; @synthesize siteCount = _siteCount; +@synthesize mostVisitedTiles = _mostVisitedTiles; +@synthesize delegate = _delegate; -- (instancetype)initWithCompactHeight:(CGFloat)compactHeight - initiallyCompact:(BOOL)compact { +- (instancetype)initWithDelegate:(id<ContentWidgetViewDelegate>)delegate + compactHeight:(CGFloat)compactHeight + initiallyCompact:(BOOL)compact { self = [super initWithFrame:CGRectZero]; if (self) { + DCHECK(delegate); + _delegate = delegate; _compactHeight = compactHeight; [self createUI:compact]; } @@ -85,8 +103,18 @@ #pragma mark - UI creation - (void)createUI:(BOOL)compact { - _firstRow = [self createRowOfSites]; - _secondRow = [self createRowOfSites]; + NSMutableArray* tiles = [[NSMutableArray alloc] init]; + for (int i = 0; i < kIconsPerRow * kRows; i++) { + [tiles addObject:[[MostVisitedTileView alloc] init]]; + } + _mostVisitedTiles = tiles; + + _firstRow = [self + createRowFromTiles:[tiles + subarrayWithRange:NSMakeRange(0, kIconsPerRow)]]; + _secondRow = [self + createRowFromTiles:[tiles subarrayWithRange:NSMakeRange(kIconsPerRow, + kIconsPerRow)]]; [self addSubview:_firstRow]; [self addSubview:_secondRow]; @@ -105,14 +133,8 @@ ]]; } -- (UIView*)createRowOfSites { - NSMutableArray<MostVisitedTileView*>* cells = [[NSMutableArray alloc] init]; - for (int i = 0; i < kIconsPerRow; i++) { - cells[i] = [[MostVisitedTileView alloc] init]; - cells[i].translatesAutoresizingMaskIntoConstraints = NO; - } - - UIStackView* stack = [[UIStackView alloc] initWithArrangedSubviews:cells]; +- (UIView*)createRowFromTiles:(NSArray<MostVisitedTileView*>*)tiles { + UIStackView* stack = [[UIStackView alloc] initWithArrangedSubviews:tiles]; stack.translatesAutoresizingMaskIntoConstraints = NO; stack.axis = UILayoutConstraintAxisHorizontal; stack.alignment = UIStackViewAlignmentTop; @@ -134,19 +156,73 @@ return container; } +- (void)updateSites:(NSDictionary<NSURL*, NTPTile*>*)sites { + for (NTPTile* site in sites.objectEnumerator) { + // If the site's position is > the # of tiles shown, there is no tile to + // update. Remember that sites is a dictionary and is not ordered by + // position. + if (static_cast<NSUInteger>(site.position) > self.mostVisitedTiles.count) { + continue; + } + MostVisitedTileView* tileView = self.mostVisitedTiles[site.position]; + tileView.titleLabel.text = site.title; + tileView.URL = site.URL; + + FaviconAttributes* attributes = nil; + + if (site.faviconFileName) { + NSURL* filePath = [app_group::ContentWidgetFaviconsFolder() + URLByAppendingPathComponent:site.faviconFileName]; + UIImage* faviconImage = [UIImage imageWithContentsOfFile:filePath.path]; + if (faviconImage) { + attributes = [FaviconAttributes attributesWithImage:faviconImage]; + } + } else { + attributes = [FaviconAttributes + attributesWithMonogram:site.fallbackMonogram + textColor:site.fallbackTextColor + backgroundColor:site.fallbackBackgroundColor + defaultBackgroundColor:site.fallbackIsDefaultColor]; + } + [tileView.faviconView configureWithAttributes:attributes]; + tileView.alpha = 1; + tileView.userInteractionEnabled = YES; + [tileView addTarget:self + action:@selector(openURLFromMostVisited:) + forControlEvents:UIControlEventTouchUpInside]; + tileView.accessibilityLabel = site.title; + } + + self.siteCount = sites.count; + [self hideEmptyTiles]; +} + +- (void)openURLFromMostVisited:(MostVisitedTileView*)mostVisitedTile { + [self.delegate openURL:mostVisitedTile.URL]; +} + +- (void)hideEmptyTiles { + for (int i = self.siteCount; i < kRows * kIconsPerRow; i++) { + self.mostVisitedTiles[i].alpha = 0; + self.mostVisitedTiles[i].userInteractionEnabled = NO; + } +} + - (CGFloat)firstRowHeight:(BOOL)compact { if (compact) { return self.compactHeight; } - CGFloat firstRowHeight = kTileHeight + 2 * kTileSpacing; + CGFloat firstRowHeight = kTileHeight + kRows * kTileSpacing; CGFloat secondRowHeight = [self secondRowHeight]; CGFloat totalHeight = firstRowHeight + secondRowHeight; - if (totalHeight >= self.compactHeight) { + if (totalHeight > self.compactHeight) { return firstRowHeight; } - return self.compactHeight - secondRowHeight; + // The expanded height should be strictly greater than compactHeight, + // otherwise iOS does not update the UI correctly. + return self.compactHeight - secondRowHeight + 1; } - (CGFloat)secondRowHeight {
diff --git a/ios/chrome/content_widget_extension/content_widget_view_controller.mm b/ios/chrome/content_widget_extension/content_widget_view_controller.mm index f3de0bd..8e2557ed 100644 --- a/ios/chrome/content_widget_extension/content_widget_view_controller.mm +++ b/ios/chrome/content_widget_extension/content_widget_view_controller.mm
@@ -13,6 +13,7 @@ #import "ios/chrome/browser/ui/util/constraints_ui_util.h" #include "ios/chrome/common/app_group/app_group_constants.h" #include "ios/chrome/content_widget_extension/content_widget_view.h" +#import "ios/chrome/content_widget_extension/most_visited_tile_view.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -27,7 +28,7 @@ const CGFloat widgetCompactHeightIOS9 = 110; } // namespace -@interface ContentWidgetViewController () +@interface ContentWidgetViewController ()<ContentWidgetViewDelegate> @property(nonatomic, strong) NSDictionary<NSURL*, NTPTile*>* sites; @property(nonatomic, weak) ContentWidgetView* widgetView; @property(nonatomic, readonly) BOOL isCompact; @@ -35,8 +36,8 @@ // Updates the widget with latest data. Returns whether any visual updates // occurred. - (BOOL)updateWidget; -// Opens the main application with the given |URL|. -- (void)openAppWithURL:(NSString*)URL; +// Expand the widget. +- (void)setExpanded:(CGSize)maxSize; @end @implementation ContentWidgetViewController @@ -47,8 +48,9 @@ #pragma mark - properties - (BOOL)isCompact { - return [self.extensionContext widgetActiveDisplayMode] == - NCWidgetDisplayModeCompact; + return base::ios::IsRunningOnIOS10OrLater() && + [self.extensionContext widgetActiveDisplayMode] == + NCWidgetDisplayModeCompact; } #pragma mark - UIViewController @@ -57,7 +59,7 @@ [super viewDidLoad]; CGFloat height = - self.extensionContext + self.extensionContext && base::ios::IsRunningOnIOS10OrLater() ? [self.extensionContext widgetMaximumSizeForDisplayMode:NCWidgetDisplayModeCompact] .height @@ -66,25 +68,23 @@ // A local variable is necessary here as the property is declared weak and the // object would be deallocated before being retained by the addSubview call. ContentWidgetView* widgetView = - [[ContentWidgetView alloc] initWithCompactHeight:height - initiallyCompact:self.isCompact]; + [[ContentWidgetView alloc] initWithDelegate:self + compactHeight:height + initiallyCompact:self.isCompact]; self.widgetView = widgetView; [self.view addSubview:self.widgetView]; if (base::ios::IsRunningOnIOS10OrLater()) { self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded; + } else { + [self setExpanded:[[UIScreen mainScreen] bounds].size]; } self.widgetView.translatesAutoresizingMaskIntoConstraints = NO; AddSameConstraints(self.widgetView, self.view); } -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - [self updateWidget]; -} - - (void)widgetPerformUpdateWithCompletionHandler: (void (^)(NCUpdateResult))completionHandler { completionHandler([self updateWidget] ? NCUpdateResultNewData @@ -113,8 +113,7 @@ self.preferredContentSize = maxSize; break; case NCWidgetDisplayModeExpanded: - self.preferredContentSize = - CGSizeMake(maxSize.width, [self.widgetView widgetExpandedHeight]); + [self setExpanded:maxSize]; break; } } @@ -130,22 +129,30 @@ #pragma mark - internal +- (void)setExpanded:(CGSize)maxSize { + [self updateWidget]; + self.preferredContentSize = + CGSizeMake(maxSize.width, + MIN([self.widgetView widgetExpandedHeight], maxSize.height)); +} + - (BOOL)updateWidget { - NSUserDefaults* sharedDefaults = - [[NSUserDefaults alloc] initWithSuiteName:app_group::ApplicationGroup()]; + NSUserDefaults* sharedDefaults = app_group::GetGroupUserDefaults(); NSDictionary<NSURL*, NTPTile*>* newSites = [NSKeyedUnarchiver unarchiveObjectWithData:[sharedDefaults objectForKey:app_group::kSuggestedItems]]; - if (newSites == self.sites) { + if ([newSites isEqualToDictionary:self.sites]) { return NO; } self.sites = newSites; + [self.widgetView updateSites:self.sites]; return YES; } -- (void)openAppWithURL:(NSString*)URL { - NSUserDefaults* sharedDefaults = - [[NSUserDefaults alloc] initWithSuiteName:app_group::ApplicationGroup()]; +#pragma mark - ContentWidgetViewDelegate + +- (void)openURL:(NSURL*)URL { + NSUserDefaults* sharedDefaults = app_group::GetGroupUserDefaults(); NSString* defaultsKey = base::SysUTF8ToNSString(app_group::kChromeAppGroupCommandPreference); @@ -163,7 +170,7 @@ appPrefKey : @"TodayExtension", commandPrefKey : base::SysUTF8ToNSString(app_group::kChromeAppGroupOpenURLCommand), - paramPrefKey : URL, + paramPrefKey : URL.absoluteString, }; [sharedDefaults setObject:commandDict forKey:defaultsKey];
diff --git a/ios/chrome/content_widget_extension/most_visited_tile_view.h b/ios/chrome/content_widget_extension/most_visited_tile_view.h index c68eabb..d93cd79 100644 --- a/ios/chrome/content_widget_extension/most_visited_tile_view.h +++ b/ios/chrome/content_widget_extension/most_visited_tile_view.h
@@ -11,7 +11,7 @@ // View to display a Most Visited tile based on the suggestion. // It displays the favicon for this Most Visited suggestion and its title. -@interface MostVisitedTileView : UIView +@interface MostVisitedTileView : UIButton // FaviconView displaying the favicon. @property(nonatomic, strong, readonly, nonnull) FaviconViewNew* faviconView; @@ -19,6 +19,9 @@ // Title of the Most Visited. @property(nonatomic, strong, readonly, nonnull) UILabel* titleLabel; +// URL of the Most Visited. +@property(nonatomic, strong, nullable) NSURL* URL; + @end #endif // IOS_CHROME_CONTENT_WIDGET_EXTENSION_MOST_VISITED_TILE_VIEW_H_
diff --git a/ios/chrome/content_widget_extension/most_visited_tile_view.mm b/ios/chrome/content_widget_extension/most_visited_tile_view.mm index fd4d567..5ca4f0b 100644 --- a/ios/chrome/content_widget_extension/most_visited_tile_view.mm +++ b/ios/chrome/content_widget_extension/most_visited_tile_view.mm
@@ -25,6 +25,7 @@ @synthesize faviconView = _faviconView; @synthesize titleLabel = _titleLabel; +@synthesize URL = _URL; #pragma mark - Public @@ -50,6 +51,8 @@ stack.spacing = kSpaceFaviconTitle; stack.alignment = UIStackViewAlignmentCenter; stack.translatesAutoresizingMaskIntoConstraints = NO; + stack.isAccessibilityElement = NO; + stack.userInteractionEnabled = NO; [self addSubview:stack]; AddSameConstraints(self, stack); @@ -58,6 +61,8 @@ [_faviconView.widthAnchor constraintEqualToConstant:kFaviconSize], [_faviconView.heightAnchor constraintEqualToConstant:kFaviconSize], ]]; + + self.translatesAutoresizingMaskIntoConstraints = NO; } return self; }
diff --git a/ios/web/public/test/fakes/test_web_state.h b/ios/web/public/test/fakes/test_web_state.h index 9bbe078..128f446 100644 --- a/ios/web/public/test/fakes/test_web_state.h +++ b/ios/web/public/test/fakes/test_web_state.h
@@ -55,6 +55,7 @@ const base::string16& GetTitle() const override; bool IsLoading() const override; double GetLoadingProgress() const override; + bool IsCrashed() const override; bool IsBeingDestroyed() const override; const GURL& GetVisibleURL() const override; const GURL& GetLastCommittedURL() const override;
diff --git a/ios/web/public/test/fakes/test_web_state.mm b/ios/web/public/test/fakes/test_web_state.mm index 67da5e2..5d428df 100644 --- a/ios/web/public/test/fakes/test_web_state.mm +++ b/ios/web/public/test/fakes/test_web_state.mm
@@ -176,6 +176,10 @@ return 0.0; } +bool TestWebState::IsCrashed() const { + return false; +} + bool TestWebState::IsBeingDestroyed() const { return false; }
diff --git a/ios/web/public/web_state/web_state.h b/ios/web/public/web_state/web_state.h index 6478ad8..245f5b1 100644 --- a/ios/web/public/web_state/web_state.h +++ b/ios/web/public/web_state/web_state.h
@@ -190,6 +190,10 @@ // (nothing loaded) and 1.0 (fully loaded). virtual double GetLoadingProgress() const = 0; + // Returns true if the web process backing this WebState is believed to + // currently be crashed. + virtual bool IsCrashed() const = 0; + // Whether this instance is in the process of being destroyed. virtual bool IsBeingDestroyed() const = 0;
diff --git a/ios/web/web_state/ui/crw_web_controller.h b/ios/web/web_state/ui/crw_web_controller.h index b72d745a..bf4e1d8e53 100644 --- a/ios/web/web_state/ui/crw_web_controller.h +++ b/ios/web/web_state/ui/crw_web_controller.h
@@ -105,6 +105,9 @@ // |WebStateObserver::DidSuppressDialog| will be called. @property(nonatomic, assign) BOOL shouldSuppressDialogs; +// YES if the web process backing WebView is believed to currently be crashed. +@property(nonatomic, assign, getter=isWebProcessCrashed) BOOL webProcessCrashed; + // Designated initializer. Initializes web controller with |webState|. The // calling code must retain the ownership of |webState|. - (instancetype)initWithWebState:(web::WebStateImpl*)webState;
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index b204af2..1befb1a8 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -359,8 +359,6 @@ // Set to YES when a hashchange event is manually dispatched for same-document // history navigations. BOOL _dispatchingSameDocumentHashChangeEvent; - // YES if the web process backing _wkWebView is believed to currently be dead. - BOOL _webProcessIsDead; // Object for loading POST requests with body. base::scoped_nsobject<CRWJSPOSTRequestLoader> _POSTRequestLoader; @@ -944,6 +942,7 @@ @synthesize usePlaceholderOverlay = _usePlaceholderOverlay; @synthesize loadPhase = _loadPhase; @synthesize shouldSuppressDialogs = _shouldSuppressDialogs; +@synthesize webProcessCrashed = _webProcessCrashed; - (instancetype)initWithWebState:(WebStateImpl*)webState { self = [super init]; @@ -1147,7 +1146,7 @@ } - (BOOL)isViewAlive { - return !_webProcessIsDead && [_containerView isViewAlive]; + return !_webProcessCrashed && [_containerView isViewAlive]; } - (BOOL)contentIsHTML { @@ -4101,7 +4100,7 @@ } - (void)webViewWebProcessDidCrash { - _webProcessIsDead = YES; + _webProcessCrashed = YES; _webStateImpl->CancelDialogs(); _webStateImpl->OnRenderProcessGone(); } @@ -4309,7 +4308,7 @@ decidePolicyForNavigationAction:(WKNavigationAction*)action decisionHandler: (void (^)(WKNavigationActionPolicy))decisionHandler { - _webProcessIsDead = NO; + _webProcessCrashed = NO; if (_isBeingDestroyed) { decisionHandler(WKNavigationActionPolicyCancel); return; @@ -4851,7 +4850,7 @@ - (void)webViewTitleDidChange { // WKWebView's title becomes empty when the web process dies; ignore that // update. - if (_webProcessIsDead) { + if (_webProcessCrashed) { DCHECK_EQ([_webView title].length, 0U); return; }
diff --git a/ios/web/web_state/ui/crw_web_controller_unittest.mm b/ios/web/web_state/ui/crw_web_controller_unittest.mm index f2f40c1..7e38171 100644 --- a/ios/web/web_state/ui/crw_web_controller_unittest.mm +++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -948,6 +948,10 @@ // Tests that WebStateDelegate::RenderProcessGone is called when WKWebView web // process has crashed. TEST_F(CRWWebControllerWebProcessTest, Crash) { + ASSERT_TRUE([web_controller() isViewAlive]); + ASSERT_FALSE([web_controller() isWebProcessCrashed]); + ASSERT_FALSE(web_state()->IsCrashed()); + web::TestWebStateObserver observer(web_state()); web::TestWebStateObserver* observer_ptr = &observer; web::SimulateWKWebViewCrash(webView_); @@ -956,6 +960,8 @@ }); EXPECT_EQ(web_state(), observer.render_process_gone_info()->web_state); EXPECT_FALSE([web_controller() isViewAlive]); + EXPECT_TRUE([web_controller() isWebProcessCrashed]); + EXPECT_TRUE(web_state()->IsCrashed()); }; } // namespace
diff --git a/ios/web/web_state/web_state_impl.h b/ios/web/web_state/web_state_impl.h index c357d9d9..22eb8adf 100644 --- a/ios/web/web_state/web_state_impl.h +++ b/ios/web/web_state/web_state_impl.h
@@ -197,6 +197,7 @@ const base::string16& GetTitle() const override; bool IsLoading() const override; double GetLoadingProgress() const override; + bool IsCrashed() const override; bool IsBeingDestroyed() const override; const GURL& GetVisibleURL() const override; const GURL& GetLastCommittedURL() const override;
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm index c8ce61a..dd27c66 100644 --- a/ios/web/web_state/web_state_impl.mm +++ b/ios/web/web_state/web_state_impl.mm
@@ -240,6 +240,10 @@ return [web_controller_ loadingProgress]; } +bool WebStateImpl::IsCrashed() const { + return [web_controller_ isWebProcessCrashed]; +} + bool WebStateImpl::IsBeingDestroyed() const { return is_being_destroyed_; }
diff --git a/media/base/audio_latency.cc b/media/base/audio_latency.cc index ccc634b..e077fdbe 100644 --- a/media/base/audio_latency.cc +++ b/media/base/audio_latency.cc
@@ -106,10 +106,10 @@ return frames_per_buffer; } -#if defined(OS_LINUX) || defined(OS_MACOSX) - // On Linux and MacOS, the low level IO implementations on the browser side - // supports all buffer size the clients want. We use the native peer - // connection buffer size (10ms) to achieve best possible performance. +#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_FUCHSIA) + // On Linux, MacOS and Fuchsia, the low level IO implementations on the + // browser side supports all buffer size the clients want. We use the native + // peer connection buffer size (10ms) to achieve best possible performance. frames_per_buffer = sample_rate / 100; #elif defined(OS_ANDROID) // TODO(olka/henrika): This settings are very old, need to be revisited.
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 2d8f866..db6fc06 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -201,7 +201,7 @@ base::FEATURE_ENABLED_BY_DEFAULT}; // Use AndroidOverlay rather than ContentVideoView in clank? -const base::Feature kUseAndroidOverlay{"use-android_overlay", +const base::Feature kUseAndroidOverlay{"UseAndroidOverlay", base::FEATURE_DISABLED_BY_DEFAULT}; // Let video track be unselected when video is playing in the background. @@ -228,7 +228,7 @@ // Support FLAC codec within ISOBMFF streams used with Media Source Extensions. const base::Feature kMseFlacInIsobmff{"MseFlacInIsobmff", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Use the new Remote Playback / media flinging pipeline. const base::Feature kNewRemotePlaybackPipeline{
diff --git a/media/gpu/android/promotion_hint_aggregator.h b/media/gpu/android/promotion_hint_aggregator.h index 44e5561..9fd1e43 100644 --- a/media/gpu/android/promotion_hint_aggregator.h +++ b/media/gpu/android/promotion_hint_aggregator.h
@@ -22,6 +22,8 @@ struct Hint { int x = 0; int y = 0; + int width = 0; + int height = 0; bool is_promotable = false; };
diff --git a/media/gpu/android_video_decode_accelerator.cc b/media/gpu/android_video_decode_accelerator.cc index 62ba3bc..152a4ec 100644 --- a/media/gpu/android_video_decode_accelerator.cc +++ b/media/gpu/android_video_decode_accelerator.cc
@@ -66,6 +66,11 @@ // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. enum { kMaxBitstreamsNotifiedInAdvance = 32 }; +// Number of frames to defer overlays for when entering fullscreen. This lets +// blink relayout settle down a bit. If overlay positions were synchronous, +// then we wouldn't need this. +enum { kFrameDelayForFullscreenLayout = 15 }; + // MediaCodec is only guaranteed to support baseline, but some devices may // support others. Advertise support for all H264 profiles and let the // MediaCodec fail when decoding if it's not actually supported. It's assumed @@ -1276,6 +1281,18 @@ surface_chooser_state_.is_frame_hidden = overlay_info.is_frame_hidden; + if (overlay_info.is_fullscreen && !surface_chooser_state_.is_fullscreen) { + // It would be nice if we could just delay until we get a hint from an + // overlay that's "in fullscreen" in the sense that the CompositorFrame it + // came from had some flag set to indicate that the renderer was in + // fullscreen mode when it was generated. However, even that's hard, since + // there's no real connection between "renderer finds out about fullscreen" + // and "blink has completed layouts for it". The latter is what we really + // want to know. + surface_chooser_state_.is_expecting_relayout = true; + hints_until_clear_relayout_flag_ = kFrameDelayForFullscreenLayout; + } + // Notify the chooser about the fullscreen state. surface_chooser_state_.is_fullscreen = overlay_info.is_fullscreen; @@ -1563,10 +1580,29 @@ void AndroidVideoDecodeAccelerator::NotifyPromotionHint( const PromotionHintAggregator::Hint& hint) { + bool update_state = false; + promotion_hint_aggregator_->NotifyPromotionHint(hint); + + // If we're expecting a full screen relayout, then also use this hint as a + // notification that another frame has happened. + if (hints_until_clear_relayout_flag_ > 0) { + hints_until_clear_relayout_flag_--; + if (hints_until_clear_relayout_flag_ == 0) { + surface_chooser_state_.is_expecting_relayout = false; + update_state = true; + } + } + + surface_chooser_state_.initial_position = + gfx::Rect(hint.x, hint.y, hint.width, hint.height); bool promotable = promotion_hint_aggregator_->IsSafeToPromote(); if (promotable != surface_chooser_state_.is_compositor_promotable) { surface_chooser_state_.is_compositor_promotable = promotable; + update_state = true; + } + + if (update_state) { surface_chooser_->UpdateState(base::Optional<AndroidOverlayFactoryCB>(), surface_chooser_state_); }
diff --git a/media/gpu/android_video_decode_accelerator.h b/media/gpu/android_video_decode_accelerator.h index b03473b..a36dd41 100644 --- a/media/gpu/android_video_decode_accelerator.h +++ b/media/gpu/android_video_decode_accelerator.h
@@ -394,6 +394,13 @@ AndroidVideoSurfaceChooser::State surface_chooser_state_; + // Number of promotion hints that we need to receive before clearing the + // "delay overlay promotion" flag in |surface_chooser_state_|. We do this so + // that the transition looks better, since it gives blink time to stabilize. + // Since overlay positioning isn't synchronous, it's good to make sure that + // blink isn't moving the quad around too. + int hints_until_clear_relayout_flag_ = 0; + // Optional factory to produce mojo AndroidOverlay instances. AndroidOverlayMojoFactoryCB overlay_factory_cb_;
diff --git a/media/gpu/android_video_surface_chooser.h b/media/gpu/android_video_surface_chooser.h index 67051a3..aa0c57c 100644 --- a/media/gpu/android_video_surface_chooser.h +++ b/media/gpu/android_video_surface_chooser.h
@@ -11,6 +11,7 @@ #include "base/optional.h" #include "media/base/android/android_overlay.h" #include "media/gpu/media_gpu_export.h" +#include "ui/gfx/geometry/rect.h" namespace media { @@ -29,6 +30,12 @@ // Is the compositor willing to promote this? bool is_compositor_promotable = false; + + // Are we expecting a relayout soon? + bool is_expecting_relayout = false; + + // Hint to use for the initial position when transitioning to an overlay. + gfx::Rect initial_position; }; // Notify the client that |overlay| is ready for use. The client may get
diff --git a/media/gpu/android_video_surface_chooser_impl.cc b/media/gpu/android_video_surface_chooser_impl.cc index 3e66239..d2f6ae8c 100644 --- a/media/gpu/android_video_surface_chooser_impl.cc +++ b/media/gpu/android_video_surface_chooser_impl.cc
@@ -110,6 +110,14 @@ if (!current_state_.is_compositor_promotable) new_overlay_state = kUsingSurfaceTexture; + // If we're expecting a relayout, then don't transition to overlay if we're + // not already in one. We don't want to transition out, though. This lets us + // delay entering on a fullscreen transition until blink relayout is complete. + // TODO(liberato): Detect this more directly. + if (current_state_.is_expecting_relayout && + client_overlay_state_ != kUsingOverlay) + new_overlay_state = kUsingSurfaceTexture; + // If we need a secure surface, then we must choose an overlay. The only way // we won't is if we don't have a factory or our request fails. If the // compositor won't promote, then we still use the overlay, since hopefully @@ -182,10 +190,7 @@ config.failed_cb = base::Bind(&AndroidVideoSurfaceChooserImpl::OnOverlayFailed, weak_factory_.GetWeakPtr()); - // TODO(liberato): where do we get the initial size from? For CVV, it's - // set via the natural size, and this is ignored anyway. The client should - // provide this. - config.rect = gfx::Rect(0, 0, 1, 1); + config.rect = current_state_.initial_position; overlay_ = overlay_factory_.Run(std::move(config)); if (!overlay_) SwitchToSurfaceTexture();
diff --git a/media/gpu/android_video_surface_chooser_impl_unittest.cc b/media/gpu/android_video_surface_chooser_impl_unittest.cc index acf4bd4f..69e811d0 100644 --- a/media/gpu/android_video_surface_chooser_impl_unittest.cc +++ b/media/gpu/android_video_surface_chooser_impl_unittest.cc
@@ -57,13 +57,15 @@ enum class IsSecure { No, Yes }; enum class IsFrameHidden { No, Yes }; enum class IsCCPromotable { No, Yes }; +enum class IsExpectingRelayout { No, Yes }; using TestParams = std::tuple<ShouldUseOverlay, AllowDynamic, IsFullscreen, IsSecure, IsFrameHidden, - IsCCPromotable>; + IsCCPromotable, + IsExpectingRelayout>; // Useful macro for instantiating tests. #define Either(x) Values(x::No, x::Yes) @@ -308,6 +310,7 @@ chooser_state_.is_secure = IsYes(IsSecure, 3); chooser_state_.is_frame_hidden = IsYes(IsFrameHidden, 4); chooser_state_.is_compositor_promotable = IsYes(IsCCPromotable, 5); + chooser_state_.is_expecting_relayout = IsYes(IsExpectingRelayout, 6); if (should_use_overlay) { EXPECT_CALL(client_, UseSurfaceTexture()).Times(0); @@ -332,8 +335,9 @@ Either(AllowDynamic), Values(IsFullscreen::No), Values(IsSecure::No), - Values(IsFrameHidden::No), - Either(IsCCPromotable))); + Either(IsFrameHidden), + Either(IsCCPromotable), + Either(IsExpectingRelayout))); INSTANTIATE_TEST_CASE_P(FullscreenUsesOverlay, AndroidVideoSurfaceChooserImplTest, Combine(Values(ShouldUseOverlay::Yes), @@ -341,7 +345,8 @@ Values(IsFullscreen::Yes), Values(IsSecure::No), Values(IsFrameHidden::No), - Values(IsCCPromotable::Yes))); + Values(IsCCPromotable::Yes), + Values(IsExpectingRelayout::No))); INSTANTIATE_TEST_CASE_P(SecureUsesOverlay, AndroidVideoSurfaceChooserImplTest, Combine(Values(ShouldUseOverlay::Yes), @@ -349,7 +354,8 @@ Either(IsFullscreen), Values(IsSecure::Yes), Values(IsFrameHidden::No), - Values(IsCCPromotable::Yes))); + Values(IsCCPromotable::Yes), + Either(IsExpectingRelayout))); INSTANTIATE_TEST_CASE_P(HiddenFramesUseSurfaceTexture, AndroidVideoSurfaceChooserImplTest, @@ -358,7 +364,8 @@ Either(IsFullscreen), Either(IsSecure), Values(IsFrameHidden::Yes), - Either(IsCCPromotable))); + Either(IsCCPromotable), + Either(IsExpectingRelayout))); // For all dynamic cases, we shouldn't use an overlay if the compositor won't // promote it. For L1, it will fail either way until the CC supports "must // promote" overlays, so we ignore those cases. Non-dynamic is excluded, since @@ -371,6 +378,41 @@ Either(IsFullscreen), Values(IsSecure::No), Values(IsFrameHidden::No), - Values(IsCCPromotable::No))); + Values(IsCCPromotable::No), + Either(IsExpectingRelayout))); + +// If we're expecting a relayout, then we should never use an overlay unless +// it's required for a secure output. +INSTANTIATE_TEST_CASE_P(InsecureExpectingRelayoutUsesSurfaceTexture, + AndroidVideoSurfaceChooserImplTest, + Combine(Values(ShouldUseOverlay::No), + Values(AllowDynamic::Yes), + Either(IsFullscreen), + Values(IsSecure::No), + Either(IsFrameHidden), + Either(IsCCPromotable), + Values(IsExpectingRelayout::Yes))); + +// "is_fullscreen" should be enough to trigger an overlay pre-M. +INSTANTIATE_TEST_CASE_P(NotDynamicInFullscreenUsesOverlay, + AndroidVideoSurfaceChooserImplTest, + Combine(Values(ShouldUseOverlay::Yes), + Values(AllowDynamic::No), + Values(IsFullscreen::Yes), + Either(IsSecure), + Either(IsFrameHidden), + Either(IsCCPromotable), + Either(IsExpectingRelayout))); + +// "is_secure" should be enough to trigger an overlay pre-M. +INSTANTIATE_TEST_CASE_P(NotDynamicSecureUsesOverlay, + AndroidVideoSurfaceChooserImplTest, + Combine(Values(ShouldUseOverlay::Yes), + Values(AllowDynamic::No), + Either(IsFullscreen), + Values(IsSecure::Yes), + Either(IsFrameHidden), + Either(IsCCPromotable), + Either(IsExpectingRelayout))); } // namespace media
diff --git a/media/gpu/avda_codec_image.cc b/media/gpu/avda_codec_image.cc index 00db66b..6ba5e0f 100644 --- a/media/gpu/avda_codec_image.cc +++ b/media/gpu/avda_codec_image.cc
@@ -234,11 +234,15 @@ void AVDACodecImage::NotifyPromotionHint(bool promotion_hint, int display_x, - int display_y) { + int display_y, + int display_width, + int display_height) { // TODO(liberato): this should just be given to us. PromotionHintAggregator::Hint hint; hint.x = display_x; hint.y = display_y; + hint.width = display_width; + hint.height = display_height; hint.is_promotable = promotion_hint; shared_state_->GetPromotionHintCB().Run(hint); }
diff --git a/media/gpu/avda_codec_image.h b/media/gpu/avda_codec_image.h index c8c8c26..3ee9822 100644 --- a/media/gpu/avda_codec_image.h +++ b/media/gpu/avda_codec_image.h
@@ -50,7 +50,9 @@ void GetTextureMatrix(float xform[16]) override; void NotifyPromotionHint(bool promotion_hint, int display_x, - int display_y) override; + int display_y, + int display_width, + int display_height) override; enum class UpdateMode { // Discards the codec buffer, no UpdateTexImage().
diff --git a/media/media_options.gni b/media/media_options.gni index 26217a65..e34f7f8 100644 --- a/media/media_options.gni +++ b/media/media_options.gni
@@ -59,7 +59,7 @@ # which are encoded using HEVC require |enable_hevc_demuxing| to be enabled. enable_dolby_vision_demuxing = proprietary_codecs && is_chromecast - enable_webrtc = !is_cast_audio_only && !is_fuchsia + enable_webrtc = !is_cast_audio_only # Enable HLS with SAMPLE-AES decryption. # Enabled by default on the cast desktop implementation to allow unit tests of
diff --git a/mojo/edk/system/watch.cc b/mojo/edk/system/watch.cc index b629f90f..63d8beb5 100644 --- a/mojo/edk/system/watch.cc +++ b/mojo/edk/system/watch.cc
@@ -25,12 +25,8 @@ bool allowed_to_call_callback) { AssertWatcherLockAcquired(); - // TODO(crbug.com/740044): Remove this CHECK. - CHECK(this); - // NOTE: This method must NEVER call into |dispatcher_| directly, because it // may be called while |dispatcher_| holds a lock. - MojoResult rv = MOJO_RESULT_SHOULD_WAIT; RequestContext* const request_context = RequestContext::current(); const bool notify_success = @@ -59,9 +55,6 @@ } void Watch::Cancel() { - // TODO(crbug.com/740044): Remove this CHECK. - CHECK(this); - RequestContext::current()->AddWatchCancelFinalizer(this); } @@ -71,13 +64,13 @@ // We hold the lock through invocation to ensure that only one notification // callback runs for this context at any given time. base::AutoLock lock(notification_lock_); - if (result == MOJO_RESULT_CANCELLED) { - // Make sure cancellation is the last notification we dispatch. - DCHECK(!is_cancelled_); - is_cancelled_ = true; - } else if (is_cancelled_) { + + // Ensure that no notifications are dispatched beyond cancellation. + if (is_cancelled_) return; - } + + if (result == MOJO_RESULT_CANCELLED) + is_cancelled_ = true; // NOTE: This will acquire |watcher_|'s internal lock. It's safe because a // thread can only enter InvokeCallback() from within a RequestContext
diff --git a/mojo/edk/system/watcher_dispatcher.cc b/mojo/edk/system/watcher_dispatcher.cc index 5fbaef34..db43843 100644 --- a/mojo/edk/system/watcher_dispatcher.cc +++ b/mojo/edk/system/watcher_dispatcher.cc
@@ -47,9 +47,6 @@ watch = std::move(it->second); - // TODO(crbug.com/740044): Remove this CHECK. - CHECK(watch); - // Wipe out all state associated with the closed dispatcher. watches_.erase(watch->context()); ready_watches_.erase(watch.get()); @@ -97,7 +94,8 @@ std::map<uintptr_t, scoped_refptr<Watch>> watches; { base::AutoLock lock(lock_); - DCHECK(!closed_); + if (closed_) + return MOJO_RESULT_INVALID_ARGUMENT; closed_ = true; std::swap(watches, watches_); watched_handles_.clear(); @@ -122,9 +120,8 @@ // after we've updated all our own relevant state and released |lock_|. { base::AutoLock lock(lock_); - - // TODO(crbug.com/740044): Remove this CHECK. - CHECK(!closed_); + if (closed_) + return MOJO_RESULT_INVALID_ARGUMENT; if (watches_.count(context) || watched_handles_.count(dispatcher.get())) return MOJO_RESULT_ALREADY_EXISTS; @@ -147,21 +144,17 @@ return rv; } - // TODO(crbug.com/740044): Perhaps the crash is caused by a racy use of - // watchers, which - while incorrect - should not in fact be able to crash at - // this layer. - // - // Hypothesis is that two threads are racing with one adding a watch and one - // closing the watcher handle. If the watcher handle is closed immediately - // before the AddWatcherRef() call above, |dispatcher| can retain an invalid - // pointer to this WatcherDispatcher indefinitely, leading to an eventual UAF - // if and when it tries to dispatch a notification. - // - // If such a race is indeed the sole source of crashes, all subsequent crash - // reports which would have come from Watch::NotifyState etc should instead - // fail the CHECK below. - base::AutoLock lock(lock_); - CHECK(!closed_); + bool remove_now; + { + // If we've been closed already, there's a chance our closure raced with + // the call to AddWatcherRef() above. In that case we want to ensure we've + // removed our ref from |dispatcher|. Note that this may in turn race + // with normal removal, but that's fine. + base::AutoLock lock(lock_); + remove_now = closed_; + } + if (remove_now) + dispatcher->RemoveWatcherRef(this, context); return MOJO_RESULT_OK; } @@ -172,6 +165,8 @@ scoped_refptr<Watch> watch; { base::AutoLock lock(lock_); + if (closed_) + return MOJO_RESULT_INVALID_ARGUMENT; auto it = watches_.find(context); if (it == watches_.end()) return MOJO_RESULT_NOT_FOUND; @@ -179,11 +174,6 @@ watches_.erase(it); } - // TODO(crbug.com/740044): Remove these CHECKs. - CHECK(watch); - CHECK(watch->dispatcher()); - CHECK(this); - // Mark the watch as cancelled so no further notifications get through. watch->Cancel(); @@ -218,6 +208,8 @@ (!ready_contexts || !ready_results || !ready_signals_states)) { return MOJO_RESULT_INVALID_ARGUMENT; } + if (closed_) + return MOJO_RESULT_INVALID_ARGUMENT; if (watched_handles_.empty()) return MOJO_RESULT_NOT_FOUND; @@ -261,10 +253,7 @@ return MOJO_RESULT_FAILED_PRECONDITION; } -WatcherDispatcher::~WatcherDispatcher() { - // TODO(crbug.com/740044): Remove this. - CHECK(closed_); -} +WatcherDispatcher::~WatcherDispatcher() = default; } // namespace edk } // namespace mojo
diff --git a/mojo/edk/system/watcher_unittest.cc b/mojo/edk/system/watcher_unittest.cc index 9987e483..92484c4 100644 --- a/mojo/edk/system/watcher_unittest.cc +++ b/mojo/edk/system/watcher_unittest.cc
@@ -12,6 +12,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/rand_util.h" #include "base/synchronization/waitable_event.h" #include "base/threading/platform_thread.h" #include "base/threading/simple_thread.h" @@ -1722,6 +1723,126 @@ EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a)); } +base::Closure g_do_random_thing_callback; + +void ReadAllMessages(uintptr_t context, + MojoResult result, + MojoHandleSignalsState state, + MojoWatcherNotificationFlags flags) { + if (result == MOJO_RESULT_OK) { + MojoHandle handle = static_cast<MojoHandle>(context); + MojoMessageHandle message; + while (MojoReadMessage(handle, &message, MOJO_READ_MESSAGE_FLAG_NONE) == + MOJO_RESULT_OK) { + MojoDestroyMessage(message); + } + } + + constexpr size_t kNumRandomThingsToDoOnNotify = 5; + for (size_t i = 0; i < kNumRandomThingsToDoOnNotify; ++i) + g_do_random_thing_callback.Run(); +} + +MojoHandle RandomHandle(MojoHandle* handles, size_t size) { + return handles[base::RandInt(0, static_cast<int>(size) - 1)]; +} + +void DoRandomThing(MojoHandle* watchers, + size_t num_watchers, + MojoHandle* watched_handles, + size_t num_watched_handles) { + switch (base::RandInt(0, 10)) { + case 0: + MojoClose(RandomHandle(watchers, num_watchers)); + break; + case 1: + MojoClose(RandomHandle(watched_handles, num_watched_handles)); + break; + case 2: + case 3: + case 4: { + MojoMessageHandle message; + ASSERT_EQ(MOJO_RESULT_OK, MojoCreateMessage(&message)); + ASSERT_EQ(MOJO_RESULT_OK, + MojoAttachMessageContext(message, 1, nullptr, nullptr)); + MojoWriteMessage(RandomHandle(watched_handles, num_watched_handles), + message, MOJO_WRITE_MESSAGE_FLAG_NONE); + break; + } + case 5: + case 6: { + MojoHandle w = RandomHandle(watchers, num_watchers); + MojoHandle h = RandomHandle(watched_handles, num_watched_handles); + MojoWatch(w, h, MOJO_HANDLE_SIGNAL_READABLE, + MOJO_WATCH_CONDITION_SATISFIED, static_cast<uintptr_t>(h)); + break; + } + case 7: + case 8: { + uint32_t num_ready_contexts = 1; + uintptr_t ready_context; + MojoResult ready_result; + MojoHandleSignalsState ready_state; + if (MojoArmWatcher(RandomHandle(watchers, num_watchers), + &num_ready_contexts, &ready_context, &ready_result, + &ready_state) == MOJO_RESULT_FAILED_PRECONDITION && + ready_result == MOJO_RESULT_OK) { + ReadAllMessages(ready_context, ready_result, ready_state, 0); + } + break; + } + case 9: + case 10: { + MojoHandle w = RandomHandle(watchers, num_watchers); + MojoHandle h = RandomHandle(watched_handles, num_watched_handles); + MojoCancelWatch(w, static_cast<uintptr_t>(h)); + break; + } + default: + NOTREACHED(); + break; + } +} + +TEST_F(WatcherTest, ConcurrencyStressTest) { + // Regression test for https://crbug.com/740044. Exercises racy usage of the + // watcher API to weed out potential crashes. + + constexpr size_t kNumWatchers = 50; + constexpr size_t kNumWatchedHandles = 50; + static_assert(kNumWatchedHandles % 2 == 0, "Invalid number of test handles."); + + constexpr size_t kNumThreads = 10; + static constexpr size_t kNumOperationsPerThread = 400; + + MojoHandle watchers[kNumWatchers]; + MojoHandle watched_handles[kNumWatchedHandles]; + g_do_random_thing_callback = + base::Bind(&DoRandomThing, watchers, kNumWatchers, watched_handles, + kNumWatchedHandles); + + for (size_t i = 0; i < kNumWatchers; ++i) + MojoCreateWatcher(&ReadAllMessages, &watchers[i]); + for (size_t i = 0; i < kNumWatchedHandles; i += 2) + CreateMessagePipe(&watched_handles[i], &watched_handles[i + 1]); + + std::unique_ptr<ThreadedRunner> threads[kNumThreads]; + auto runner_callback = base::Bind([]() { + for (size_t i = 0; i < kNumOperationsPerThread; ++i) + g_do_random_thing_callback.Run(); + }); + for (size_t i = 0; i < kNumThreads; ++i) { + threads[i] = base::MakeUnique<ThreadedRunner>(runner_callback); + threads[i]->Start(); + } + for (size_t i = 0; i < kNumThreads; ++i) + threads[i]->Join(); + for (size_t i = 0; i < kNumWatchers; ++i) + MojoClose(watchers[i]); + for (size_t i = 0; i < kNumWatchedHandles; ++i) + MojoClose(watched_handles[i]); +} + } // namespace } // namespace edk } // namespace mojo
diff --git a/mojo/public/cpp/bindings/BUILD.gn b/mojo/public/cpp/bindings/BUILD.gn index f427466..067523a 100644 --- a/mojo/public/cpp/bindings/BUILD.gn +++ b/mojo/public/cpp/bindings/BUILD.gn
@@ -67,7 +67,6 @@ "lib/control_message_handler.h", "lib/control_message_proxy.cc", "lib/control_message_proxy.h", - "lib/debug_util.h", "lib/deque.h", "lib/filter_chain.cc", "lib/fixed_buffer.cc",
diff --git a/mojo/public/cpp/bindings/interface_endpoint_client.h b/mojo/public/cpp/bindings/interface_endpoint_client.h index 25b815c..891039d 100644 --- a/mojo/public/cpp/bindings/interface_endpoint_client.h +++ b/mojo/public/cpp/bindings/interface_endpoint_client.h
@@ -26,7 +26,6 @@ #include "mojo/public/cpp/bindings/filter_chain.h" #include "mojo/public/cpp/bindings/lib/control_message_handler.h" #include "mojo/public/cpp/bindings/lib/control_message_proxy.h" -#include "mojo/public/cpp/bindings/lib/debug_util.h" #include "mojo/public/cpp/bindings/message.h" #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" @@ -39,8 +38,7 @@ // endpoint, either the implementation side or the client side. // It should only be accessed and destructed on the creating sequence. class MOJO_CPP_BINDINGS_EXPORT InterfaceEndpointClient - : NON_EXPORTED_BASE(public MessageReceiverWithResponder), - NON_EXPORTED_BASE(private internal::LifeTimeTrackerForDebugging) { + : NON_EXPORTED_BASE(public MessageReceiverWithResponder) { public: // |receiver| is okay to be null. If it is not null, it must outlive this // object.
diff --git a/mojo/public/cpp/bindings/lib/debug_util.h b/mojo/public/cpp/bindings/lib/debug_util.h deleted file mode 100644 index 1783645..0000000 --- a/mojo/public/cpp/bindings/lib/debug_util.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_DEBUG_UTIL_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_LIB_DEBUG_UTIL_H_ - -namespace mojo { -namespace internal { - -// TODO(crbug.com/741047): Remove this after the bug is fixed. -class LifeTimeTrackerForDebugging { - public: - LifeTimeTrackerForDebugging() {} - - ~LifeTimeTrackerForDebugging() { state_ = DESTROYED; } - - void CheckObjectIsValid() { - CHECK(this); - - // This adress has been used to construct a LifeTimeTrackerForDebugging. - CHECK(state_ == ALIVE || state_ == DESTROYED); - - // If the previous check succeeds but this fails, it is likely to be - // use-after-free problem. - CHECK_EQ(ALIVE, state_); - } - - private: - enum MagicValue : uint64_t { - ALIVE = 0x1029384756afbecd, - DESTROYED = 0xdcebfa6574839201 - }; - - uint64_t state_ = ALIVE; -}; - -} // namespace internal -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_DEBUG_UTIL_H_
diff --git a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc index 0fe98c7e..bb59369 100644 --- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc +++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
@@ -167,15 +167,8 @@ InterfaceEndpointClient::~InterfaceEndpointClient() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - // TODO(crbug.com/741047): Remove these checks. - CheckObjectIsValid(); - CHECK(task_runner_->RunsTasksInCurrentSequence()); - - if (controller_) { - CHECK(handle_.group_controller()); + if (controller_) handle_.group_controller()->DetachEndpointClient(handle_); - } } AssociatedGroup* InterfaceEndpointClient::associated_group() {
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.cc b/mojo/public/cpp/bindings/lib/multiplex_router.cc index f40c040..c98b7d4 100644 --- a/mojo/public/cpp/bindings/lib/multiplex_router.cc +++ b/mojo/public/cpp/bindings/lib/multiplex_router.cc
@@ -504,16 +504,12 @@ void MultiplexRouter::DetachEndpointClient( const ScopedInterfaceEndpointHandle& handle) { - // TODO(crbug.com/741047): Remove this check. - CheckObjectIsValid(); - const InterfaceId id = handle.id(); DCHECK(IsValidInterfaceId(id)); MayAutoLock locker(&lock_); - // TODO(crbug.com/741047): change this to DCEHCK. - CHECK(base::ContainsKey(endpoints_, id)); + DCHECK(base::ContainsKey(endpoints_, id)); InterfaceEndpoint* endpoint = endpoints_[id].get(); endpoint->DetachClient(); @@ -670,9 +666,6 @@ void MultiplexRouter::OnPipeConnectionError() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // TODO(crbug.com/741047): Remove this check. - CheckObjectIsValid(); - scoped_refptr<MultiplexRouter> protector(this); MayAutoLock locker(&lock_);
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.h b/mojo/public/cpp/bindings/lib/multiplex_router.h index 3061ce6..be6b2cc 100644 --- a/mojo/public/cpp/bindings/lib/multiplex_router.h +++ b/mojo/public/cpp/bindings/lib/multiplex_router.h
@@ -25,7 +25,6 @@ #include "mojo/public/cpp/bindings/connector.h" #include "mojo/public/cpp/bindings/filter_chain.h" #include "mojo/public/cpp/bindings/interface_id.h" -#include "mojo/public/cpp/bindings/lib/debug_util.h" #include "mojo/public/cpp/bindings/lib/deque.h" #include "mojo/public/cpp/bindings/message_header_validator.h" #include "mojo/public/cpp/bindings/pipe_control_message_handler.h" @@ -56,8 +55,7 @@ class MOJO_CPP_BINDINGS_EXPORT MultiplexRouter : NON_EXPORTED_BASE(public MessageReceiver), public AssociatedGroupController, - NON_EXPORTED_BASE(public PipeControlMessageHandlerDelegate), - NON_EXPORTED_BASE(private LifeTimeTrackerForDebugging) { + NON_EXPORTED_BASE(public PipeControlMessageHandlerDelegate) { public: enum Config { // There is only the master interface running on this router. Please note
diff --git a/net/BUILD.gn b/net/BUILD.gn index c6a1186..866a0f2 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1820,7 +1820,10 @@ sources -= [ "cert/x509_certificate_ios.cc" ] } if (is_mac) { - sources -= [ "cert/x509_certificate_mac.cc" ] + sources -= [ + "cert/x509_cert_types_mac.cc", + "cert/x509_certificate_mac.cc", + ] } if (use_nss_certs) { sources -= [ "cert/x509_certificate_nss.cc" ] @@ -1829,7 +1832,10 @@ sources -= [ "cert/x509_certificate_openssl.cc" ] } if (is_win) { - sources -= [ "cert/x509_certificate_win.cc" ] + sources -= [ + "cert/x509_cert_types_win.cc", + "cert/x509_certificate_win.cc", + ] } } else { sources -= [ "cert/x509_certificate_bytes.cc" ]
diff --git a/net/cert/x509_cert_types.cc b/net/cert/x509_cert_types.cc index d0e09b7d..221046cc 100644 --- a/net/cert/x509_cert_types.cc +++ b/net/cert/x509_cert_types.cc
@@ -13,6 +13,11 @@ #include "net/base/parse_number.h" #include "net/cert/x509_certificate.h" +#if BUILDFLAG(USE_BYTE_CERTS) +#include "net/cert/internal/parse_name.h" +#include "net/der/input.h" +#endif + namespace net { namespace { @@ -39,6 +44,64 @@ CertPrincipal::~CertPrincipal() { } +#if BUILDFLAG(USE_BYTE_CERTS) +bool CertPrincipal::ParseDistinguishedName(const void* ber_name_data, + size_t length) { + RDNSequence rdns; + if (!ParseName( + der::Input(reinterpret_cast<const uint8_t*>(ber_name_data), length), + &rdns)) + return false; + + for (const RelativeDistinguishedName& rdn : rdns) { + for (const X509NameAttribute& name_attribute : rdn) { + if (name_attribute.type == TypeCommonNameOid()) { + if (common_name.empty() && + !name_attribute.ValueAsString(&common_name)) { + return false; + } + } else if (name_attribute.type == TypeLocalityNameOid()) { + if (locality_name.empty() && + !name_attribute.ValueAsString(&locality_name)) { + return false; + } + } else if (name_attribute.type == TypeStateOrProvinceNameOid()) { + if (state_or_province_name.empty() && + !name_attribute.ValueAsString(&state_or_province_name)) { + return false; + } + } else if (name_attribute.type == TypeCountryNameOid()) { + if (country_name.empty() && + !name_attribute.ValueAsString(&country_name)) { + return false; + } + } else if (name_attribute.type == TypeStreetAddressOid()) { + std::string s; + if (!name_attribute.ValueAsString(&s)) + return false; + street_addresses.push_back(s); + } else if (name_attribute.type == TypeOrganizationNameOid()) { + std::string s; + if (!name_attribute.ValueAsString(&s)) + return false; + organization_names.push_back(s); + } else if (name_attribute.type == TypeOrganizationUnitNameOid()) { + std::string s; + if (!name_attribute.ValueAsString(&s)) + return false; + organization_unit_names.push_back(s); + } else if (name_attribute.type == TypeDomainComponentOid()) { + std::string s; + if (!name_attribute.ValueAsString(&s)) + return false; + domain_components.push_back(s); + } + } + } + return true; +} +#endif + std::string CertPrincipal::GetDisplayName() const { if (!common_name.empty()) return common_name;
diff --git a/net/cert/x509_cert_types.h b/net/cert/x509_cert_types.h index 0a38a6da..e8c28dd3 100644 --- a/net/cert/x509_cert_types.h +++ b/net/cert/x509_cert_types.h
@@ -19,6 +19,7 @@ #include "net/base/hash_value.h" #include "net/base/net_export.h" #include "net/cert/cert_status_flags.h" +#include "net/net_features.h" #if defined(OS_MACOSX) && !defined(OS_IOS) #include <Security/x509defs.h> @@ -36,8 +37,10 @@ explicit CertPrincipal(const std::string& name); ~CertPrincipal(); -#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN) +#if BUILDFLAG(USE_BYTE_CERTS) || (defined(OS_MACOSX) && !defined(OS_IOS)) || \ + defined(OS_WIN) // Parses a BER-format DistinguishedName. + // TODO(mattm): change this to take a der::Input. bool ParseDistinguishedName(const void* ber_name_data, size_t length); #endif
diff --git a/net/cert/x509_cert_types_unittest.cc b/net/cert/x509_cert_types_unittest.cc index 9882090cd..2ac7c57 100644 --- a/net/cert/x509_cert_types_unittest.cc +++ b/net/cert/x509_cert_types_unittest.cc
@@ -6,6 +6,7 @@ #include "base/strings/string_piece.h" #include "base/time/time.h" +#include "build/build_config.h" #include "net/test/test_certificate_data.h" #include "testing/gtest/include/gtest/gtest.h" @@ -13,7 +14,8 @@ namespace { -#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN) +#if BUILDFLAG(USE_BYTE_CERTS) || (defined(OS_MACOSX) && !defined(OS_IOS)) || \ + defined(OS_WIN) TEST(X509TypesTest, ParseDNVerisign) { CertPrincipal verisign; EXPECT_TRUE(verisign.ParseDistinguishedName(VerisignDN, sizeof(VerisignDN)));
diff --git a/net/cert/x509_certificate_bytes.cc b/net/cert/x509_certificate_bytes.cc index 96dcf3fb..17cd7f3 100644 --- a/net/cert/x509_certificate_bytes.cc +++ b/net/cert/x509_certificate_bytes.cc
@@ -12,7 +12,6 @@ #include "net/cert/asn1_util.h" #include "net/cert/internal/cert_errors.h" #include "net/cert/internal/name_constraints.h" -#include "net/cert/internal/parse_name.h" #include "net/cert/internal/parsed_certificate.h" #include "net/cert/internal/signature_algorithm.h" #include "net/cert/internal/verify_name_match.h" @@ -83,62 +82,6 @@ return NormalizeName(issuer_value, out_normalized_issuer, &errors); } -// Fills |principal| from the DER encoded |name_tlv|, returning true on success -// or false if parsing failed or some of the values could not be converted to -// UTF-8. -bool ParsePrincipal(const der::Input& name_tlv, CertPrincipal* principal) { - RDNSequence rdns; - if (!ParseName(name_tlv, &rdns)) - return false; - - for (const RelativeDistinguishedName& rdn : rdns) { - for (const X509NameAttribute& name_attribute : rdn) { - if (name_attribute.type == TypeCommonNameOid()) { - if (principal->common_name.empty() && - !name_attribute.ValueAsString(&principal->common_name)) { - return false; - } - } else if (name_attribute.type == TypeLocalityNameOid()) { - if (principal->locality_name.empty() && - !name_attribute.ValueAsString(&principal->locality_name)) { - return false; - } - } else if (name_attribute.type == TypeStateOrProvinceNameOid()) { - if (principal->state_or_province_name.empty() && - !name_attribute.ValueAsString(&principal->state_or_province_name)) { - return false; - } - } else if (name_attribute.type == TypeCountryNameOid()) { - if (principal->country_name.empty() && - !name_attribute.ValueAsString(&principal->country_name)) { - return false; - } - } else if (name_attribute.type == TypeStreetAddressOid()) { - std::string s; - if (!name_attribute.ValueAsString(&s)) - return false; - principal->street_addresses.push_back(s); - } else if (name_attribute.type == TypeOrganizationNameOid()) { - std::string s; - if (!name_attribute.ValueAsString(&s)) - return false; - principal->organization_names.push_back(s); - } else if (name_attribute.type == TypeOrganizationUnitNameOid()) { - std::string s; - if (!name_attribute.ValueAsString(&s)) - return false; - principal->organization_unit_names.push_back(s); - } else if (name_attribute.type == TypeDomainComponentOid()) { - std::string s; - if (!name_attribute.ValueAsString(&s)) - return false; - principal->domain_components.push_back(s); - } - } - } - return true; -} - // Parses certificates from a PKCS#7 SignedData structure, appending them to // |handles|. void CreateOSCertHandlesFromPKCS7Bytes( @@ -182,8 +125,10 @@ DefaultParseCertificateOptions(), &tbs, nullptr)) return false; - if (!ParsePrincipal(tbs.subject_tlv, &subject_) || - !ParsePrincipal(tbs.issuer_tlv, &issuer_)) { + if (!subject_.ParseDistinguishedName(tbs.subject_tlv.UnsafeData(), + tbs.subject_tlv.Length()) || + !issuer_.ParseDistinguishedName(tbs.issuer_tlv.UnsafeData(), + tbs.issuer_tlv.Length())) { return false; }
diff --git a/net/spdy/core/http2_frame_decoder_adapter.cc b/net/spdy/core/http2_frame_decoder_adapter.cc index cb1e745..2f86bb1 100644 --- a/net/spdy/core/http2_frame_decoder_adapter.cc +++ b/net/spdy/core/http2_frame_decoder_adapter.cc
@@ -15,9 +15,7 @@ #include <cstring> #include <utility> -#include "base/format_macros.h" #include "base/logging.h" -#include "base/optional.h" #include "base/sys_byteorder.h" #include "build/build_config.h" #include "net/http2/decoder/decode_buffer.h" @@ -32,6 +30,7 @@ #include "net/spdy/core/spdy_alt_svc_wire_format.h" #include "net/spdy/core/spdy_bug_tracker.h" #include "net/spdy/core/spdy_frame_builder.h" +#include "net/spdy/core/spdy_framer.h" #include "net/spdy/core/spdy_header_block.h" #include "net/spdy/core/spdy_headers_handler_interface.h" #include "net/spdy/core/spdy_protocol.h" @@ -39,18 +38,12 @@ #include "net/spdy/platform/api/spdy_ptr_util.h" #include "net/spdy/platform/api/spdy_string_utils.h" -#if defined(COMPILER_GCC) -#define PRETTY_THIS SpdyStringPrintf("%s@%p ", __PRETTY_FUNCTION__, this) -#elif defined(COMPILER_MSVC) -#define PRETTY_THIS SpdyStringPrintf("%s@%p ", __FUNCSIG__, this) -#else -#define PRETTY_THIS SpdyStringPrintf("%s@%p ", __func__, this) -#endif - namespace net { - namespace { +using SpdyFramerError = SpdyFramer::SpdyFramerError; +using SpdyState = SpdyFramer::SpdyState; + const bool kHasPriorityFields = true; const bool kNotHasPriorityFields = false; @@ -87,951 +80,858 @@ #endif } -class Http2DecoderAdapter : public SpdyFramerDecoderAdapter, - public Http2FrameDecoderListener { - typedef SpdyFramer::SpdyState SpdyState; - typedef SpdyFramer::SpdyFramerError SpdyFramerError; +} // namespace - public: - Http2DecoderAdapter() : SpdyFramerDecoderAdapter() { - DVLOG(1) << "Http2DecoderAdapter ctor"; - ResetInternal(); - } - ~Http2DecoderAdapter() override {} +Http2DecoderAdapter::Http2DecoderAdapter() { + DVLOG(1) << "Http2DecoderAdapter ctor"; + ResetInternal(); +} - // =========================================================================== - // Implementations of the pure virtual methods from SpdyFramerDecoderAdapter; - // the other virtual methods of SpdyFramerDecoderAdapter have satsifactory - // default implementations. +Http2DecoderAdapter::~Http2DecoderAdapter() {} - void set_extension_visitor(ExtensionVisitorInterface* visitor) override { - extension_ = visitor; - } +void Http2DecoderAdapter::set_visitor(SpdyFramerVisitorInterface* visitor) { + visitor_ = visitor; +} - // Passes the call on to the HPACK decoder. - void SetDecoderHeaderTableDebugVisitor( - std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) - override { - GetHpackDecoder()->SetHeaderTableDebugVisitor(std::move(visitor)); - } +void Http2DecoderAdapter::set_debug_visitor( + SpdyFramerDebugVisitorInterface* debug_visitor) { + debug_visitor_ = debug_visitor; +} - size_t ProcessInput(const char* data, size_t len) override { - size_t limit = recv_frame_size_limit_; - frame_decoder_->set_maximum_payload_size(limit); +void Http2DecoderAdapter::set_process_single_input_frame(bool v) { + process_single_input_frame_ = v; +} - size_t total_processed = 0; - while (len > 0 && spdy_state_ != SpdyFramer::SPDY_ERROR) { - // Process one at a time so that we update the adapter's internal - // state appropriately. - const size_t processed = ProcessInputFrame(data, len); +void Http2DecoderAdapter::set_extension_visitor( + ExtensionVisitorInterface* visitor) { + extension_ = visitor; +} - // We had some data, and weren't in an error state, so should have - // processed/consumed at least one byte of it, even if we then ended up - // in an error state. - DCHECK(processed > 0) << "processed=" << processed - << " spdy_state_=" << spdy_state_ - << " spdy_framer_error_=" << spdy_framer_error_; +// Passes the call on to the HPACK decoder. +void Http2DecoderAdapter::SetDecoderHeaderTableDebugVisitor( + std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) { + GetHpackDecoder()->SetHeaderTableDebugVisitor(std::move(visitor)); +} - data += processed; - len -= processed; - total_processed += processed; - if (process_single_input_frame() || processed == 0) { - break; - } +size_t Http2DecoderAdapter::ProcessInput(const char* data, size_t len) { + size_t limit = recv_frame_size_limit_; + frame_decoder_->set_maximum_payload_size(limit); + + size_t total_processed = 0; + while (len > 0 && spdy_state_ != SpdyFramer::SPDY_ERROR) { + // Process one at a time so that we update the adapter's internal + // state appropriately. + const size_t processed = ProcessInputFrame(data, len); + + // We had some data, and weren't in an error state, so should have + // processed/consumed at least one byte of it, even if we then ended up + // in an error state. + DCHECK(processed > 0) << "processed=" << processed + << " spdy_state_=" << spdy_state_ + << " spdy_framer_error_=" << spdy_framer_error_; + + data += processed; + len -= processed; + total_processed += processed; + if (process_single_input_frame() || processed == 0) { + break; } - return total_processed; } + return total_processed; +} - void Reset() override { ResetInternal(); } +void Http2DecoderAdapter::Reset() { + ResetInternal(); +} - SpdyState state() const override { return spdy_state_; } +SpdyState Http2DecoderAdapter::state() const { + return spdy_state_; +} - SpdyFramerError spdy_framer_error() const override { - return spdy_framer_error_; +SpdyFramerError Http2DecoderAdapter::spdy_framer_error() const { + return spdy_framer_error_; +} + +bool Http2DecoderAdapter::probable_http_response() const { + return latched_probable_http_response_; +} + +size_t Http2DecoderAdapter::EstimateMemoryUsage() const { + // Skip |frame_decoder_|, |frame_header_| and |hpack_first_frame_header_| as + // they don't allocate. + return SpdyEstimateMemoryUsage(alt_svc_origin_) + + SpdyEstimateMemoryUsage(alt_svc_value_); +} + +// =========================================================================== +// Implementations of the methods declared by Http2FrameDecoderListener. + +// Called once the common frame header has been decoded for any frame. +// This function is largely based on SpdyFramer::ValidateFrameHeader +// and some parts of SpdyFramer::ProcessCommonHeader. +bool Http2DecoderAdapter::OnFrameHeader(const Http2FrameHeader& header) { + DVLOG(1) << "OnFrameHeader: " << header; + decoded_frame_header_ = true; + if (!latched_probable_http_response_) { + latched_probable_http_response_ = header.IsProbableHttpResponse(); } - - bool probable_http_response() const override { - return latched_probable_http_response_; + const uint8_t raw_frame_type = static_cast<uint8_t>(header.type); + visitor()->OnCommonHeader(header.stream_id, header.payload_length, + raw_frame_type, header.flags); + if (has_expected_frame_type_ && header.type != expected_frame_type_) { + // Report an unexpected frame error and close the connection if we + // expect a known frame type (probably CONTINUATION) and receive an + // unknown frame. + VLOG(1) << "The framer was expecting to receive a " << expected_frame_type_ + << " frame, but instead received an unknown frame of type " + << header.type; + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME); + return false; } - - size_t EstimateMemoryUsage() const override { - // Skip |frame_decoder_|, |frame_header_| and |hpack_first_frame_header_| as - // they don't allocate. - return SpdyEstimateMemoryUsage(alt_svc_origin_) + - SpdyEstimateMemoryUsage(alt_svc_value_); - } - // =========================================================================== - // Implementations of the methods declared by Http2FrameDecoderListener. - - // Called once the common frame header has been decoded for any frame. - // This function is largely based on SpdyFramer::ValidateFrameHeader - // and some parts of SpdyFramer::ProcessCommonHeader. - bool OnFrameHeader(const Http2FrameHeader& header) override { - DVLOG(1) << "OnFrameHeader: " << header; - decoded_frame_header_ = true; - if (!latched_probable_http_response_) { - latched_probable_http_response_ = header.IsProbableHttpResponse(); + if (!IsSupportedHttp2FrameType(header.type)) { + if (extension_ != nullptr) { + // Unknown frames will be passed to the registered extension. + return true; } - const uint8_t raw_frame_type = static_cast<uint8_t>(header.type); - visitor()->OnCommonHeader(header.stream_id, header.payload_length, - raw_frame_type, header.flags); - if (has_expected_frame_type_ && header.type != expected_frame_type_) { - // Report an unexpected frame error and close the connection if we - // expect a known frame type (probably CONTINUATION) and receive an - // unknown frame. - VLOG(1) << "The framer was expecting to receive a " - << expected_frame_type_ - << " frame, but instead received an unknown frame of type " - << header.type; - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME); + // In HTTP2 we ignore unknown frame types for extensibility, as long as + // the rest of the control frame header is valid. + // We rely on the visitor to check validity of stream_id. + bool valid_stream = + visitor()->OnUnknownFrame(header.stream_id, raw_frame_type); + if (!valid_stream) { + // Report an invalid frame error if the stream_id is not valid. + VLOG(1) << "Unknown control frame type " << header.type + << " received on invalid stream " << header.stream_id; + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME); + return false; + } else { + DVLOG(1) << "Ignoring unknown frame type " << header.type; + return true; + } + } + + SpdyFrameType frame_type = ToSpdyFrameType(header.type); + if (!IsValidHTTP2FrameStreamId(header.stream_id, frame_type)) { + VLOG(1) << "The framer received an invalid streamID of " << header.stream_id + << " for a frame of type " << header.type; + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID); + return false; + } + + if (has_expected_frame_type_ && header.type != expected_frame_type_) { + VLOG(1) << "Expected frame type " << expected_frame_type_ << ", not " + << header.type; + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME); + return false; + } + + if (!has_expected_frame_type_ && + header.type == Http2FrameType::CONTINUATION) { + VLOG(1) << "Got CONTINUATION frame when not expected."; + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME); + return false; + } + + if (header.type == Http2FrameType::DATA) { + // For some reason SpdyFramer still rejects invalid DATA frame flags. + uint8_t valid_flags = Http2FrameFlag::PADDED | Http2FrameFlag::END_STREAM; + if (header.HasAnyFlags(~valid_flags)) { + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_DATA_FRAME_FLAGS); return false; } - if (!IsSupportedHttp2FrameType(header.type)) { - if (extension_ != nullptr) { - // Unknown frames will be passed to the registered extension. - return true; - } - // In HTTP2 we ignore unknown frame types for extensibility, as long as - // the rest of the control frame header is valid. - // We rely on the visitor to check validity of stream_id. - bool valid_stream = - visitor()->OnUnknownFrame(header.stream_id, raw_frame_type); - if (!valid_stream) { - // Report an invalid frame error if the stream_id is not valid. - VLOG(1) << "Unknown control frame type " << header.type - << " received on invalid stream " << header.stream_id; - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME); - return false; - } else { - DVLOG(1) << "Ignoring unknown frame type " << header.type; - return true; - } - } - - SpdyFrameType frame_type = ToSpdyFrameType(header.type); - if (!IsValidHTTP2FrameStreamId(header.stream_id, frame_type)) { - VLOG(1) << "The framer received an invalid streamID of " - << header.stream_id << " for a frame of type " << header.type; - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID); - return false; - } - - if (has_expected_frame_type_ && header.type != expected_frame_type_) { - VLOG(1) << "Expected frame type " << expected_frame_type_ << ", not " - << header.type; - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME); - return false; - } - - if (!has_expected_frame_type_ && - header.type == Http2FrameType::CONTINUATION) { - VLOG(1) << "Got CONTINUATION frame when not expected."; - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME); - return false; - } - - if (header.type == Http2FrameType::DATA) { - // For some reason SpdyFramer still rejects invalid DATA frame flags. - uint8_t valid_flags = Http2FrameFlag::PADDED | Http2FrameFlag::END_STREAM; - if (header.HasAnyFlags(~valid_flags)) { - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_DATA_FRAME_FLAGS); - return false; - } - } - - return true; } - void OnDataStart(const Http2FrameHeader& header) override { - DVLOG(1) << "OnDataStart: " << header; + return true; +} - if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) { - frame_header_ = header; - has_frame_header_ = true; - visitor()->OnDataFrameHeader(header.stream_id, header.payload_length, - header.IsEndStream()); +void Http2DecoderAdapter::OnDataStart(const Http2FrameHeader& header) { + DVLOG(1) << "OnDataStart: " << header; + + if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) { + frame_header_ = header; + has_frame_header_ = true; + visitor()->OnDataFrameHeader(header.stream_id, header.payload_length, + header.IsEndStream()); + } +} + +void Http2DecoderAdapter::OnDataPayload(const char* data, size_t len) { + DVLOG(1) << "OnDataPayload: len=" << len; + DCHECK(has_frame_header_); + DCHECK_EQ(frame_header_.type, Http2FrameType::DATA); + visitor()->OnStreamFrameData(frame_header().stream_id, data, len); +} + +void Http2DecoderAdapter::OnDataEnd() { + DVLOG(1) << "OnDataEnd"; + DCHECK(has_frame_header_); + DCHECK_EQ(frame_header_.type, Http2FrameType::DATA); + if (frame_header().IsEndStream()) { + visitor()->OnStreamEnd(frame_header().stream_id); + } + opt_pad_length_.reset(); +} + +void Http2DecoderAdapter::OnHeadersStart(const Http2FrameHeader& header) { + DVLOG(1) << "OnHeadersStart: " << header; + if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) { + frame_header_ = header; + has_frame_header_ = true; + if (header.HasPriority()) { + // Once we've got the priority fields, then we can report the arrival + // of this HEADERS frame. + on_headers_called_ = false; + return; } - } - - void OnDataPayload(const char* data, size_t len) override { - DVLOG(1) << "OnDataPayload: len=" << len; - DCHECK(has_frame_header_); - DCHECK_EQ(frame_header_.type, Http2FrameType::DATA); - visitor()->OnStreamFrameData(frame_header().stream_id, data, len); - } - - void OnDataEnd() override { - DVLOG(1) << "OnDataEnd"; - DCHECK(has_frame_header_); - DCHECK_EQ(frame_header_.type, Http2FrameType::DATA); - if (frame_header().IsEndStream()) { - visitor()->OnStreamEnd(frame_header().stream_id); - } - opt_pad_length_.reset(); - } - - void OnHeadersStart(const Http2FrameHeader& header) override { - DVLOG(1) << "OnHeadersStart: " << header; - if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) { - frame_header_ = header; - has_frame_header_ = true; - if (header.HasPriority()) { - // Once we've got the priority fields, then we can report the arrival - // of this HEADERS frame. - on_headers_called_ = false; - return; - } - on_headers_called_ = true; - ReportReceiveCompressedFrame(header); - visitor()->OnHeaders(header.stream_id, kNotHasPriorityFields, - 0, // priority - 0, // parent_stream_id - false, // exclusive - header.IsEndStream(), header.IsEndHeaders()); - CommonStartHpackBlock(); - } - } - - void OnHeadersPriority(const Http2PriorityFields& priority) override { - DVLOG(1) << "OnHeadersPriority: " << priority; - DCHECK(has_frame_header_); - DCHECK_EQ(frame_type(), Http2FrameType::HEADERS) << frame_header_; - DCHECK(frame_header_.HasPriority()); - DCHECK(!on_headers_called_); on_headers_called_ = true; - ReportReceiveCompressedFrame(frame_header_); - visitor()->OnHeaders(frame_header_.stream_id, kHasPriorityFields, - priority.weight, priority.stream_dependency, - priority.is_exclusive, frame_header_.IsEndStream(), - frame_header_.IsEndHeaders()); + ReportReceiveCompressedFrame(header); + visitor()->OnHeaders(header.stream_id, kNotHasPriorityFields, + 0, // priority + 0, // parent_stream_id + false, // exclusive + header.IsEndStream(), header.IsEndHeaders()); CommonStartHpackBlock(); } +} - void OnHpackFragment(const char* data, size_t len) override { - DVLOG(1) << "OnHpackFragment: len=" << len; - on_hpack_fragment_called_ = true; - if (!GetHpackDecoder()->HandleControlFrameHeadersData(data, len)) { - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_DECOMPRESS_FAILURE); - return; - } +void Http2DecoderAdapter::OnHeadersPriority( + const Http2PriorityFields& priority) { + DVLOG(1) << "OnHeadersPriority: " << priority; + DCHECK(has_frame_header_); + DCHECK_EQ(frame_type(), Http2FrameType::HEADERS) << frame_header_; + DCHECK(frame_header_.HasPriority()); + DCHECK(!on_headers_called_); + on_headers_called_ = true; + ReportReceiveCompressedFrame(frame_header_); + visitor()->OnHeaders(frame_header_.stream_id, kHasPriorityFields, + priority.weight, priority.stream_dependency, + priority.is_exclusive, frame_header_.IsEndStream(), + frame_header_.IsEndHeaders()); + CommonStartHpackBlock(); +} + +void Http2DecoderAdapter::OnHpackFragment(const char* data, size_t len) { + DVLOG(1) << "OnHpackFragment: len=" << len; + on_hpack_fragment_called_ = true; + if (!GetHpackDecoder()->HandleControlFrameHeadersData(data, len)) { + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_DECOMPRESS_FAILURE); + return; } +} - void OnHeadersEnd() override { - DVLOG(1) << "OnHeadersEnd"; - CommonHpackFragmentEnd(); - opt_pad_length_.reset(); +void Http2DecoderAdapter::OnHeadersEnd() { + DVLOG(1) << "OnHeadersEnd"; + CommonHpackFragmentEnd(); + opt_pad_length_.reset(); +} + +void Http2DecoderAdapter::OnPriorityFrame(const Http2FrameHeader& header, + const Http2PriorityFields& priority) { + DVLOG(1) << "OnPriorityFrame: " << header << "; priority: " << priority; + if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) { + visitor()->OnPriority(header.stream_id, priority.stream_dependency, + priority.weight, priority.is_exclusive); } +} - void OnPriorityFrame(const Http2FrameHeader& header, - const Http2PriorityFields& priority) override { - DVLOG(1) << "OnPriorityFrame: " << header << "; priority: " << priority; - if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) { - visitor()->OnPriority(header.stream_id, priority.stream_dependency, - priority.weight, priority.is_exclusive); - } - } - - void OnContinuationStart(const Http2FrameHeader& header) override { - DVLOG(1) << "OnContinuationStart: " << header; - if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) { - DCHECK(has_hpack_first_frame_header_); - if (header.stream_id != hpack_first_frame_header_.stream_id) { - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME); - return; - } - frame_header_ = header; - has_frame_header_ = true; - ReportReceiveCompressedFrame(header); - visitor()->OnContinuation(header.stream_id, header.IsEndHeaders()); - } - } - - void OnContinuationEnd() override { - DVLOG(1) << "OnContinuationEnd"; - CommonHpackFragmentEnd(); - } - - void OnPadLength(size_t trailing_length) override { - DVLOG(1) << "OnPadLength: " << trailing_length; - opt_pad_length_ = trailing_length; - if (frame_header_.type == Http2FrameType::DATA) { - visitor()->OnStreamPadding(stream_id(), 1); - } else if (frame_header_.type == Http2FrameType::HEADERS) { - CHECK_LT(trailing_length, 256u); - } - } - - void OnPadding(const char* padding, size_t skipped_length) override { - DVLOG(1) << "OnPadding: " << skipped_length; - if (frame_header_.type == Http2FrameType::DATA) { - visitor()->OnStreamPadding(stream_id(), skipped_length); - } else { - MaybeAnnounceEmptyFirstHpackFragment(); - } - } - - void OnRstStream(const Http2FrameHeader& header, - Http2ErrorCode http2_error_code) override { - DVLOG(1) << "OnRstStream: " << header << "; code=" << http2_error_code; - if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) { - SpdyErrorCode error_code = - ParseErrorCode(static_cast<uint32_t>(http2_error_code)); - visitor()->OnRstStream(header.stream_id, error_code); - } - } - - void OnSettingsStart(const Http2FrameHeader& header) override { - DVLOG(1) << "OnSettingsStart: " << header; - if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) { - frame_header_ = header; - has_frame_header_ = true; - visitor()->OnSettings(); - } - } - - void OnSetting(const Http2SettingFields& setting_fields) override { - DVLOG(1) << "OnSetting: " << setting_fields; - const uint16_t parameter = static_cast<uint16_t>(setting_fields.parameter); - SpdySettingsIds setting_id; - if (!ParseSettingsId(parameter, &setting_id)) { - if (extension_ == nullptr) { - DVLOG(1) << "Ignoring unknown setting id: " << setting_fields; - } else { - extension_->OnSetting(parameter, setting_fields.value); - } - return; - } - visitor()->OnSetting(setting_id, setting_fields.value); - } - - void OnSettingsEnd() override { - DVLOG(1) << "OnSettingsEnd"; - visitor()->OnSettingsEnd(); - } - - void OnSettingsAck(const Http2FrameHeader& header) override { - DVLOG(1) << "OnSettingsAck: " << header; - if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) { - visitor()->OnSettingsAck(); - } - } - - void OnPushPromiseStart(const Http2FrameHeader& header, - const Http2PushPromiseFields& promise, - size_t total_padding_length) override { - DVLOG(1) << "OnPushPromiseStart: " << header << "; promise: " << promise - << "; total_padding_length: " << total_padding_length; - if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) { - if (promise.promised_stream_id == 0) { - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME); - return; - } - frame_header_ = header; - has_frame_header_ = true; - ReportReceiveCompressedFrame(header); - visitor()->OnPushPromise(header.stream_id, promise.promised_stream_id, - header.IsEndHeaders()); - CommonStartHpackBlock(); - } - } - - void OnPushPromiseEnd() override { - DVLOG(1) << "OnPushPromiseEnd"; - CommonHpackFragmentEnd(); - opt_pad_length_.reset(); - } - - void OnPing(const Http2FrameHeader& header, - const Http2PingFields& ping) override { - DVLOG(1) << "OnPing: " << header << "; ping: " << ping; - if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) { - visitor()->OnPing(ToSpdyPingId(ping), false); - } - } - - void OnPingAck(const Http2FrameHeader& header, - const Http2PingFields& ping) override { - DVLOG(1) << "OnPingAck: " << header << "; ping: " << ping; - if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) { - visitor()->OnPing(ToSpdyPingId(ping), true); - } - } - - void OnGoAwayStart(const Http2FrameHeader& header, - const Http2GoAwayFields& goaway) override { - DVLOG(1) << "OnGoAwayStart: " << header << "; goaway: " << goaway; - if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) { - frame_header_ = header; - has_frame_header_ = true; - SpdyErrorCode error_code = - ParseErrorCode(static_cast<uint32_t>(goaway.error_code)); - visitor()->OnGoAway(goaway.last_stream_id, error_code); - } - } - - void OnGoAwayOpaqueData(const char* data, size_t len) override { - DVLOG(1) << "OnGoAwayOpaqueData: len=" << len; - visitor()->OnGoAwayFrameData(data, len); - } - - void OnGoAwayEnd() override { - DVLOG(1) << "OnGoAwayEnd"; - visitor()->OnGoAwayFrameData(nullptr, 0); - } - - void OnWindowUpdate(const Http2FrameHeader& header, - uint32_t increment) override { - DVLOG(1) << "OnWindowUpdate: " << header << "; increment=" << increment; - if (IsOkToStartFrame(header)) { - visitor()->OnWindowUpdate(header.stream_id, increment); - } - } - - // Per RFC7838, an ALTSVC frame on stream 0 with origin_length == 0, or one on - // a stream other than stream 0 with origin_length != 0 MUST be ignored. All - // frames are decoded by Http2DecoderAdapter, and it is left to the consumer - // (listener) to implement this behavior. - void OnAltSvcStart(const Http2FrameHeader& header, - size_t origin_length, - size_t value_length) override { - DVLOG(1) << "OnAltSvcStart: " << header - << "; origin_length: " << origin_length - << "; value_length: " << value_length; - if (!IsOkToStartFrame(header)) { +void Http2DecoderAdapter::OnContinuationStart(const Http2FrameHeader& header) { + DVLOG(1) << "OnContinuationStart: " << header; + if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) { + DCHECK(has_hpack_first_frame_header_); + if (header.stream_id != hpack_first_frame_header_.stream_id) { + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME); return; } frame_header_ = header; has_frame_header_ = true; - alt_svc_origin_.clear(); - alt_svc_value_.clear(); + ReportReceiveCompressedFrame(header); + visitor()->OnContinuation(header.stream_id, header.IsEndHeaders()); } +} - void OnAltSvcOriginData(const char* data, size_t len) override { - DVLOG(1) << "OnAltSvcOriginData: len=" << len; - alt_svc_origin_.append(data, len); +void Http2DecoderAdapter::OnContinuationEnd() { + DVLOG(1) << "OnContinuationEnd"; + CommonHpackFragmentEnd(); +} + +void Http2DecoderAdapter::OnPadLength(size_t trailing_length) { + DVLOG(1) << "OnPadLength: " << trailing_length; + opt_pad_length_ = trailing_length; + if (frame_header_.type == Http2FrameType::DATA) { + visitor()->OnStreamPadding(stream_id(), 1); + } else if (frame_header_.type == Http2FrameType::HEADERS) { + CHECK_LT(trailing_length, 256u); } +} - // Called when decoding the Alt-Svc-Field-Value of an ALTSVC; - // the field is uninterpreted. - void OnAltSvcValueData(const char* data, size_t len) override { - DVLOG(1) << "OnAltSvcValueData: len=" << len; - alt_svc_value_.append(data, len); +void Http2DecoderAdapter::OnPadding(const char* padding, + size_t skipped_length) { + DVLOG(1) << "OnPadding: " << skipped_length; + if (frame_header_.type == Http2FrameType::DATA) { + visitor()->OnStreamPadding(stream_id(), skipped_length); + } else { + MaybeAnnounceEmptyFirstHpackFragment(); } +} - void OnAltSvcEnd() override { - DVLOG(1) << "OnAltSvcEnd: origin.size(): " << alt_svc_origin_.size() - << "; value.size(): " << alt_svc_value_.size(); - SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector; - if (!SpdyAltSvcWireFormat::ParseHeaderFieldValue(alt_svc_value_, - &altsvc_vector)) { - DLOG(ERROR) << "SpdyAltSvcWireFormat::ParseHeaderFieldValue failed."; +void Http2DecoderAdapter::OnRstStream(const Http2FrameHeader& header, + Http2ErrorCode http2_error_code) { + DVLOG(1) << "OnRstStream: " << header << "; code=" << http2_error_code; + if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) { + SpdyErrorCode error_code = + ParseErrorCode(static_cast<uint32_t>(http2_error_code)); + visitor()->OnRstStream(header.stream_id, error_code); + } +} + +void Http2DecoderAdapter::OnSettingsStart(const Http2FrameHeader& header) { + DVLOG(1) << "OnSettingsStart: " << header; + if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) { + frame_header_ = header; + has_frame_header_ = true; + visitor()->OnSettings(); + } +} + +void Http2DecoderAdapter::OnSetting(const Http2SettingFields& setting_fields) { + DVLOG(1) << "OnSetting: " << setting_fields; + const uint16_t parameter = static_cast<uint16_t>(setting_fields.parameter); + SpdySettingsIds setting_id; + if (!ParseSettingsId(parameter, &setting_id)) { + if (extension_ == nullptr) { + DVLOG(1) << "Ignoring unknown setting id: " << setting_fields; + } else { + extension_->OnSetting(parameter, setting_fields.value); + } + return; + } + visitor()->OnSetting(setting_id, setting_fields.value); +} + +void Http2DecoderAdapter::OnSettingsEnd() { + DVLOG(1) << "OnSettingsEnd"; + visitor()->OnSettingsEnd(); +} + +void Http2DecoderAdapter::OnSettingsAck(const Http2FrameHeader& header) { + DVLOG(1) << "OnSettingsAck: " << header; + if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) { + visitor()->OnSettingsAck(); + } +} + +void Http2DecoderAdapter::OnPushPromiseStart( + const Http2FrameHeader& header, + const Http2PushPromiseFields& promise, + size_t total_padding_length) { + DVLOG(1) << "OnPushPromiseStart: " << header << "; promise: " << promise + << "; total_padding_length: " << total_padding_length; + if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) { + if (promise.promised_stream_id == 0) { SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME); return; } - visitor()->OnAltSvc(frame_header_.stream_id, alt_svc_origin_, - altsvc_vector); - // We assume that ALTSVC frames are rare, so get rid of the storage. - alt_svc_origin_.clear(); - alt_svc_origin_.shrink_to_fit(); - alt_svc_value_.clear(); - alt_svc_value_.shrink_to_fit(); + frame_header_ = header; + has_frame_header_ = true; + ReportReceiveCompressedFrame(header); + visitor()->OnPushPromise(header.stream_id, promise.promised_stream_id, + header.IsEndHeaders()); + CommonStartHpackBlock(); } +} - // Except for BLOCKED frames, all other unknown frames are either dropped or - // passed to a registered extension. - void OnUnknownStart(const Http2FrameHeader& header) override { - DVLOG(1) << "OnUnknownStart: " << header; - if (IsOkToStartFrame(header)) { - if (extension_ != nullptr) { - const uint8_t type = static_cast<uint8_t>(header.type); - const uint8_t flags = static_cast<uint8_t>(header.flags); - handling_extension_payload_ = extension_->OnFrameHeader( - header.stream_id, header.payload_length, type, flags); - } +void Http2DecoderAdapter::OnPushPromiseEnd() { + DVLOG(1) << "OnPushPromiseEnd"; + CommonHpackFragmentEnd(); + opt_pad_length_.reset(); +} + +void Http2DecoderAdapter::OnPing(const Http2FrameHeader& header, + const Http2PingFields& ping) { + DVLOG(1) << "OnPing: " << header << "; ping: " << ping; + if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) { + visitor()->OnPing(ToSpdyPingId(ping), false); + } +} + +void Http2DecoderAdapter::OnPingAck(const Http2FrameHeader& header, + const Http2PingFields& ping) { + DVLOG(1) << "OnPingAck: " << header << "; ping: " << ping; + if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) { + visitor()->OnPing(ToSpdyPingId(ping), true); + } +} + +void Http2DecoderAdapter::OnGoAwayStart(const Http2FrameHeader& header, + const Http2GoAwayFields& goaway) { + DVLOG(1) << "OnGoAwayStart: " << header << "; goaway: " << goaway; + if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) { + frame_header_ = header; + has_frame_header_ = true; + SpdyErrorCode error_code = + ParseErrorCode(static_cast<uint32_t>(goaway.error_code)); + visitor()->OnGoAway(goaway.last_stream_id, error_code); + } +} + +void Http2DecoderAdapter::OnGoAwayOpaqueData(const char* data, size_t len) { + DVLOG(1) << "OnGoAwayOpaqueData: len=" << len; + visitor()->OnGoAwayFrameData(data, len); +} + +void Http2DecoderAdapter::OnGoAwayEnd() { + DVLOG(1) << "OnGoAwayEnd"; + visitor()->OnGoAwayFrameData(nullptr, 0); +} + +void Http2DecoderAdapter::OnWindowUpdate(const Http2FrameHeader& header, + uint32_t increment) { + DVLOG(1) << "OnWindowUpdate: " << header << "; increment=" << increment; + if (IsOkToStartFrame(header)) { + visitor()->OnWindowUpdate(header.stream_id, increment); + } +} + +// Per RFC7838, an ALTSVC frame on stream 0 with origin_length == 0, or one on +// a stream other than stream 0 with origin_length != 0 MUST be ignored. All +// frames are decoded by Http2DecoderAdapter, and it is left to the consumer +// (listener) to implement this behavior. +void Http2DecoderAdapter::OnAltSvcStart(const Http2FrameHeader& header, + size_t origin_length, + size_t value_length) { + DVLOG(1) << "OnAltSvcStart: " << header + << "; origin_length: " << origin_length + << "; value_length: " << value_length; + if (!IsOkToStartFrame(header)) { + return; + } + frame_header_ = header; + has_frame_header_ = true; + alt_svc_origin_.clear(); + alt_svc_value_.clear(); +} + +void Http2DecoderAdapter::OnAltSvcOriginData(const char* data, size_t len) { + DVLOG(1) << "OnAltSvcOriginData: len=" << len; + alt_svc_origin_.append(data, len); +} + +// Called when decoding the Alt-Svc-Field-Value of an ALTSVC; +// the field is uninterpreted. +void Http2DecoderAdapter::OnAltSvcValueData(const char* data, size_t len) { + DVLOG(1) << "OnAltSvcValueData: len=" << len; + alt_svc_value_.append(data, len); +} + +void Http2DecoderAdapter::OnAltSvcEnd() { + DVLOG(1) << "OnAltSvcEnd: origin.size(): " << alt_svc_origin_.size() + << "; value.size(): " << alt_svc_value_.size(); + SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector; + if (!SpdyAltSvcWireFormat::ParseHeaderFieldValue(alt_svc_value_, + &altsvc_vector)) { + DLOG(ERROR) << "SpdyAltSvcWireFormat::ParseHeaderFieldValue failed."; + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME); + return; + } + visitor()->OnAltSvc(frame_header_.stream_id, alt_svc_origin_, altsvc_vector); + // We assume that ALTSVC frames are rare, so get rid of the storage. + alt_svc_origin_.clear(); + alt_svc_origin_.shrink_to_fit(); + alt_svc_value_.clear(); + alt_svc_value_.shrink_to_fit(); +} + +// Except for BLOCKED frames, all other unknown frames are either dropped or +// passed to a registered extension. +void Http2DecoderAdapter::OnUnknownStart(const Http2FrameHeader& header) { + DVLOG(1) << "OnUnknownStart: " << header; + if (IsOkToStartFrame(header)) { + if (extension_ != nullptr) { + const uint8_t type = static_cast<uint8_t>(header.type); + const uint8_t flags = static_cast<uint8_t>(header.flags); + handling_extension_payload_ = extension_->OnFrameHeader( + header.stream_id, header.payload_length, type, flags); } } +} - void OnUnknownPayload(const char* data, size_t len) override { - if (handling_extension_payload_) { - extension_->OnFramePayload(data, len); - } else { - DVLOG(1) << "OnUnknownPayload: len=" << len; - } +void Http2DecoderAdapter::OnUnknownPayload(const char* data, size_t len) { + if (handling_extension_payload_) { + extension_->OnFramePayload(data, len); + } else { + DVLOG(1) << "OnUnknownPayload: len=" << len; } +} - void OnUnknownEnd() override { - DVLOG(1) << "OnUnknownEnd"; - handling_extension_payload_ = false; - } +void Http2DecoderAdapter::OnUnknownEnd() { + DVLOG(1) << "OnUnknownEnd"; + handling_extension_payload_ = false; +} - void OnPaddingTooLong(const Http2FrameHeader& header, - size_t missing_length) override { - DVLOG(1) << "OnPaddingTooLong: " << header - << "; missing_length: " << missing_length; - if (header.type == Http2FrameType::DATA) { - if (header.payload_length == 0) { - DCHECK_EQ(1u, missing_length); - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_DATA_FRAME_FLAGS); - return; - } - visitor()->OnStreamPadding(header.stream_id, 1); - } - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_PADDING); - } - - void OnFrameSizeError(const Http2FrameHeader& header) override { - DVLOG(1) << "OnFrameSizeError: " << header; - size_t recv_limit = recv_frame_size_limit_; - if (header.payload_length > recv_limit) { - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_OVERSIZED_PAYLOAD); +void Http2DecoderAdapter::OnPaddingTooLong(const Http2FrameHeader& header, + size_t missing_length) { + DVLOG(1) << "OnPaddingTooLong: " << header + << "; missing_length: " << missing_length; + if (header.type == Http2FrameType::DATA) { + if (header.payload_length == 0) { + DCHECK_EQ(1u, missing_length); + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_DATA_FRAME_FLAGS); return; } - if (header.type != Http2FrameType::DATA && - header.payload_length > recv_limit) { - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_CONTROL_PAYLOAD_TOO_LARGE); - return; - } - switch (header.type) { - case Http2FrameType::GOAWAY: - case Http2FrameType::ALTSVC: - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME); - break; - default: - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME_SIZE); - } + visitor()->OnStreamPadding(header.stream_id, 1); } + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_PADDING); +} - private: - // Decodes the input up to the next frame boundary (i.e. at most one frame), - // stopping early if an error is detected. - size_t ProcessInputFrame(const char* data, size_t len) { - DCHECK_NE(spdy_state_, SpdyState::SPDY_ERROR); - DecodeBuffer db(data, len); - DecodeStatus status = frame_decoder_->DecodeFrame(&db); - if (spdy_state_ != SpdyFramer::SPDY_ERROR) { - DetermineSpdyState(status); - } else { - VLOG(1) << "ProcessInputFrame spdy_framer_error_=" - << SpdyFramer::SpdyFramerErrorToString(spdy_framer_error_); - if (spdy_framer_error_ == SpdyFramerError::SPDY_INVALID_PADDING && - has_frame_header_ && frame_type() != Http2FrameType::DATA) { - // spdy_framer_test checks that all of the available frame payload - // has been consumed, so do that. - size_t total = remaining_total_payload(); - if (total <= frame_header().payload_length) { - size_t avail = db.MinLengthRemaining(total); - VLOG(1) << "Skipping past " << avail << " bytes, of " << total - << " total remaining in the frame's payload."; - db.AdvanceCursor(avail); - } else { - SPDY_BUG << "Total remaining (" << total - << ") should not be greater than the payload length; " - << frame_header(); - } +void Http2DecoderAdapter::OnFrameSizeError(const Http2FrameHeader& header) { + DVLOG(1) << "OnFrameSizeError: " << header; + size_t recv_limit = recv_frame_size_limit_; + if (header.payload_length > recv_limit) { + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_OVERSIZED_PAYLOAD); + return; + } + if (header.type != Http2FrameType::DATA && + header.payload_length > recv_limit) { + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_CONTROL_PAYLOAD_TOO_LARGE); + return; + } + switch (header.type) { + case Http2FrameType::GOAWAY: + case Http2FrameType::ALTSVC: + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME); + break; + default: + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME_SIZE); + } +} + +// Decodes the input up to the next frame boundary (i.e. at most one frame), +// stopping early if an error is detected. +size_t Http2DecoderAdapter::ProcessInputFrame(const char* data, size_t len) { + DCHECK_NE(spdy_state_, SpdyState::SPDY_ERROR); + DecodeBuffer db(data, len); + DecodeStatus status = frame_decoder_->DecodeFrame(&db); + if (spdy_state_ != SpdyState::SPDY_ERROR) { + DetermineSpdyState(status); + } else { + VLOG(1) << "ProcessInputFrame spdy_framer_error_=" + << SpdyFramer::SpdyFramerErrorToString(spdy_framer_error_); + if (spdy_framer_error_ == SpdyFramerError::SPDY_INVALID_PADDING && + has_frame_header_ && frame_type() != Http2FrameType::DATA) { + // spdy_framer_test checks that all of the available frame payload + // has been consumed, so do that. + size_t total = remaining_total_payload(); + if (total <= frame_header().payload_length) { + size_t avail = db.MinLengthRemaining(total); + VLOG(1) << "Skipping past " << avail << " bytes, of " << total + << " total remaining in the frame's payload."; + db.AdvanceCursor(avail); + } else { + SPDY_BUG << "Total remaining (" << total + << ") should not be greater than the payload length; " + << frame_header(); } } - return db.Offset(); } + return db.Offset(); +} - // After decoding, determine the next SpdyState. Only called if the current - // state is NOT SpdyState::SPDY_ERROR (i.e. if none of the callback methods - // detected an error condition), because otherwise we assume that the callback - // method has set spdy_framer_error_ appropriately. - void DetermineSpdyState(DecodeStatus status) { - DCHECK_EQ(spdy_framer_error_, SpdyFramer::SPDY_NO_ERROR); - DCHECK(!HasError()) << spdy_framer_error_; - switch (status) { - case DecodeStatus::kDecodeDone: - DVLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeDone"; - ResetBetweenFrames(); - break; - case DecodeStatus::kDecodeInProgress: - DVLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeInProgress"; - if (decoded_frame_header_) { - if (IsDiscardingPayload()) { - set_spdy_state(SpdyState::SPDY_IGNORE_REMAINING_PAYLOAD); - } else if (has_frame_header_ && - frame_type() == Http2FrameType::DATA) { - if (IsReadingPaddingLength()) { - set_spdy_state(SpdyState::SPDY_READ_DATA_FRAME_PADDING_LENGTH); - } else if (IsSkippingPadding()) { - set_spdy_state(SpdyState::SPDY_CONSUME_PADDING); - } else { - set_spdy_state(SpdyState::SPDY_FORWARD_STREAM_FRAME); - } - } else { - set_spdy_state(SpdyState::SPDY_CONTROL_FRAME_PAYLOAD); - } - } else { - set_spdy_state(SpdyState::SPDY_READING_COMMON_HEADER); - } - break; - case DecodeStatus::kDecodeError: - VLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeError"; +// After decoding, determine the next SpdyState. Only called if the current +// state is NOT SpdyState::SPDY_ERROR (i.e. if none of the callback methods +// detected an error condition), because otherwise we assume that the callback +// method has set spdy_framer_error_ appropriately. +void Http2DecoderAdapter::DetermineSpdyState(DecodeStatus status) { + DCHECK_EQ(spdy_framer_error_, SpdyFramer::SPDY_NO_ERROR); + DCHECK(!HasError()) << spdy_framer_error_; + switch (status) { + case DecodeStatus::kDecodeDone: + DVLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeDone"; + ResetBetweenFrames(); + break; + case DecodeStatus::kDecodeInProgress: + DVLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeInProgress"; + if (decoded_frame_header_) { if (IsDiscardingPayload()) { - if (remaining_total_payload() == 0) { - // Push the Http2FrameDecoder out of state kDiscardPayload now - // since doing so requires no input. - DecodeBuffer tmp("", 0); - DecodeStatus status = frame_decoder_->DecodeFrame(&tmp); - if (status != DecodeStatus::kDecodeDone) { - SPDY_BUG << "Expected to be done decoding the frame, not " - << status; - SetSpdyErrorAndNotify(SpdyFramer::SPDY_INTERNAL_FRAMER_ERROR); - } else if (spdy_framer_error_ != SpdyFramer::SPDY_NO_ERROR) { - SPDY_BUG << "Expected to have no error, not " - << SpdyFramer::SpdyFramerErrorToString( - spdy_framer_error_); - } else { - ResetBetweenFrames(); - } + set_spdy_state(SpdyState::SPDY_IGNORE_REMAINING_PAYLOAD); + } else if (has_frame_header_ && frame_type() == Http2FrameType::DATA) { + if (IsReadingPaddingLength()) { + set_spdy_state(SpdyState::SPDY_READ_DATA_FRAME_PADDING_LENGTH); + } else if (IsSkippingPadding()) { + set_spdy_state(SpdyState::SPDY_CONSUME_PADDING); } else { - set_spdy_state(SpdyState::SPDY_IGNORE_REMAINING_PAYLOAD); + set_spdy_state(SpdyState::SPDY_FORWARD_STREAM_FRAME); } } else { - SetSpdyErrorAndNotify(SpdyFramer::SPDY_INVALID_CONTROL_FRAME); + set_spdy_state(SpdyState::SPDY_CONTROL_FRAME_PAYLOAD); } - break; - } + } else { + set_spdy_state(SpdyState::SPDY_READING_COMMON_HEADER); + } + break; + case DecodeStatus::kDecodeError: + VLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeError"; + if (IsDiscardingPayload()) { + if (remaining_total_payload() == 0) { + // Push the Http2FrameDecoder out of state kDiscardPayload now + // since doing so requires no input. + DecodeBuffer tmp("", 0); + DecodeStatus status = frame_decoder_->DecodeFrame(&tmp); + if (status != DecodeStatus::kDecodeDone) { + SPDY_BUG << "Expected to be done decoding the frame, not " + << status; + SetSpdyErrorAndNotify(SpdyFramer::SPDY_INTERNAL_FRAMER_ERROR); + } else if (spdy_framer_error_ != SpdyFramer::SPDY_NO_ERROR) { + SPDY_BUG << "Expected to have no error, not " + << SpdyFramer::SpdyFramerErrorToString(spdy_framer_error_); + } else { + ResetBetweenFrames(); + } + } else { + set_spdy_state(SpdyState::SPDY_IGNORE_REMAINING_PAYLOAD); + } + } else { + SetSpdyErrorAndNotify(SpdyFramer::SPDY_INVALID_CONTROL_FRAME); + } + break; + } +} + +void Http2DecoderAdapter::ResetBetweenFrames() { + CorruptFrameHeader(&frame_header_); + decoded_frame_header_ = false; + has_frame_header_ = false; + set_spdy_state(SpdyState::SPDY_READY_FOR_FRAME); +} + +// ResetInternal is called from the constructor, and during tests, but not +// otherwise (i.e. not between every frame). +void Http2DecoderAdapter::ResetInternal() { + set_spdy_state(SpdyState::SPDY_READY_FOR_FRAME); + spdy_framer_error_ = SpdyFramerError::SPDY_NO_ERROR; + + decoded_frame_header_ = false; + has_frame_header_ = false; + on_headers_called_ = false; + on_hpack_fragment_called_ = false; + latched_probable_http_response_ = false; + has_expected_frame_type_ = false; + + CorruptFrameHeader(&frame_header_); + CorruptFrameHeader(&hpack_first_frame_header_); + + frame_decoder_.reset(new Http2FrameDecoder(this)); + hpack_decoder_ = nullptr; +} + +void Http2DecoderAdapter::set_spdy_state(SpdyState v) { + DVLOG(2) << "set_spdy_state(" << SpdyFramer::StateToString(v) << ")"; + spdy_state_ = v; +} + +void Http2DecoderAdapter::SetSpdyErrorAndNotify(SpdyFramerError error) { + if (HasError()) { + DCHECK_EQ(spdy_state_, SpdyState::SPDY_ERROR); + } else { + VLOG(2) << "SetSpdyErrorAndNotify(" + << SpdyFramer::SpdyFramerErrorToString(error) << ")"; + DCHECK_NE(error, SpdyFramerError::SPDY_NO_ERROR); + spdy_framer_error_ = error; + set_spdy_state(SpdyState::SPDY_ERROR); + frame_decoder_->set_listener(&no_op_listener_); + visitor()->OnError(error); + } +} + +bool Http2DecoderAdapter::HasError() const { + if (spdy_state_ == SpdyState::SPDY_ERROR) { + DCHECK_NE(spdy_framer_error(), SpdyFramerError::SPDY_NO_ERROR); + return true; + } else { + DCHECK_EQ(spdy_framer_error(), SpdyFramerError::SPDY_NO_ERROR); + return false; + } +} + +const Http2FrameHeader& Http2DecoderAdapter::frame_header() const { + DCHECK(has_frame_header_); + return frame_header_; +} + +uint32_t Http2DecoderAdapter::stream_id() const { + return frame_header().stream_id; +} + +Http2FrameType Http2DecoderAdapter::frame_type() const { + return frame_header().type; +} + +size_t Http2DecoderAdapter::remaining_total_payload() const { + DCHECK(has_frame_header_); + size_t remaining = frame_decoder_->remaining_payload(); + if (IsPaddable(frame_type()) && frame_header_.IsPadded()) { + remaining += frame_decoder_->remaining_padding(); + } + return remaining; +} + +bool Http2DecoderAdapter::IsReadingPaddingLength() { + bool result = frame_header_.IsPadded() && !opt_pad_length_; + DVLOG(2) << "Http2DecoderAdapter::IsReadingPaddingLength: " << result; + return result; +} +bool Http2DecoderAdapter::IsSkippingPadding() { + bool result = frame_header_.IsPadded() && opt_pad_length_ && + frame_decoder_->remaining_payload() == 0 && + frame_decoder_->remaining_padding() > 0; + DVLOG(2) << "Http2DecoderAdapter::IsSkippingPadding: " << result; + return result; +} +bool Http2DecoderAdapter::IsDiscardingPayload() { + bool result = decoded_frame_header_ && frame_decoder_->IsDiscardingPayload(); + DVLOG(2) << "Http2DecoderAdapter::IsDiscardingPayload: " << result; + return result; +} +// Called from OnXyz or OnXyzStart methods to decide whether it is OK to +// handle the callback. +bool Http2DecoderAdapter::IsOkToStartFrame(const Http2FrameHeader& header) { + DVLOG(3) << "IsOkToStartFrame"; + if (HasError()) { + VLOG(2) << "HasError()"; + return false; + } + DCHECK(!has_frame_header_); + if (has_expected_frame_type_ && header.type != expected_frame_type_) { + VLOG(1) << "Expected frame type " << expected_frame_type_ << ", not " + << header.type; + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME); + return false; } - void ResetBetweenFrames() { - CorruptFrameHeader(&frame_header_); - decoded_frame_header_ = false; - has_frame_header_ = false; - set_spdy_state(SpdyState::SPDY_READY_FOR_FRAME); + return true; +} + +bool Http2DecoderAdapter::HasRequiredStreamId(uint32_t stream_id) { + DVLOG(3) << "HasRequiredStreamId: " << stream_id; + if (HasError()) { + VLOG(2) << "HasError()"; + return false; } - - // ResetInternal is called from the constructor, and during tests, but not - // otherwise (i.e. not between every frame). - void ResetInternal() { - set_spdy_state(SpdyState::SPDY_READY_FOR_FRAME); - spdy_framer_error_ = SpdyFramerError::SPDY_NO_ERROR; - - decoded_frame_header_ = false; - has_frame_header_ = false; - on_headers_called_ = false; - on_hpack_fragment_called_ = false; - latched_probable_http_response_ = false; - has_expected_frame_type_ = false; - - CorruptFrameHeader(&frame_header_); - CorruptFrameHeader(&hpack_first_frame_header_); - - frame_decoder_.reset(new Http2FrameDecoder(this)); - hpack_decoder_ = nullptr; - } - - void set_spdy_state(SpdyState v) { - DVLOG(2) << "set_spdy_state(" << SpdyFramer::StateToString(v) << ")"; - spdy_state_ = v; - } - - void SetSpdyErrorAndNotify(SpdyFramerError error) { - if (HasError()) { - DCHECK_EQ(spdy_state_, SpdyState::SPDY_ERROR); - } else { - VLOG(2) << "SetSpdyErrorAndNotify(" - << SpdyFramer::SpdyFramerErrorToString(error) << ")"; - DCHECK_NE(error, SpdyFramerError::SPDY_NO_ERROR); - spdy_framer_error_ = error; - set_spdy_state(SpdyState::SPDY_ERROR); - frame_decoder_->set_listener(&no_op_listener_); - visitor()->OnError(error); - } - } - - bool HasError() const { - if (spdy_state_ == SpdyState::SPDY_ERROR) { - DCHECK_NE(spdy_framer_error(), SpdyFramerError::SPDY_NO_ERROR); - return true; - } else { - DCHECK_EQ(spdy_framer_error(), SpdyFramerError::SPDY_NO_ERROR); - return false; - } - } - - const Http2FrameHeader& frame_header() const { - DCHECK(has_frame_header_); - return frame_header_; - } - - uint32_t stream_id() const { return frame_header().stream_id; } - - Http2FrameType frame_type() const { return frame_header().type; } - - size_t remaining_total_payload() const { - DCHECK(has_frame_header_); - size_t remaining = frame_decoder_->remaining_payload(); - if (IsPaddable(frame_type()) && frame_header_.IsPadded()) { - remaining += frame_decoder_->remaining_padding(); - } - return remaining; - } - - bool IsReadingPaddingLength() { - bool result = frame_header_.IsPadded() && !opt_pad_length_; - DVLOG(2) << "Http2DecoderAdapter::IsReadingPaddingLength: " << result; - return result; - } - bool IsSkippingPadding() { - bool result = frame_header_.IsPadded() && opt_pad_length_ && - frame_decoder_->remaining_payload() == 0 && - frame_decoder_->remaining_padding() > 0; - DVLOG(2) << "Http2DecoderAdapter::IsSkippingPadding: " << result; - return result; - } - bool IsDiscardingPayload() { - bool result = - decoded_frame_header_ && frame_decoder_->IsDiscardingPayload(); - DVLOG(2) << "Http2DecoderAdapter::IsDiscardingPayload: " << result; - return result; - } - // Called from OnXyz or OnXyzStart methods to decide whether it is OK to - // handle the callback. - bool IsOkToStartFrame(const Http2FrameHeader& header) { - DVLOG(3) << "IsOkToStartFrame"; - if (HasError()) { - VLOG(2) << "HasError()"; - return false; - } - DCHECK(!has_frame_header_); - if (has_expected_frame_type_ && header.type != expected_frame_type_) { - VLOG(1) << "Expected frame type " << expected_frame_type_ << ", not " - << header.type; - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME); - return false; - } - + if (stream_id != 0) { return true; } + VLOG(1) << "Stream Id is required, but zero provided"; + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID); + return false; +} - bool HasRequiredStreamId(uint32_t stream_id) { - DVLOG(3) << "HasRequiredStreamId: " << stream_id; - if (HasError()) { - VLOG(2) << "HasError()"; - return false; - } - if (stream_id != 0) { - return true; - } - VLOG(1) << "Stream Id is required, but zero provided"; - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID); +bool Http2DecoderAdapter::HasRequiredStreamId(const Http2FrameHeader& header) { + return HasRequiredStreamId(header.stream_id); +} + +bool Http2DecoderAdapter::HasRequiredStreamIdZero(uint32_t stream_id) { + DVLOG(3) << "HasRequiredStreamIdZero: " << stream_id; + if (HasError()) { + VLOG(2) << "HasError()"; return false; } - - bool HasRequiredStreamId(const Http2FrameHeader& header) { - return HasRequiredStreamId(header.stream_id); + if (stream_id == 0) { + return true; } + VLOG(1) << "Stream Id was not zero, as required: " << stream_id; + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID); + return false; +} - bool HasRequiredStreamIdZero(uint32_t stream_id) { - DVLOG(3) << "HasRequiredStreamIdZero: " << stream_id; - if (HasError()) { - VLOG(2) << "HasError()"; - return false; - } - if (stream_id == 0) { - return true; - } - VLOG(1) << "Stream Id was not zero, as required: " << stream_id; - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID); - return false; +bool Http2DecoderAdapter::HasRequiredStreamIdZero( + const Http2FrameHeader& header) { + return HasRequiredStreamIdZero(header.stream_id); +} + +void Http2DecoderAdapter::ReportReceiveCompressedFrame( + const Http2FrameHeader& header) { + if (debug_visitor() != nullptr) { + size_t total = header.payload_length + Http2FrameHeader::EncodedSize(); + debug_visitor()->OnReceiveCompressedFrame( + header.stream_id, ToSpdyFrameType(header.type), total); } +} - bool HasRequiredStreamIdZero(const Http2FrameHeader& header) { - return HasRequiredStreamIdZero(header.stream_id); +HpackDecoderAdapter* Http2DecoderAdapter::GetHpackDecoder() { + if (hpack_decoder_ == nullptr) { + hpack_decoder_ = SpdyMakeUnique<HpackDecoderAdapter>(); } + return hpack_decoder_.get(); +} - void ReportReceiveCompressedFrame(const Http2FrameHeader& header) { - if (debug_visitor() != nullptr) { - size_t total = header.payload_length + Http2FrameHeader::EncodedSize(); - debug_visitor()->OnReceiveCompressedFrame( - header.stream_id, ToSpdyFrameType(header.type), total); - } +void Http2DecoderAdapter::CommonStartHpackBlock() { + DVLOG(1) << "CommonStartHpackBlock"; + DCHECK(!has_hpack_first_frame_header_); + if (!frame_header_.IsEndHeaders()) { + hpack_first_frame_header_ = frame_header_; + has_hpack_first_frame_header_ = true; + } else { + CorruptFrameHeader(&hpack_first_frame_header_); } - - HpackDecoderAdapter* GetHpackDecoder() override { - if (hpack_decoder_ == nullptr) { - hpack_decoder_ = SpdyMakeUnique<HpackDecoderAdapter>(); - } - return hpack_decoder_.get(); + on_hpack_fragment_called_ = false; + SpdyHeadersHandlerInterface* handler = + visitor()->OnHeaderFrameStart(stream_id()); + if (handler == nullptr) { + SPDY_BUG << "visitor_->OnHeaderFrameStart returned nullptr"; + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INTERNAL_FRAMER_ERROR); + return; } + GetHpackDecoder()->HandleControlFrameHeadersStart(handler); +} - void CommonStartHpackBlock() { - DVLOG(1) << "CommonStartHpackBlock"; - DCHECK(!has_hpack_first_frame_header_); - if (!frame_header_.IsEndHeaders()) { - hpack_first_frame_header_ = frame_header_; - has_hpack_first_frame_header_ = true; +// SpdyFramer calls HandleControlFrameHeadersData even if there are zero +// fragment bytes in the first frame, so do the same. +void Http2DecoderAdapter::MaybeAnnounceEmptyFirstHpackFragment() { + if (!on_hpack_fragment_called_) { + OnHpackFragment(nullptr, 0); + DCHECK(on_hpack_fragment_called_); + } +} + +void Http2DecoderAdapter::CommonHpackFragmentEnd() { + DVLOG(1) << "CommonHpackFragmentEnd: stream_id=" << stream_id(); + if (HasError()) { + VLOG(1) << "HasError(), returning"; + return; + } + DCHECK(has_frame_header_); + MaybeAnnounceEmptyFirstHpackFragment(); + if (frame_header_.IsEndHeaders()) { + DCHECK_EQ(has_hpack_first_frame_header_, + frame_type() == Http2FrameType::CONTINUATION) + << frame_header(); + has_expected_frame_type_ = false; + if (GetHpackDecoder()->HandleControlFrameHeadersComplete(nullptr)) { + visitor()->OnHeaderFrameEnd(stream_id()); } else { - CorruptFrameHeader(&hpack_first_frame_header_); - } - on_hpack_fragment_called_ = false; - SpdyHeadersHandlerInterface* handler = - visitor()->OnHeaderFrameStart(stream_id()); - if (handler == nullptr) { - SPDY_BUG << "visitor_->OnHeaderFrameStart returned nullptr"; - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INTERNAL_FRAMER_ERROR); + SetSpdyErrorAndNotify(SpdyFramerError::SPDY_DECOMPRESS_FAILURE); return; } - GetHpackDecoder()->HandleControlFrameHeadersStart(handler); - } - - // SpdyFramer calls HandleControlFrameHeadersData even if there are zero - // fragment bytes in the first frame, so do the same. - void MaybeAnnounceEmptyFirstHpackFragment() { - if (!on_hpack_fragment_called_) { - OnHpackFragment(nullptr, 0); - DCHECK(on_hpack_fragment_called_); + const Http2FrameHeader& first = frame_type() == Http2FrameType::CONTINUATION + ? hpack_first_frame_header_ + : frame_header_; + if (first.type == Http2FrameType::HEADERS && first.IsEndStream()) { + visitor()->OnStreamEnd(first.stream_id); } + has_hpack_first_frame_header_ = false; + CorruptFrameHeader(&hpack_first_frame_header_); + } else { + DCHECK(has_hpack_first_frame_header_); + has_expected_frame_type_ = true; + expected_frame_type_ = Http2FrameType::CONTINUATION; } - - void CommonHpackFragmentEnd() { - DVLOG(1) << "CommonHpackFragmentEnd: stream_id=" << stream_id(); - if (HasError()) { - VLOG(1) << "HasError(), returning"; - return; - } - DCHECK(has_frame_header_); - MaybeAnnounceEmptyFirstHpackFragment(); - if (frame_header_.IsEndHeaders()) { - DCHECK_EQ(has_hpack_first_frame_header_, - frame_type() == Http2FrameType::CONTINUATION) - << frame_header(); - has_expected_frame_type_ = false; - if (GetHpackDecoder()->HandleControlFrameHeadersComplete(nullptr)) { - visitor()->OnHeaderFrameEnd(stream_id()); - } else { - SetSpdyErrorAndNotify(SpdyFramerError::SPDY_DECOMPRESS_FAILURE); - return; - } - const Http2FrameHeader& first = - frame_type() == Http2FrameType::CONTINUATION - ? hpack_first_frame_header_ - : frame_header_; - if (first.type == Http2FrameType::HEADERS && first.IsEndStream()) { - visitor()->OnStreamEnd(first.stream_id); - } - has_hpack_first_frame_header_ = false; - CorruptFrameHeader(&hpack_first_frame_header_); - } else { - DCHECK(has_hpack_first_frame_header_); - has_expected_frame_type_ = true; - expected_frame_type_ = Http2FrameType::CONTINUATION; - } - } - - // If non-null, unknown frames and settings are passed to the extension. - ExtensionVisitorInterface* extension_ = nullptr; - - // The HPACK decoder to be used for this adapter. User is responsible for - // clearing if the adapter is to be used for another connection. - std::unique_ptr<HpackDecoderAdapter> hpack_decoder_ = nullptr; - - // The HTTP/2 frame decoder. Accessed via a unique_ptr to allow replacement - // (e.g. in tests) when Reset() is called. - std::unique_ptr<Http2FrameDecoder> frame_decoder_; - - // The most recently decoded frame header; invalid after we reached the end - // of that frame. - Http2FrameHeader frame_header_; - - // If decoding an HPACK block that is split across multiple frames, this holds - // the frame header of the HEADERS or PUSH_PROMISE that started the block. - Http2FrameHeader hpack_first_frame_header_; - - // Amount of trailing padding. Currently used just as an indicator of whether - // OnPadLength has been called. - base::Optional<size_t> opt_pad_length_; - - // Temporary buffers for the AltSvc fields. - Http2String alt_svc_origin_; - Http2String alt_svc_value_; - - // Listener used if we transition to an error state; the listener ignores all - // the callbacks. - Http2FrameDecoderNoOpListener no_op_listener_; - - // Next frame type expected. Currently only used for CONTINUATION frames, - // but could be used for detecting whether the first frame is a SETTINGS - // frame. - // TODO(jamessyng): Provide means to indicate that decoder should require - // SETTINGS frame as the first frame. - Http2FrameType expected_frame_type_; - - // Attempt to duplicate the SpdyState and SpdyFramerError values that - // SpdyFramer sets. Values determined by getting tests to pass. - SpdyState spdy_state_; - SpdyFramerError spdy_framer_error_; - - // The limit on the size of received HTTP/2 payloads as specified in the - // SETTINGS_MAX_FRAME_SIZE advertised to peer. - size_t recv_frame_size_limit_ = kSpdyInitialFrameSizeLimit; - - // Has OnFrameHeader been called? - bool decoded_frame_header_ = false; - - // Have we recorded an Http2FrameHeader for the current frame? - // We only do so if the decoder will make multiple callbacks for - // the frame; for example, for PING frames we don't make record - // the frame header, but for ALTSVC we do. - bool has_frame_header_ = false; - - // Have we recorded an Http2FrameHeader for the current HPACK block? - // True only for multi-frame HPACK blocks. - bool has_hpack_first_frame_header_ = false; - - // Has OnHeaders() already been called for current HEADERS block? Only - // meaningful between OnHeadersStart and OnHeadersPriority. - bool on_headers_called_; - - // Has OnHpackFragment() already been called for current HPACK block? - // SpdyFramer will pass an empty buffer to the HPACK decoder if a HEADERS - // or PUSH_PROMISE has no HPACK data in it (e.g. a HEADERS frame with only - // padding). Detect that condition and replicate the behavior using this - // field. - bool on_hpack_fragment_called_; - - // Have we seen a frame header that appears to be an HTTP/1 response? - bool latched_probable_http_response_ = false; - - // Is expected_frame_type_ set? - bool has_expected_frame_type_ = false; - - // Is the current frame payload destined for |extension_|? - bool handling_extension_payload_ = false; -}; - -} // namespace +} bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* goaway_data, size_t len) { return true; } -SpdyFramerDecoderAdapter::SpdyFramerDecoderAdapter() { - DVLOG(1) << PRETTY_THIS; -} - -SpdyFramerDecoderAdapter::~SpdyFramerDecoderAdapter() { - DVLOG(1) << PRETTY_THIS; -} - -void SpdyFramerDecoderAdapter::set_visitor( - SpdyFramerVisitorInterface* visitor) { - visitor_ = visitor; -} - -void SpdyFramerDecoderAdapter::set_debug_visitor( - SpdyFramerDebugVisitorInterface* debug_visitor) { - debug_visitor_ = debug_visitor; -} - -void SpdyFramerDecoderAdapter::set_process_single_input_frame(bool v) { - process_single_input_frame_ = v; -} - -std::unique_ptr<SpdyFramerDecoderAdapter> CreateHttp2FrameDecoderAdapter() { +std::unique_ptr<Http2DecoderAdapter> CreateHttp2FrameDecoderAdapter() { return SpdyMakeUnique<Http2DecoderAdapter>(); }
diff --git a/net/spdy/core/http2_frame_decoder_adapter.h b/net/spdy/core/http2_frame_decoder_adapter.h index a1ea8b7c..db463e2 100644 --- a/net/spdy/core/http2_frame_decoder_adapter.h +++ b/net/spdy/core/http2_frame_decoder_adapter.h
@@ -5,15 +5,13 @@ #ifndef NET_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_ #define NET_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_ -// Provides a SpdyFramerDecoderAdapter that uses Http2FrameDecoder for decoding -// HTTP/2 frames. The adapter does not directly decode HPACK, but instead calls -// SpdyFramer::GetHpackDecoderAdapter() to get the decoder to be used. - #include <stddef.h> #include <cstdint> #include <memory> +#include "base/optional.h" +#include "net/http2/decoder/http2_frame_decoder.h" #include "net/spdy/core/hpack/hpack_header_table.h" #include "net/spdy/core/spdy_alt_svc_wire_format.h" #include "net/spdy/core/spdy_framer.h" @@ -23,7 +21,7 @@ namespace net { -// SpdyFramerDecoderAdapter will use the given visitor implementing this +// Http2DecoderAdapter will use the given visitor implementing this // interface to deliver event callbacks as frames are decoded. // // Control frames that contain HTTP2 header blocks (HEADER, and PUSH_PROMISE) @@ -182,42 +180,42 @@ virtual bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) = 0; }; -// Abstract base class for an HTTP/2 decoder to be called from SpdyFramer. -class SpdyFramerDecoderAdapter { +// Adapts SpdyFramer interface to use Http2FrameDecoder. +class SPDY_EXPORT_PRIVATE Http2DecoderAdapter + : public Http2FrameDecoderListener { public: - SpdyFramerDecoderAdapter(); - virtual ~SpdyFramerDecoderAdapter(); + Http2DecoderAdapter(); + ~Http2DecoderAdapter() override; // Set callbacks to be called from the framer. A visitor must be set, or // else the framer will likely crash. It is acceptable for the visitor // to do nothing. If this is called multiple times, only the last visitor // will be used. - virtual void set_visitor(SpdyFramerVisitorInterface* visitor); + void set_visitor(SpdyFramerVisitorInterface* visitor); SpdyFramerVisitorInterface* visitor() const { return visitor_; } // Set extension callbacks to be called from the framer or decoder. Optional. // If called multiple times, only the last visitor will be used. - virtual void set_extension_visitor(ExtensionVisitorInterface* visitor) = 0; + void set_extension_visitor(ExtensionVisitorInterface* visitor); // Set debug callbacks to be called from the framer. The debug visitor is // completely optional and need not be set in order for normal operation. // If this is called multiple times, only the last visitor will be used. - virtual void set_debug_visitor( - SpdyFramerDebugVisitorInterface* debug_visitor); + void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor); SpdyFramerDebugVisitorInterface* debug_visitor() const { return debug_visitor_; } // Set debug callbacks to be called from the HPACK decoder. - virtual void SetDecoderHeaderTableDebugVisitor( - std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) = 0; + void SetDecoderHeaderTableDebugVisitor( + std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor); // Sets whether or not ProcessInput returns after finishing a frame, or // continues processing additional frames. Normally ProcessInput processes // all input, but this method enables the caller (and visitor) to work with // a single frame at a time (or that portion of the frame which is provided // as input). Reset() does not change the value of this flag. - virtual void set_process_single_input_frame(bool v); + void set_process_single_input_frame(bool v); bool process_single_input_frame() const { return process_single_input_frame_; } @@ -226,35 +224,206 @@ // the number of bytes consumed. It is safe to pass more bytes in than // may be consumed. Should process (or otherwise buffer) as much as // available, unless process_single_input_frame is true. - virtual size_t ProcessInput(const char* data, size_t len) = 0; + size_t ProcessInput(const char* data, size_t len); // Reset the decoder (used just for tests at this time). - virtual void Reset() = 0; + void Reset(); // Current state of the decoder. - virtual SpdyFramer::SpdyState state() const = 0; + SpdyFramer::SpdyState state() const; // Current error code (NO_ERROR if state != ERROR). - virtual SpdyFramer::SpdyFramerError spdy_framer_error() const = 0; + SpdyFramer::SpdyFramerError spdy_framer_error() const; // Has any frame header looked like the start of an HTTP/1.1 (or earlier) // response? Used to detect if a backend/server that we sent a request to // has responded with an HTTP/1.1 (or earlier) response. - virtual bool probable_http_response() const = 0; + bool probable_http_response() const; // Returns the estimate of dynamically allocated memory in bytes. - virtual size_t EstimateMemoryUsage() const = 0; + size_t EstimateMemoryUsage() const; - // Get (and lazily initialize) the HPACK decoder state. - virtual HpackDecoderAdapter* GetHpackDecoder() = 0; + HpackDecoderAdapter* GetHpackDecoder(); private: + bool OnFrameHeader(const Http2FrameHeader& header) override; + void OnDataStart(const Http2FrameHeader& header) override; + void OnDataPayload(const char* data, size_t len) override; + void OnDataEnd() override; + void OnHeadersStart(const Http2FrameHeader& header) override; + void OnHeadersPriority(const Http2PriorityFields& priority) override; + void OnHpackFragment(const char* data, size_t len) override; + void OnHeadersEnd() override; + void OnPriorityFrame(const Http2FrameHeader& header, + const Http2PriorityFields& priority) override; + void OnContinuationStart(const Http2FrameHeader& header) override; + void OnContinuationEnd() override; + void OnPadLength(size_t trailing_length) override; + void OnPadding(const char* padding, size_t skipped_length) override; + void OnRstStream(const Http2FrameHeader& header, + Http2ErrorCode http2_error_code) override; + void OnSettingsStart(const Http2FrameHeader& header) override; + void OnSetting(const Http2SettingFields& setting_fields) override; + void OnSettingsEnd() override; + void OnSettingsAck(const Http2FrameHeader& header) override; + void OnPushPromiseStart(const Http2FrameHeader& header, + const Http2PushPromiseFields& promise, + size_t total_padding_length) override; + void OnPushPromiseEnd() override; + void OnPing(const Http2FrameHeader& header, + const Http2PingFields& ping) override; + void OnPingAck(const Http2FrameHeader& header, + const Http2PingFields& ping) override; + void OnGoAwayStart(const Http2FrameHeader& header, + const Http2GoAwayFields& goaway) override; + void OnGoAwayOpaqueData(const char* data, size_t len) override; + void OnGoAwayEnd() override; + void OnWindowUpdate(const Http2FrameHeader& header, + uint32_t increment) override; + void OnAltSvcStart(const Http2FrameHeader& header, + size_t origin_length, + size_t value_length) override; + void OnAltSvcOriginData(const char* data, size_t len) override; + void OnAltSvcValueData(const char* data, size_t len) override; + void OnAltSvcEnd() override; + void OnUnknownStart(const Http2FrameHeader& header) override; + void OnUnknownPayload(const char* data, size_t len) override; + void OnUnknownEnd() override; + void OnPaddingTooLong(const Http2FrameHeader& header, + size_t missing_length) override; + void OnFrameSizeError(const Http2FrameHeader& header) override; + + size_t ProcessInputFrame(const char* data, size_t len); + + void DetermineSpdyState(DecodeStatus status); + void ResetBetweenFrames(); + + // ResetInternal is called from the constructor, and during tests, but not + // otherwise (i.e. not between every frame). + void ResetInternal(); + + void set_spdy_state(SpdyFramer::SpdyState v); + + void SetSpdyErrorAndNotify(SpdyFramer::SpdyFramerError error); + + bool HasError() const; + const Http2FrameHeader& frame_header() const; + + uint32_t stream_id() const; + Http2FrameType frame_type() const; + + size_t remaining_total_payload() const; + + bool IsReadingPaddingLength(); + bool IsSkippingPadding(); + bool IsDiscardingPayload(); + // Called from OnXyz or OnXyzStart methods to decide whether it is OK to + // handle the callback. + bool IsOkToStartFrame(const Http2FrameHeader& header); + bool HasRequiredStreamId(uint32_t stream_id); + + bool HasRequiredStreamId(const Http2FrameHeader& header); + + bool HasRequiredStreamIdZero(uint32_t stream_id); + + bool HasRequiredStreamIdZero(const Http2FrameHeader& header); + + void ReportReceiveCompressedFrame(const Http2FrameHeader& header); + + void CommonStartHpackBlock(); + + // SpdyFramer calls HandleControlFrameHeadersData even if there are zero + // fragment bytes in the first frame, so do the same. + void MaybeAnnounceEmptyFirstHpackFragment(); + void CommonHpackFragmentEnd(); + + // The most recently decoded frame header; invalid after we reached the end + // of that frame. + Http2FrameHeader frame_header_; + + // If decoding an HPACK block that is split across multiple frames, this holds + // the frame header of the HEADERS or PUSH_PROMISE that started the block. + Http2FrameHeader hpack_first_frame_header_; + + // Amount of trailing padding. Currently used just as an indicator of whether + // OnPadLength has been called. + base::Optional<size_t> opt_pad_length_; + + // Temporary buffers for the AltSvc fields. + Http2String alt_svc_origin_; + Http2String alt_svc_value_; + + // Listener used if we transition to an error state; the listener ignores all + // the callbacks. + Http2FrameDecoderNoOpListener no_op_listener_; + SpdyFramerVisitorInterface* visitor_ = nullptr; SpdyFramerDebugVisitorInterface* debug_visitor_ = nullptr; + + // If non-null, unknown frames and settings are passed to the extension. + ExtensionVisitorInterface* extension_ = nullptr; + + // The HPACK decoder to be used for this adapter. User is responsible for + // clearing if the adapter is to be used for another connection. + std::unique_ptr<HpackDecoderAdapter> hpack_decoder_ = nullptr; + + // The HTTP/2 frame decoder. Accessed via a unique_ptr to allow replacement + // (e.g. in tests) when Reset() is called. + std::unique_ptr<Http2FrameDecoder> frame_decoder_; + + // Next frame type expected. Currently only used for CONTINUATION frames, + // but could be used for detecting whether the first frame is a SETTINGS + // frame. + // TODO(jamessyng): Provide means to indicate that decoder should require + // SETTINGS frame as the first frame. + Http2FrameType expected_frame_type_; + + // Attempt to duplicate the SpdyState and SpdyFramerError values that + // SpdyFramer sets. Values determined by getting tests to pass. + SpdyFramer::SpdyState spdy_state_; + SpdyFramer::SpdyFramerError spdy_framer_error_; + + // The limit on the size of received HTTP/2 payloads as specified in the + // SETTINGS_MAX_FRAME_SIZE advertised to peer. + size_t recv_frame_size_limit_ = kSpdyInitialFrameSizeLimit; + + // Has OnFrameHeader been called? + bool decoded_frame_header_ = false; + + // Have we recorded an Http2FrameHeader for the current frame? + // We only do so if the decoder will make multiple callbacks for + // the frame; for example, for PING frames we don't make record + // the frame header, but for ALTSVC we do. + bool has_frame_header_ = false; + + // Have we recorded an Http2FrameHeader for the current HPACK block? + // True only for multi-frame HPACK blocks. + bool has_hpack_first_frame_header_ = false; + + // Has OnHeaders() already been called for current HEADERS block? Only + // meaningful between OnHeadersStart and OnHeadersPriority. + bool on_headers_called_; + + // Has OnHpackFragment() already been called for current HPACK block? + // SpdyFramer will pass an empty buffer to the HPACK decoder if a HEADERS + // or PUSH_PROMISE has no HPACK data in it (e.g. a HEADERS frame with only + // padding). Detect that condition and replicate the behavior using this + // field. + bool on_hpack_fragment_called_; + + // Have we seen a frame header that appears to be an HTTP/1 response? + bool latched_probable_http_response_ = false; + + // Is expected_frame_type_ set? + bool has_expected_frame_type_ = false; + + // Is the current frame payload destined for |extension_|? + bool handling_extension_payload_ = false; + bool process_single_input_frame_ = false; }; -std::unique_ptr<SpdyFramerDecoderAdapter> CreateHttp2FrameDecoderAdapter(); +std::unique_ptr<Http2DecoderAdapter> CreateHttp2FrameDecoderAdapter(); } // namespace net
diff --git a/net/spdy/core/spdy_framer.h b/net/spdy/core/spdy_framer.h index cfa1a42..69439482 100644 --- a/net/spdy/core/spdy_framer.h +++ b/net/spdy/core/spdy_framer.h
@@ -26,20 +26,19 @@ namespace net { -class HttpProxyClientSocketPoolTest; +class Http2DecoderAdapter; class HttpNetworkLayer; class HttpNetworkTransactionTest; +class HttpProxyClientSocketPoolTest; +class SpdyFrameBuilder; +class SpdyFramer; +class SpdyFramerVisitorInterface; class SpdyHttpStreamTest; class SpdyNetworkTransactionTest; class SpdyProxyClientSocketTest; class SpdySessionTest; class SpdyStreamTest; -class SpdyFramer; -class SpdyFrameBuilder; -class SpdyFramerDecoderAdapter; -class SpdyFramerVisitorInterface; - namespace test { class TestSpdyVisitor; @@ -638,7 +637,7 @@ SpdyHeadersHandlerInterface* header_handler_; // Decoder to use instead of this instance. - std::unique_ptr<SpdyFramerDecoderAdapter> decoder_adapter_; + std::unique_ptr<Http2DecoderAdapter> decoder_adapter_; // Determines whether HPACK compression is used. const CompressionOption compression_option_;
diff --git a/pdf/pdfium/fuzzers/BUILD.gn b/pdf/pdfium/fuzzers/BUILD.gn index 118e9cc..41ef2d0 100644 --- a/pdf/pdfium/fuzzers/BUILD.gn +++ b/pdf/pdfium/fuzzers/BUILD.gn
@@ -216,6 +216,6 @@ "//v8:external_startup_data", ] dict = "dicts/pdf.dict" - seed_corpus = "src/third_party/pdfium/test" + seed_corpus = "//third_party/pdfium/test" } }
diff --git a/pdf/pdfium/fuzzers/corpora/pdf_codec_bmp/not_kitty.bmp b/pdf/pdfium/fuzzers/corpora/pdf_codec_bmp/not_kitty.bmp new file mode 100644 index 0000000..0309c928 --- /dev/null +++ b/pdf/pdfium/fuzzers/corpora/pdf_codec_bmp/not_kitty.bmp Binary files differ
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index 53f12786..2c33892 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -1707,16 +1707,6 @@ FORM_DoDocumentAAction(form_, FPDFDOC_AACTION_DP); } -PDFiumPage::Area PDFiumEngine::GetCharIndex(const pp::MouseInputEvent& event, - int* page_index, - int* char_index, - int* form_type, - PDFiumPage::LinkTarget* target) { - // First figure out which page this is in. - pp::Point mouse_point = event.GetPosition(); - return GetCharIndex(mouse_point, page_index, char_index, form_type, target); -} - PDFiumPage::Area PDFiumEngine::GetCharIndex(const pp::Point& point, int* page_index, int* char_index, @@ -1779,8 +1769,9 @@ int char_index = -1; int form_type = FPDF_FORMFIELD_UNKNOWN; PDFiumPage::LinkTarget target; + pp::Point point = event.GetPosition(); PDFiumPage::Area area = - GetCharIndex(event, &page_index, &char_index, &form_type, &target); + GetCharIndex(point, &page_index, &char_index, &form_type, &target); mouse_down_state_.Set(area, target); // Decide whether to open link or not based on user action in mouse up and @@ -1794,8 +1785,8 @@ if (page_index != -1) { last_page_mouse_down_ = page_index; - double page_x, page_y; - pp::Point point = event.GetPosition(); + double page_x; + double page_y; DeviceToPage(page_index, point.x(), point.y(), &page_x, &page_y); FORM_OnLButtonDown(form_, pages_[page_index]->GetPage(), 0, page_x, page_y); @@ -1895,8 +1886,9 @@ int char_index = -1; int form_type = FPDF_FORMFIELD_UNKNOWN; PDFiumPage::LinkTarget target; + pp::Point point = event.GetPosition(); PDFiumPage::Area area = - GetCharIndex(event, &page_index, &char_index, &form_type, &target); + GetCharIndex(point, &page_index, &char_index, &form_type, &target); // Open link on mouse up for same link for which mouse down happened earlier. if (mouse_down_state_.Matches(area, target)) { @@ -1928,8 +1920,8 @@ return false; if (page_index != -1) { - double page_x, page_y; - pp::Point point = event.GetPosition(); + double page_x; + double page_y; DeviceToPage(page_index, point.x(), point.y(), &page_x, &page_y); FORM_OnLButtonUp(form_, pages_[page_index]->GetPage(), 0, page_x, page_y); } @@ -1946,8 +1938,9 @@ int char_index = -1; int form_type = FPDF_FORMFIELD_UNKNOWN; PDFiumPage::LinkTarget target; + pp::Point point = event.GetPosition(); PDFiumPage::Area area = - GetCharIndex(event, &page_index, &char_index, &form_type, &target); + GetCharIndex(point, &page_index, &char_index, &form_type, &target); // Clear |mouse_down_state_| if mouse moves away from where the mouse down // happened. @@ -1986,8 +1979,8 @@ } if (page_index != -1) { - double page_x, page_y; - pp::Point point = event.GetPosition(); + double page_x; + double page_y; DeviceToPage(page_index, point.x(), point.y(), &page_x, &page_y); FORM_OnMouseMove(form_, pages_[page_index]->GetPage(), 0, page_x, page_y); }
diff --git a/pdf/pdfium/pdfium_engine.h b/pdf/pdfium/pdfium_engine.h index 37d30d8f..7dd2cee 100644 --- a/pdf/pdfium/pdfium_engine.h +++ b/pdf/pdfium/pdfium_engine.h
@@ -339,13 +339,8 @@ // the plugin's text selection. void SetFormSelectedText(FPDF_FORMHANDLE form_handle, FPDF_PAGE page); - // Given a mouse event, returns which page and character location it's closest - // to. - PDFiumPage::Area GetCharIndex(const pp::MouseInputEvent& event, - int* page_index, - int* char_index, - int* form_type, - PDFiumPage::LinkTarget* target); + // Given |point|, returns which page and character location it's closest to, + // as well as extra information about objects at that point. PDFiumPage::Area GetCharIndex(const pp::Point& point, int* page_index, int* char_index,
diff --git a/ppapi/features/features.gni b/ppapi/features/features.gni index 560d1ec..ac17e1f 100644 --- a/ppapi/features/features.gni +++ b/ppapi/features/features.gni
@@ -7,5 +7,5 @@ import("//build/config/features.gni") declare_args() { - enable_plugins = !is_android && !is_ios && !is_chromecast && !is_fuchsia + enable_plugins = !is_android && !is_ios && !is_chromecast }
diff --git a/printing/features/features.gni b/printing/features/features.gni index b3d6967..a41202a2 100644 --- a/printing/features/features.gni +++ b/printing/features/features.gni
@@ -7,11 +7,11 @@ declare_args() { # Enable basic printing support and UI. - enable_basic_printing = !is_chromecast && !is_ios && !is_fuchsia + enable_basic_printing = !is_chromecast && !is_ios # Enable printing with print preview. It does not imply # enable_basic_printing. It's possible to build Chrome with preview only. - enable_print_preview = !is_android && !is_chromecast && !is_ios && !is_fuchsia + enable_print_preview = !is_android && !is_chromecast && !is_ios - use_cups = (is_desktop_linux || is_mac) && !is_chromecast && !is_fuchsia + use_cups = (is_desktop_linux || is_mac) && !is_chromecast }
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn index 59ee750..1bcad96 100644 --- a/remoting/host/BUILD.gn +++ b/remoting/host/BUILD.gn
@@ -137,6 +137,8 @@ "dns_blackhole_checker.h", "evaluate_capability.cc", "evaluate_capability.h", + "file_transfer_message_handler.cc", + "file_transfer_message_handler.h", "file_transfer_message_handler_factory.cc", "file_transfer_message_handler_factory.h", "forward_process_stats_agent.cc",
diff --git a/remoting/host/file_transfer_message_handler.cc b/remoting/host/file_transfer_message_handler.cc new file mode 100644 index 0000000..1f7fad01 --- /dev/null +++ b/remoting/host/file_transfer_message_handler.cc
@@ -0,0 +1,31 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/host/file_transfer_message_handler.h" + +#include "remoting/base/compound_buffer.h" + +namespace remoting { + +FileTransferMessageHandler::FileTransferMessageHandler( + const std::string& name, + std::unique_ptr<protocol::MessagePipe> pipe) + : protocol::NamedMessagePipeHandler(name, std::move(pipe)) {} + +FileTransferMessageHandler::~FileTransferMessageHandler() = default; + +void FileTransferMessageHandler::OnConnected() { + // TODO(jarhar): Implement open logic. +} + +void FileTransferMessageHandler::OnIncomingMessage( + std::unique_ptr<CompoundBuffer> message) { + // TODO(jarhar): Implement message received logic. +} + +void FileTransferMessageHandler::OnDisconnecting() { + // TODO(jarhar): Implement close logic. +} + +} // namespace remoting
diff --git a/remoting/host/file_transfer_message_handler.h b/remoting/host/file_transfer_message_handler.h new file mode 100644 index 0000000..dca3315 --- /dev/null +++ b/remoting/host/file_transfer_message_handler.h
@@ -0,0 +1,26 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_HOST_FILE_TRANSFER_MESSAGE_HANDLER_H_ +#define REMOTING_HOST_FILE_TRANSFER_MESSAGE_HANDLER_H_ + +#include "remoting/protocol/named_message_pipe_handler.h" + +namespace remoting { + +class FileTransferMessageHandler : public protocol::NamedMessagePipeHandler { + public: + FileTransferMessageHandler(const std::string& name, + std::unique_ptr<protocol::MessagePipe> pipe); + ~FileTransferMessageHandler() override; + + // protocol::NamedMessagePipeHandler implementation. + void OnConnected() override; + void OnIncomingMessage(std::unique_ptr<CompoundBuffer> message) override; + void OnDisconnecting() override; +}; + +} // namespace remoting + +#endif // REMOTING_HOST_FILE_TRANSFER_MESSAGE_HANDLER_H_
diff --git a/remoting/host/file_transfer_message_handler_factory.cc b/remoting/host/file_transfer_message_handler_factory.cc index c14ccabe..e9ec036 100644 --- a/remoting/host/file_transfer_message_handler_factory.cc +++ b/remoting/host/file_transfer_message_handler_factory.cc
@@ -4,6 +4,8 @@ #include "remoting/host/file_transfer_message_handler_factory.h" +#include "remoting/host/file_transfer_message_handler.h" + namespace remoting { FileTransferMessageHandlerFactory::FileTransferMessageHandlerFactory() = @@ -14,7 +16,10 @@ void FileTransferMessageHandlerFactory::CreateDataChannelHandler( const std::string& channel_name, std::unique_ptr<protocol::MessagePipe> pipe) { - // TODO(jarhar): Implement FileTransferMessageHandler and pass pipe to it. + // FileTransferMessageHandler manages its own lifetime and is tied to the + // lifetime of |pipe|. Once |pipe| is closed, this instance will be cleaned + // up. + new FileTransferMessageHandler(channel_name, std::move(pipe)); } } // namespace remoting
diff --git a/remoting/host/win/unprivileged_process_delegate.cc b/remoting/host/win/unprivileged_process_delegate.cc index dfff10c..c70589f 100644 --- a/remoting/host/win/unprivileged_process_delegate.cc +++ b/remoting/host/win/unprivileged_process_delegate.cc
@@ -155,8 +155,7 @@ // Generate a unique window station name. std::string window_station_name = base::StringPrintf( - "chromoting-%d-%d", - base::GetCurrentProcId(), + "chromoting-%" CrPRIdPid "-%d", base::GetCurrentProcId(), base::RandInt(1, std::numeric_limits<int>::max())); // Make sure that a new window station will be created instead of opening
diff --git a/services/ui/service.cc b/services/ui/service.cc index e1efc27..e8f02c9 100644 --- a/services/ui/service.cc +++ b/services/ui/service.cc
@@ -272,7 +272,7 @@ // so keep this line below both of those. input_device_server_.RegisterAsObserver(); - window_server_.reset(new ws::WindowServer(this)); + window_server_ = base::MakeUnique<ws::WindowServer>(this); std::unique_ptr<ws::GpuHost> gpu_host = base::MakeUnique<ws::DefaultGpuHost>(window_server_.get()); std::unique_ptr<ws::FrameSinkManagerClientBinding> frame_sink_manager =
diff --git a/services/ui/ws/event_dispatcher.cc b/services/ui/ws/event_dispatcher.cc index 1d99e171..d137da0e 100644 --- a/services/ui/ws/event_dispatcher.cc +++ b/services/ui/ws/event_dispatcher.cc
@@ -339,8 +339,9 @@ LocationTarget updated_target = location_target; updated_target.deepest_window.in_non_client_area = true; updated_target.deepest_window.window = - (fallback_to_root_ && location_target.deepest_window.window) - ? location_target.deepest_window.window->GetRoot() + location_target.deepest_window.window + ? delegate_->GetFallbackTargetForEventBlockedByModal( + location_target.deepest_window.window->GetRoot()) : nullptr; return updated_target; }
diff --git a/services/ui/ws/event_dispatcher.h b/services/ui/ws/event_dispatcher.h index f5256e5..d8936e3 100644 --- a/services/ui/ws/event_dispatcher.h +++ b/services/ui/ws/event_dispatcher.h
@@ -59,8 +59,6 @@ explicit EventDispatcher(EventDispatcherDelegate* delegate); ~EventDispatcher() override; - void set_fallback_to_root(bool value) { fallback_to_root_ = value; } - ModalWindowController* modal_window_controller() { return &modal_window_controller_; } @@ -353,13 +351,6 @@ AcceleratorMatchPhase::ANY; #endif - // Used to determine behavior when the target of an event is blocked by a - // modal window. - // . If true, the target becomes the root window. - // . If false, no target is used, which means the window-manager does not - // see the event. - bool fallback_to_root_ = false; - DISALLOW_COPY_AND_ASSIGN(EventDispatcher); };
diff --git a/services/ui/ws/event_dispatcher_delegate.h b/services/ui/ws/event_dispatcher_delegate.h index fbf1b72..2a8f3060 100644 --- a/services/ui/ws/event_dispatcher_delegate.h +++ b/services/ui/ws/event_dispatcher_delegate.h
@@ -97,6 +97,13 @@ virtual void OnEventTargetNotFound(const ui::Event& event, int64_t display_id) = 0; + // If an event is blocked by a modal window this function is used to determine + // which window the event should be dispatched to. Return null to indicate no + // window. |window| is the window the event would be targetted at if there was + // no modal window open. + virtual ServerWindow* GetFallbackTargetForEventBlockedByModal( + ServerWindow* window) = 0; + // Called when an event occurs that targets a window that should be blocked // by a modal window. |modal_window| is the modal window that blocked the // event.
diff --git a/services/ui/ws/event_dispatcher_unittest.cc b/services/ui/ws/event_dispatcher_unittest.cc index 7fea2747..a86e3d49 100644 --- a/services/ui/ws/event_dispatcher_unittest.cc +++ b/services/ui/ws/event_dispatcher_unittest.cc
@@ -66,6 +66,8 @@ last_accelerator_(0) {} ~TestEventDispatcherDelegate() override {} + void EnableFallbackToRoot() { fallback_to_root_ = true; } + ui::Event* last_event_target_not_found() { return last_event_target_not_found_.get(); } @@ -175,6 +177,10 @@ int64_t display_id) override { last_event_target_not_found_ = ui::Event::Clone(event); } + ServerWindow* GetFallbackTargetForEventBlockedByModal( + ServerWindow* window) override { + return fallback_to_root_ ? root_ : nullptr; + } void OnEventOccurredOutsideOfModalWindow( ServerWindow* modal_transient) override { window_that_blocked_event_ = modal_transient; @@ -191,6 +197,9 @@ base::Optional<bool> last_cursor_visibility_; ServerWindow* window_that_blocked_event_ = nullptr; + // If true events blocked by a modal window are sent to |root_|. + bool fallback_to_root_ = false; + DISALLOW_COPY_AND_ASSIGN(TestEventDispatcherDelegate); }; @@ -1641,7 +1650,7 @@ // enabled. TEST_P(EventDispatcherTest, ModalWindowEventOnDescendantOfModalParentWithFallback) { - event_dispatcher()->set_fallback_to_root(true); + test_event_dispatcher_delegate()->EnableFallbackToRoot(); std::unique_ptr<ServerWindow> w1 = CreateChildWindow(WindowId(1, 3)); std::unique_ptr<ServerWindow> w11 = @@ -1727,9 +1736,9 @@ } // Variant of ModalWindowEventOutsideSystemModal with -// set_fallback_to_root(true). +// EnableFallbackToRoot(). TEST_P(EventDispatcherTest, ModalWindowEventOutsideSystemModalWithFallback) { - event_dispatcher()->set_fallback_to_root(true); + test_event_dispatcher_delegate()->EnableFallbackToRoot(); std::unique_ptr<ServerWindow> w1 = CreateChildWindow(WindowId(1, 3));
diff --git a/services/ui/ws/frame_generator.cc b/services/ui/ws/frame_generator.cc index 4f379d8f..d3f48ee 100644 --- a/services/ui/ws/frame_generator.cc +++ b/services/ui/ws/frame_generator.cc
@@ -36,7 +36,8 @@ SetNeedsBeginFrame(true); } -void FrameGenerator::OnSurfaceCreated(const viz::SurfaceInfo& surface_info) { +void FrameGenerator::OnFirstSurfaceActivation( + const viz::SurfaceInfo& surface_info) { DCHECK(surface_info.is_valid()); // Only handle embedded surfaces changing here. The display root surface
diff --git a/services/ui/ws/frame_generator.h b/services/ui/ws/frame_generator.h index 43c4685a..adbc2766 100644 --- a/services/ui/ws/frame_generator.h +++ b/services/ui/ws/frame_generator.h
@@ -34,7 +34,7 @@ void SetHighContrastMode(bool enabled); // Updates the WindowManager's SurfaceInfo. - void OnSurfaceCreated(const viz::SurfaceInfo& surface_info); + void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info); // Swaps the |window_manager_surface_info_| with that of |other|. void SwapSurfaceWith(FrameGenerator* other);
diff --git a/services/ui/ws/frame_generator_unittest.cc b/services/ui/ws/frame_generator_unittest.cc index 0411dc9..356d550 100644 --- a/services/ui/ws/frame_generator_unittest.cc +++ b/services/ui/ws/frame_generator_unittest.cc
@@ -135,7 +135,7 @@ // |frame_generator_|. After InitWithSurfaceInfo finishes, |frame_generator_| // has a valid SurfaceInfo and does not request BeginFrames. void InitWithSurfaceInfo() { - frame_generator_->OnSurfaceCreated(kArbitrarySurfaceInfo); + frame_generator_->OnFirstSurfaceActivation(kArbitrarySurfaceInfo); // Issue a BeginFrame so that frame_generator_ stops requesting BeginFrames // after submitting a CompositorFrame. @@ -187,7 +187,7 @@ EXPECT_EQ(viz::BeginFrameAck(), LastBeginFrameAck()); } -TEST_F(FrameGeneratorTest, OnSurfaceCreated) { +TEST_F(FrameGeneratorTest, OnFirstSurfaceActivation) { InitWithSurfaceInfo(); // Verify that the CompositorFrame refers to the window manager's surface via
diff --git a/services/ui/ws/server_window_compositor_frame_sink_manager.h b/services/ui/ws/server_window_compositor_frame_sink_manager.h index aadecca..7256b1b 100644 --- a/services/ui/ws/server_window_compositor_frame_sink_manager.h +++ b/services/ui/ws/server_window_compositor_frame_sink_manager.h
@@ -6,12 +6,12 @@ #define SERVICES_UI_WS_SERVER_WINDOW_COMPOSITOR_FRAME_SINK_MANAGER_H_ #include "base/macros.h" -#include "cc/ipc/compositor_frame.mojom.h" #include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/surfaces/surface_id.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/ui/public/interfaces/window_tree.mojom.h" #include "services/viz/compositing/privileged/interfaces/frame_sink_manager.mojom.h" +#include "services/viz/public/interfaces/compositing/compositor_frame.mojom.h" namespace ui { namespace ws {
diff --git a/services/ui/ws/window_manager_state.cc b/services/ui/ws/window_manager_state.cc index a0d3263..6b5c44e6a 100644 --- a/services/ui/ws/window_manager_state.cc +++ b/services/ui/ws/window_manager_state.cc
@@ -810,6 +810,13 @@ UpdateNativeCursorFromDispatcher(); } +ServerWindow* WindowManagerState::GetFallbackTargetForEventBlockedByModal( + ServerWindow* window) { + DCHECK(window); + // TODO(sky): reevaluate when http://crbug.com/646998 is fixed. + return GetWindowManagerRootForDisplayRoot(window); +} + void WindowManagerState::OnEventOccurredOutsideOfModalWindow( ServerWindow* modal_window) { window_tree_->OnEventOccurredOutsideOfModalWindow(modal_window);
diff --git a/services/ui/ws/window_manager_state.h b/services/ui/ws/window_manager_state.h index b05d06f1..31eddae 100644 --- a/services/ui/ws/window_manager_state.h +++ b/services/ui/ws/window_manager_state.h
@@ -285,6 +285,8 @@ ServerWindow* GetRootWindowContaining(gfx::Point* location_in_display, int64_t* display_id) override; void OnEventTargetNotFound(const Event& event, int64_t display_id) override; + ServerWindow* GetFallbackTargetForEventBlockedByModal( + ServerWindow* window) override; void OnEventOccurredOutsideOfModalWindow(ServerWindow* modal_window) override; // ServerWindowObserver:
diff --git a/services/ui/ws/window_server.cc b/services/ui/ws/window_server.cc index 7b7d26c1..137a2f1 100644 --- a/services/ui/ws/window_server.cc +++ b/services/ui/ws/window_server.cc
@@ -913,7 +913,8 @@ delegate_->StartDisplayInit(); } -void WindowServer::OnSurfaceCreated(const viz::SurfaceInfo& surface_info) { +void WindowServer::OnFirstSurfaceActivation( + const viz::SurfaceInfo& surface_info) { WindowId window_id( WindowIdFromTransportId(surface_info.id().frame_sink_id().client_id())); ServerWindow* window = GetWindow(window_id); @@ -935,7 +936,7 @@ // special case because ServerWindows created by the WindowServer are not // part of a WindowTree. Send the SurfaceId directly to FrameGenerator and // claim the temporary reference for the display root. - display->platform_display()->GetFrameGenerator()->OnSurfaceCreated( + display->platform_display()->GetFrameGenerator()->OnFirstSurfaceActivation( surface_info); display->root_window() ->GetOrCreateCompositorFrameSinkManager()
diff --git a/services/ui/ws/window_server.h b/services/ui/ws/window_server.h index ec6a69e7..20e2b46 100644 --- a/services/ui/ws/window_server.h +++ b/services/ui/ws/window_server.h
@@ -372,7 +372,7 @@ void OnGpuServiceInitialized() override; // viz::mojom::FrameSinkManagerClient: - void OnSurfaceCreated(const viz::SurfaceInfo& surface_info) override; + void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override; void OnClientConnectionClosed(const viz::FrameSinkId& frame_sink_id) override; void OnAggregatedHitTestRegionListUpdated( const viz::FrameSinkId& frame_sink_id,
diff --git a/services/viz/compositing/privileged/interfaces/frame_sink_manager.mojom b/services/viz/compositing/privileged/interfaces/frame_sink_manager.mojom index 72ccbc21..a499709 100644 --- a/services/viz/compositing/privileged/interfaces/frame_sink_manager.mojom +++ b/services/viz/compositing/privileged/interfaces/frame_sink_manager.mojom
@@ -95,9 +95,9 @@ // compositor. The frame sink manager host is either the browser process in // Chrome or the window server process. interface FrameSinkManagerClient { - // Called by the frame sink manager immediately upon receiving a - // CompositorFrame with a new SurfaceId for the first time. - OnSurfaceCreated(cc.mojom.SurfaceInfo surface_info); + // Called by the frame sink manager when a CompositorFrame with a new + // SurfaceId activates for the first time. + OnFirstSurfaceActivation(cc.mojom.SurfaceInfo surface_info); // The CompositorFrameSink pipe for |frame_sink_id| was closed. The client // cannot submit any CompositorFrames to viz after this occurs.
diff --git a/services/viz/public/cpp/compositing/BUILD.gn b/services/viz/public/cpp/compositing/BUILD.gn index 07d4324..8ac67f5 100644 --- a/services/viz/public/cpp/compositing/BUILD.gn +++ b/services/viz/public/cpp/compositing/BUILD.gn
@@ -12,6 +12,7 @@ deps = [ "//base/test:test_support", "//components/viz/common:common", + "//components/viz/test:test_support", "//media/capture/mojo:capture_types", "//services/service_manager/public/cpp", "//services/service_manager/public/cpp:service_test_support",
diff --git a/services/viz/public/cpp/compositing/DEPS b/services/viz/public/cpp/compositing/DEPS index 4debd219..d1586ba 100644 --- a/services/viz/public/cpp/compositing/DEPS +++ b/services/viz/public/cpp/compositing/DEPS
@@ -1,3 +1,9 @@ include_rules = [ + "+ui/gfx/ipc", "+ui/gfx/mojo", + "+ui/gfx/geometry/mojo", + "+cc", + "+gpu/ipc", + "+skia/public/interfaces", + "+ui/latency/mojo", ]
diff --git a/services/viz/public/cpp/compositing/compositor_frame.typemap b/services/viz/public/cpp/compositing/compositor_frame.typemap new file mode 100644 index 0000000..353a7af --- /dev/null +++ b/services/viz/public/cpp/compositing/compositor_frame.typemap
@@ -0,0 +1,15 @@ +# 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/compositor_frame.mojom" +public_headers = [ "//cc/output/compositor_frame.h" ] +traits_headers = + [ "//services/viz/public/cpp/compositing/compositor_frame_struct_traits.h" ] +sources = [ + "//services/viz/public/cpp/compositing/compositor_frame_struct_traits.cc", +] +deps = [ + "//cc", +] +type_mappings = [ "viz.mojom.CompositorFrame=cc::CompositorFrame[move_only]" ]
diff --git a/cc/ipc/compositor_frame_for_blink.typemap b/services/viz/public/cpp/compositing/compositor_frame_for_blink.typemap similarity index 81% rename from cc/ipc/compositor_frame_for_blink.typemap rename to services/viz/public/cpp/compositing/compositor_frame_for_blink.typemap index 9fbd8a9..256c13f 100644 --- a/cc/ipc/compositor_frame_for_blink.typemap +++ b/services/viz/public/cpp/compositing/compositor_frame_for_blink.typemap
@@ -2,11 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -mojom = "//cc/ipc/compositor_frame.mojom" +mojom = "//services/viz/public/interfaces/compositing/compositor_frame.mojom" public_headers = [ "//cc/output/compositor_frame.h" ] traits_headers = [ "//cc/ipc/compositor_frame_metadata_struct_traits.h", - "//cc/ipc/compositor_frame_struct_traits.h", "//cc/ipc/filter_operation_struct_traits.h", "//cc/ipc/filter_operations_struct_traits.h", "//cc/ipc/render_pass_struct_traits.h", @@ -19,6 +18,7 @@ "//gpu/ipc/common/sync_token_struct_traits.h", "//ipc/ipc_message_utils.h", "//mojo/common/common_custom_types_struct_traits.h", + "//services/viz/public/cpp/compositing/compositor_frame_struct_traits.h", "//skia/public/interfaces/image_filter_struct_traits.h", "//ui/gfx/mojo/selection_bound_struct_traits.h", "//ui/gfx/mojo/transform_struct_traits.h", @@ -29,9 +29,10 @@ "//cc/ipc:interfaces", "//gpu/ipc/common:interfaces", "//mojo/common:common_custom_types", + "//services/viz/public/interfaces/compositing", "//skia/public/interfaces", "//ui/gfx/geometry/mojo", "//ui/gfx/mojo", "//ui/latency/mojo:interfaces", ] -type_mappings = [ "cc.mojom.CompositorFrame=cc::CompositorFrame[move_only]" ] +type_mappings = [ "viz.mojom.CompositorFrame=cc::CompositorFrame[move_only]" ]
diff --git a/cc/ipc/compositor_frame_struct_traits.cc b/services/viz/public/cpp/compositing/compositor_frame_struct_traits.cc similarity index 64% rename from cc/ipc/compositor_frame_struct_traits.cc rename to services/viz/public/cpp/compositing/compositor_frame_struct_traits.cc index f06f370..c9bfd12 100644 --- a/cc/ipc/compositor_frame_struct_traits.cc +++ b/services/viz/public/cpp/compositing/compositor_frame_struct_traits.cc
@@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/ipc/compositor_frame_struct_traits.h" +#include "services/viz/public/cpp/compositing/compositor_frame_struct_traits.h" + #include "cc/ipc/compositor_frame_metadata_struct_traits.h" #include "cc/ipc/render_pass_struct_traits.h" #include "cc/ipc/transferable_resource_struct_traits.h" @@ -10,10 +11,8 @@ namespace mojo { // static -bool StructTraits<cc::mojom::CompositorFrameDataView, - cc::CompositorFrame>::Read(cc::mojom::CompositorFrameDataView - data, - cc::CompositorFrame* out) { +bool StructTraits<viz::mojom::CompositorFrameDataView, cc::CompositorFrame>:: + Read(viz::mojom::CompositorFrameDataView data, cc::CompositorFrame* out) { return data.ReadPasses(&out->render_pass_list) && !out->render_pass_list.empty() && data.ReadMetadata(&out->metadata) && data.ReadResources(&out->resource_list);
diff --git a/services/viz/public/cpp/compositing/compositor_frame_struct_traits.h b/services/viz/public/cpp/compositing/compositor_frame_struct_traits.h new file mode 100644 index 0000000..c85ce80 --- /dev/null +++ b/services/viz/public/cpp/compositing/compositor_frame_struct_traits.h
@@ -0,0 +1,37 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_VIZ_PUBLIC_CPP_COMPOSITING_COMPOSITOR_FRAME_STRUCT_TRAITS_H_ +#define SERVICES_VIZ_PUBLIC_CPP_COMPOSITING_COMPOSITOR_FRAME_STRUCT_TRAITS_H_ + +#include <vector> + +#include "cc/output/compositor_frame.h" +#include "services/viz/public/interfaces/compositing/compositor_frame.mojom-shared.h" + +namespace mojo { + +template <> +struct StructTraits<viz::mojom::CompositorFrameDataView, cc::CompositorFrame> { + static const cc::CompositorFrameMetadata& metadata( + const cc::CompositorFrame& input) { + return input.metadata; + } + + static const std::vector<viz::TransferableResource>& resources( + const cc::CompositorFrame& input) { + return input.resource_list; + } + + static const cc::RenderPassList& passes(const cc::CompositorFrame& input) { + return input.render_pass_list; + } + + static bool Read(viz::mojom::CompositorFrameDataView data, + cc::CompositorFrame* out); +}; + +} // namespace mojo + +#endif // SERVICES_VIZ_PUBLIC_CPP_COMPOSITING_COMPOSITOR_FRAME_STRUCT_TRAITS_H_
diff --git a/services/viz/public/cpp/compositing/struct_traits_unittest.cc b/services/viz/public/cpp/compositing/struct_traits_unittest.cc index 8b9eb28..a989f48 100644 --- a/services/viz/public/cpp/compositing/struct_traits_unittest.cc +++ b/services/viz/public/cpp/compositing/struct_traits_unittest.cc
@@ -5,10 +5,51 @@ #include <utility> #include "base/message_loop/message_loop.h" +#include "cc/ipc/begin_frame_args_struct_traits.h" +#include "cc/ipc/compositor_frame_metadata_struct_traits.h" +#include "cc/ipc/copy_output_request_struct_traits.h" +#include "cc/ipc/copy_output_result_struct_traits.h" +#include "cc/ipc/filter_operation_struct_traits.h" +#include "cc/ipc/filter_operations_struct_traits.h" +#include "cc/ipc/frame_sink_id_struct_traits.h" +#include "cc/ipc/local_surface_id_struct_traits.h" +#include "cc/ipc/quads_struct_traits.h" +#include "cc/ipc/render_pass_struct_traits.h" +#include "cc/ipc/returned_resource_struct_traits.h" +#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" +#include "cc/quads/debug_border_draw_quad.h" +#include "cc/quads/render_pass.h" +#include "cc/quads/solid_color_draw_quad.h" +#include "components/viz/common/frame_sinks/begin_frame_args.h" +#include "components/viz/common/quads/resource_format.h" #include "components/viz/common/resources/resource_settings.h" +#include "components/viz/common/resources/transferable_resource.h" +#include "components/viz/test/begin_frame_args_test.h" +#include "gpu/ipc/common/mailbox_holder_struct_traits.h" +#include "gpu/ipc/common/mailbox_struct_traits.h" +#include "gpu/ipc/common/sync_token_struct_traits.h" +#include "ipc/ipc_message_utils.h" +#include "mojo/common/common_custom_types_struct_traits.h" #include "mojo/public/cpp/bindings/binding_set.h" +#include "services/viz/public/cpp/compositing/compositor_frame_struct_traits.h" #include "services/viz/public/cpp/compositing/resource_settings_struct_traits.h" +#include "services/viz/public/interfaces/compositing/compositor_frame.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" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/geometry/mojo/geometry_struct_traits.h" +#include "ui/gfx/ipc/color/gfx_param_traits.h" +#include "ui/gfx/mojo/buffer_types_struct_traits.h" +#include "ui/gfx/mojo/selection_bound_struct_traits.h" +#include "ui/gfx/mojo/transform_struct_traits.h" +#include "ui/latency/mojo/latency_info_struct_traits.h" namespace viz { @@ -36,6 +77,129 @@ output.buffer_to_texture_target_map); } +// 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. +TEST_F(StructTraitsTest, CompositorFrame) { + std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create(); + render_pass->SetNew(1, gfx::Rect(5, 6), gfx::Rect(2, 3), gfx::Transform()); + + // SharedQuadState. + const gfx::Transform sqs_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, 13.f, 14.f, + 15.f, 16.f); + const gfx::Rect sqs_layer_rect(1234, 5678); + const gfx::Rect sqs_visible_layer_rect(12, 34, 56, 78); + const gfx::Rect sqs_clip_rect(123, 456, 789, 101112); + const bool sqs_is_clipped = true; + const float sqs_opacity = 0.9f; + const SkBlendMode sqs_blend_mode = SkBlendMode::kSrcOver; + const int sqs_sorting_context_id = 1337; + cc::SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState(); + sqs->SetAll(sqs_quad_to_target_transform, sqs_layer_rect, + sqs_visible_layer_rect, sqs_clip_rect, sqs_is_clipped, + sqs_opacity, sqs_blend_mode, sqs_sorting_context_id); + + // DebugBorderDrawQuad. + const gfx::Rect rect1(1234, 4321, 1357, 7531); + const SkColor color1 = SK_ColorRED; + const int32_t width1 = 1337; + cc::DebugBorderDrawQuad* debug_quad = + render_pass->CreateAndAppendDrawQuad<cc::DebugBorderDrawQuad>(); + debug_quad->SetNew(sqs, rect1, rect1, color1, width1); + + // SolidColorDrawQuad. + const gfx::Rect rect2(2468, 8642, 4321, 1234); + const uint32_t color2 = 0xffffffff; + const bool force_anti_aliasing_off = true; + cc::SolidColorDrawQuad* solid_quad = + render_pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>(); + solid_quad->SetNew(sqs, rect2, rect2, color2, force_anti_aliasing_off); + + // TransferableResource constants. + const uint32_t tr_id = 1337; + const ResourceFormat tr_format = ALPHA_8; + const gfx::BufferFormat tr_buffer_format = gfx::BufferFormat::R_8; + const uint32_t tr_filter = 1234; + const gfx::Size tr_size(1234, 5678); + TransferableResource resource; + resource.id = tr_id; + resource.format = tr_format; + resource.buffer_format = tr_buffer_format; + resource.filter = tr_filter; + resource.size = tr_size; + + // CompositorFrameMetadata constants. + const float device_scale_factor = 2.6f; + const gfx::Vector2dF root_scroll_offset(1234.5f, 6789.1f); + const float page_scale_factor = 1337.5f; + const gfx::SizeF scrollable_viewport_size(1337.7f, 1234.5f); + const uint32_t content_source_id = 3; + const BeginFrameAck begin_frame_ack(5, 10, false); + + cc::CompositorFrame input; + input.metadata.device_scale_factor = device_scale_factor; + input.metadata.root_scroll_offset = root_scroll_offset; + input.metadata.page_scale_factor = page_scale_factor; + input.metadata.scrollable_viewport_size = scrollable_viewport_size; + input.render_pass_list.push_back(std::move(render_pass)); + input.resource_list.push_back(resource); + input.metadata.content_source_id = content_source_id; + input.metadata.begin_frame_ack = begin_frame_ack; + + cc::CompositorFrame output; + mojom::CompositorFrame::Deserialize(mojom::CompositorFrame::Serialize(&input), + &output); + + EXPECT_EQ(device_scale_factor, output.metadata.device_scale_factor); + EXPECT_EQ(root_scroll_offset, output.metadata.root_scroll_offset); + EXPECT_EQ(page_scale_factor, output.metadata.page_scale_factor); + EXPECT_EQ(scrollable_viewport_size, output.metadata.scrollable_viewport_size); + EXPECT_EQ(content_source_id, output.metadata.content_source_id); + EXPECT_EQ(begin_frame_ack, output.metadata.begin_frame_ack); + + ASSERT_EQ(1u, output.resource_list.size()); + TransferableResource out_resource = output.resource_list[0]; + EXPECT_EQ(tr_id, out_resource.id); + EXPECT_EQ(tr_format, out_resource.format); + EXPECT_EQ(tr_buffer_format, out_resource.buffer_format); + EXPECT_EQ(tr_filter, out_resource.filter); + EXPECT_EQ(tr_size, out_resource.size); + + EXPECT_EQ(1u, output.render_pass_list.size()); + const cc::RenderPass* out_render_pass = output.render_pass_list[0].get(); + ASSERT_EQ(2u, out_render_pass->quad_list.size()); + ASSERT_EQ(1u, out_render_pass->shared_quad_state_list.size()); + + const cc::SharedQuadState* out_sqs = + out_render_pass->shared_quad_state_list.ElementAt(0); + EXPECT_EQ(sqs_quad_to_target_transform, out_sqs->quad_to_target_transform); + EXPECT_EQ(sqs_layer_rect, out_sqs->quad_layer_rect); + EXPECT_EQ(sqs_visible_layer_rect, out_sqs->visible_quad_layer_rect); + EXPECT_EQ(sqs_clip_rect, out_sqs->clip_rect); + EXPECT_EQ(sqs_is_clipped, out_sqs->is_clipped); + EXPECT_EQ(sqs_opacity, out_sqs->opacity); + EXPECT_EQ(sqs_blend_mode, out_sqs->blend_mode); + EXPECT_EQ(sqs_sorting_context_id, out_sqs->sorting_context_id); + + const cc::DebugBorderDrawQuad* out_debug_border_draw_quad = + cc::DebugBorderDrawQuad::MaterialCast( + out_render_pass->quad_list.ElementAt(0)); + EXPECT_EQ(rect1, out_debug_border_draw_quad->rect); + EXPECT_EQ(rect1, out_debug_border_draw_quad->visible_rect); + EXPECT_EQ(color1, out_debug_border_draw_quad->color); + EXPECT_EQ(width1, out_debug_border_draw_quad->width); + + const cc::SolidColorDrawQuad* out_solid_color_draw_quad = + cc::SolidColorDrawQuad::MaterialCast( + out_render_pass->quad_list.ElementAt(1)); + EXPECT_EQ(rect2, out_solid_color_draw_quad->rect); + EXPECT_EQ(rect2, out_solid_color_draw_quad->visible_rect); + EXPECT_EQ(color2, out_solid_color_draw_quad->color); + EXPECT_EQ(force_anti_aliasing_off, + out_solid_color_draw_quad->force_anti_aliasing_off); +} + } // namespace } // namespace viz
diff --git a/services/viz/public/cpp/compositing/typemaps.gni b/services/viz/public/cpp/compositing/typemaps.gni index 56c999e..7af5e5c 100644 --- a/services/viz/public/cpp/compositing/typemaps.gni +++ b/services/viz/public/cpp/compositing/typemaps.gni
@@ -2,4 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -typemaps = [ "//services/viz/public/cpp/compositing/resource_settings.typemap" ] +typemaps = [ + "//services/viz/public/cpp/compositing/compositor_frame.typemap", + "//services/viz/public/cpp/compositing/resource_settings.typemap", +]
diff --git a/services/viz/public/interfaces/compositing/BUILD.gn b/services/viz/public/interfaces/compositing/BUILD.gn index 781f7b7..c0bc16cb 100644 --- a/services/viz/public/interfaces/compositing/BUILD.gn +++ b/services/viz/public/interfaces/compositing/BUILD.gn
@@ -6,6 +6,7 @@ mojom("compositing") { sources = [ + "compositor_frame.mojom", "compositor_frame_sink.mojom", "resource_settings.mojom", ]
diff --git a/cc/ipc/compositor_frame.mojom b/services/viz/public/interfaces/compositing/compositor_frame.mojom similarity index 96% rename from cc/ipc/compositor_frame.mojom rename to services/viz/public/interfaces/compositing/compositor_frame.mojom index e32e1ef1a..ad7d6bb6 100644 --- a/cc/ipc/compositor_frame.mojom +++ b/services/viz/public/interfaces/compositing/compositor_frame.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/compositor_frame_metadata.mojom"; import "cc/ipc/render_pass.mojom";
diff --git a/services/viz/public/interfaces/compositing/compositor_frame_sink.mojom b/services/viz/public/interfaces/compositing/compositor_frame_sink.mojom index 6ba6cf3d..3f93e56 100644 --- a/services/viz/public/interfaces/compositing/compositor_frame_sink.mojom +++ b/services/viz/public/interfaces/compositing/compositor_frame_sink.mojom
@@ -5,7 +5,6 @@ module viz.mojom; import "cc/ipc/begin_frame_args.mojom"; -import "cc/ipc/compositor_frame.mojom"; import "cc/ipc/copy_output_request.mojom"; import "cc/ipc/frame_sink_id.mojom"; import "cc/ipc/local_surface_id.mojom"; @@ -13,6 +12,7 @@ import "cc/ipc/returned_resource.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 "ui/gfx/geometry/mojo/geometry.mojom"; // A CompositorFrameSink is an interface for receiving CompositorFrame @@ -34,7 +34,7 @@ // DidReceiveCompositorFrameAck() asynchronously when the frame has been // processed in order to unthrottle the next frame. SubmitCompositorFrame(cc.mojom.LocalSurfaceId local_surface_id, - cc.mojom.CompositorFrame frame, + viz.mojom.CompositorFrame frame, viz.mojom.HitTestRegionList? hit_test_region_list); // Notifies the frame sink that a BeginFrame was completed, but that no
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index c9ec6dd..ca68c80 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -10473,7 +10473,6 @@ "Fuchsia": { "additional_compile_targets": [ "gl_unittests", - "media_unittests", "net_unittests" ], "gtest_tests": [ @@ -10502,6 +10501,15 @@ "test": "ipc_tests" }, { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.media_unittests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "media_unittests" + }, + { "swarming": { "can_use_on_swarming_builders": false }, @@ -10586,6 +10594,15 @@ "test": "ipc_tests" }, { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.media_unittests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": false + }, + "test": "media_unittests" + }, + { "swarming": { "can_use_on_swarming_builders": false },
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json index a8f92d2..61020f5 100644 --- a/testing/buildbot/chromium.perf.json +++ b/testing/buildbot/chromium.perf.json
@@ -2644,6 +2644,67 @@ }, { "args": [ + "smoothness.key_desktop_move_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_desktop_move_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build48-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "smoothness.key_desktop_move_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_desktop_move_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build48-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.key_mobile_sites_smooth", "-v", "--upload-results", @@ -3132,6 +3193,67 @@ }, { "args": [ + "smoothness.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_animation_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build13-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "smoothness.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_animation_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build13-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.tough_filters_cases", "-v", "--upload-results", @@ -3193,6 +3315,67 @@ }, { "args": [ + "smoothness.tough_image_decode_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_image_decode_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build48-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "smoothness.tough_image_decode_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_image_decode_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build48-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.tough_path_rendering_cases", "-v", "--upload-results", @@ -3559,6 +3742,128 @@ }, { "args": [ + "start_with_ext.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.cold.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build48-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.cold.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build48-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.warm.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build13-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.warm.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build13-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "start_with_url.cold.startup_pages", "-v", "--upload-results", @@ -7356,6 +7661,67 @@ }, { "args": [ + "smoothness.key_desktop_move_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_desktop_move_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build75-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "smoothness.key_desktop_move_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_desktop_move_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build75-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.key_mobile_sites_smooth", "-v", "--upload-results", @@ -7844,6 +8210,67 @@ }, { "args": [ + "smoothness.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_animation_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build73-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "smoothness.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_animation_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build73-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.tough_filters_cases", "-v", "--upload-results", @@ -7905,6 +8332,67 @@ }, { "args": [ + "smoothness.tough_image_decode_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_image_decode_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build75-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "smoothness.tough_image_decode_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_image_decode_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build75-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.tough_path_rendering_cases", "-v", "--upload-results", @@ -8271,6 +8759,128 @@ }, { "args": [ + "start_with_ext.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.cold.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build75-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.cold.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build75-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.warm.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build73-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.warm.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build73-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "start_with_url.cold.startup_pages", "-v", "--upload-results", @@ -10818,6 +11428,37 @@ }, { "args": [ + "smoothness.key_desktop_move_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.key_desktop_move_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.key_mobile_sites_smooth", "-v", "--upload-results", @@ -11066,6 +11707,37 @@ }, { "args": [ + "smoothness.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_animation_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build164-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.tough_filters_cases", "-v", "--upload-results", @@ -11097,6 +11769,37 @@ }, { "args": [ + "smoothness.tough_image_decode_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_image_decode_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build165-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.tough_path_rendering_cases", "-v", "--upload-results", @@ -11283,6 +11986,68 @@ }, { "args": [ + "start_with_ext.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "start_with_ext.cold.blank_page", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build166-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "start_with_ext.warm.blank_page", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build164-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "start_with_url.cold.startup_pages", "-v", "--upload-results", @@ -14541,6 +15306,67 @@ }, { "args": [ + "smoothness.key_desktop_move_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_desktop_move_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build45-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "smoothness.key_desktop_move_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_desktop_move_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build45-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.key_mobile_sites_smooth", "-v", "--upload-results", @@ -15029,6 +15855,67 @@ }, { "args": [ + "smoothness.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_animation_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build15-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "smoothness.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_animation_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build15-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.tough_filters_cases", "-v", "--upload-results", @@ -15090,6 +15977,67 @@ }, { "args": [ + "smoothness.tough_image_decode_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_image_decode_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build45-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "smoothness.tough_image_decode_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_image_decode_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build45-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.tough_path_rendering_cases", "-v", "--upload-results", @@ -15456,6 +16404,128 @@ }, { "args": [ + "start_with_ext.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.cold.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build45-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.cold.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build45-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.warm.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build15-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.warm.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build15-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "start_with_url.cold.startup_pages", "-v", "--upload-results", @@ -18034,6 +19104,37 @@ }, { "args": [ + "smoothness.key_desktop_move_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.key_desktop_move_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.key_mobile_sites_smooth", "-v", "--upload-results", @@ -18282,6 +19383,37 @@ }, { "args": [ + "smoothness.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_animation_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build112-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.tough_filters_cases", "-v", "--upload-results", @@ -18313,6 +19445,37 @@ }, { "args": [ + "smoothness.tough_image_decode_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "smoothness.tough_image_decode_cases", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build113-b1--device1", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.tough_path_rendering_cases", "-v", "--upload-results", @@ -18499,6 +19662,68 @@ }, { "args": [ + "start_with_ext.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "start_with_ext.cold.blank_page", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build114-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-webview", + "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk" + ], + "isolate_name": "telemetry_perf_webview_tests", + "name": "start_with_ext.warm.blank_page", + "override_compile_targets": [ + "telemetry_perf_webview_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build112-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "start_with_url.cold.startup_pages", "-v", "--upload-results", @@ -21757,6 +22982,67 @@ }, { "args": [ + "smoothness.key_desktop_move_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_desktop_move_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build49-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "smoothness.key_desktop_move_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_desktop_move_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build49-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.key_mobile_sites_smooth", "-v", "--upload-results", @@ -22245,6 +23531,67 @@ }, { "args": [ + "smoothness.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_animation_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build9-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "smoothness.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_animation_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build9-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.tough_filters_cases", "-v", "--upload-results", @@ -22306,6 +23653,67 @@ }, { "args": [ + "smoothness.tough_image_decode_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_image_decode_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build49-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "smoothness.tough_image_decode_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_image_decode_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build49-b1--device5", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.tough_path_rendering_cases", "-v", "--upload-results", @@ -22672,6 +24080,128 @@ }, { "args": [ + "start_with_ext.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.cold.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build49-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.cold.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build49-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.warm.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build9-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.warm.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build9-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "start_with_url.cold.startup_pages", "-v", "--upload-results", @@ -26347,6 +27877,67 @@ }, { "args": [ + "smoothness.key_desktop_move_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_desktop_move_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build47-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "smoothness.key_desktop_move_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.key_desktop_move_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build47-b1--device3", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.key_mobile_sites_smooth", "-v", "--upload-results", @@ -26835,6 +28426,67 @@ }, { "args": [ + "smoothness.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_animation_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build17-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "smoothness.tough_animation_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_animation_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build17-b1--device6", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.tough_filters_cases", "-v", "--upload-results", @@ -26896,6 +28548,67 @@ }, { "args": [ + "smoothness.tough_image_decode_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_image_decode_cases", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build47-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "smoothness.tough_image_decode_cases", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "smoothness.tough_image_decode_cases.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build47-b1--device2", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "smoothness.tough_path_rendering_cases", "-v", "--upload-results", @@ -27262,6 +28975,128 @@ }, { "args": [ + "start_with_ext.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.cold.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build47-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.cold.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.cold.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build47-b1--device4", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=android-chromium" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.warm.blank_page", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build17-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ + "start_with_ext.warm.blank_page", + "-v", + "--upload-results", + "--output-format=chartjson", + "--browser=reference", + "--output-trace-tag=_ref" + ], + "isolate_name": "telemetry_perf_tests", + "name": "start_with_ext.warm.blank_page.reference", + "override_compile_targets": [ + "telemetry_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "android_devices": "1", + "id": "build17-b1--device7", + "os": "Android", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": true, + "io_timeout": 3600, + "upload_test_results": false + } + }, + { + "args": [ "start_with_url.cold.startup_pages", "-v", "--upload-results",
diff --git a/testing/buildbot/filters/fuchsia.media_unittests.filter b/testing/buildbot/filters/fuchsia.media_unittests.filter new file mode 100644 index 0000000..236c722 --- /dev/null +++ b/testing/buildbot/filters/fuchsia.media_unittests.filter
@@ -0,0 +1,11 @@ +# TODO(fuchsia): Fix these tests and remove the filter. crbug.com/731302 . + +# Mojo hasn't been ported yet. crbug.com/740791 +-Mojo* + +# These tests are slow and may flake under qemu. crbug.com/745094 +-Pipeline* + +# These tests depend on base::CancelableSyncSocket, which is currently +# broken, see https://crbug.com/741783 +-*Audio*DeviceTest.*CreateStream*
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService index 704e628..03517aa2 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
@@ -1,7 +1,6 @@ # These tests currently fail when run with --enable-network-service # See https://crbug.com/729849 -Bug(none) accessibility/table-cell-for-column-and-row-crash.html [ Timeout ] Bug(none) battery-status/api-defined.html [ Timeout ] Bug(none) battery-status/multiple-promises-after-resolve.html [ Timeout ] Bug(none) battery-status/multiple-promises.html [ Timeout ] @@ -101,28 +100,12 @@ Bug(none) bluetooth/service/getCharacteristics/gen-get-same-object-with-uuid.html [ Timeout ] Bug(none) bluetooth/service/getCharacteristics/gen-get-same-object.html [ Timeout ] Bug(none) bluetooth/service/getCharacteristics/gen-invalid-characteristic-name.html [ Timeout ] -Bug(none) compositing/color-matching/image-color-matching.html [ Failure ] -Bug(none) compositing/geometry/video-fixed-scrolling.html [ Failure ] -Bug(none) compositing/geometry/video-opacity-overlay.html [ Failure ] -Bug(none) compositing/iframes/iframe-in-composited-layer.html [ Failure ] -Bug(none) compositing/layers-inside-overflow-scroll.html [ Failure Timeout ] -Bug(none) compositing/overflow/overflow-compositing-descendant.html [ Failure ] -Bug(none) compositing/overflow/scroll-ancestor-update.html [ Failure ] -Bug(none) compositing/reflections/load-video-in-reflection.html [ Failure ] -Bug(none) compositing/self-painting-layers.html [ Failure ] -Bug(none) compositing/self-painting-layers2.html [ Timeout ] Bug(none) compositing/video-frame-size-change.html [ Timeout ] -Bug(none) compositing/video/video-reflection.html [ Timeout ] -Bug(none) compositing/visibility/visibility-simple-video-layer.html [ Failure ] -Bug(none) crypto/gc.html [ Timeout ] Bug(none) css-parser/color3.html [ Failure ] Bug(none) css-parser/color3_hsl.html [ Failure ] Bug(none) css-parser/color3_hsla_1.html [ Failure ] Bug(none) css-parser/color3_hsla_2.html [ Failure ] Bug(none) css-parser/color3_keywords.html [ Failure ] -Bug(none) css2.1/t040304-c64-uri-00-a-g.html [ Failure ] -Bug(none) css3/filters/effect-reference-removed-while-pending-resources.html [ Timeout ] -Bug(none) dom/attr/access-after-element-destruction.html [ Timeout ] Bug(none) dom/legacy_dom_conformance/svg/level3/xpath/Attribute_Nodes.svg [ Failure ] Bug(none) dom/legacy_dom_conformance/svg/level3/xpath/Attribute_Nodes_xmlns.svg [ Failure ] Bug(none) dom/legacy_dom_conformance/svg/level3/xpath/Comment_Nodes.svg [ Failure ] @@ -183,32 +166,13 @@ Bug(none) dom/legacy_dom_conformance/svg/level3/xpath/XPathResult_snapshotLength_ORDERED_NODE_SNAPSHOT_TYPE.svg [ Failure ] Bug(none) dom/legacy_dom_conformance/svg/level3/xpath/XPathResult_snapshotLength_UNORDERED_NODE_SNAPSHOT_TYPE.svg [ Failure ] Bug(none) dom/legacy_dom_conformance/svg/level3/xpath/XPathResult_stringValue.svg [ Failure ] -Bug(none) editing/input/drag_in_unselectable.html [ Failure ] -Bug(none) editing/input/text-input-controller-leak-document.html [ Timeout ] -Bug(none) editing/inserting/delete-insignificant-text-crash.html [ Timeout ] -Bug(none) editing/inserting/insert-html-crash.html [ Timeout ] -Bug(none) editing/style/apply-style-join-child-text-nodes-crash.html [ Timeout ] Bug(none) external/wpt/2dcontext/imagebitmap/createImageBitmap-drawImage.html [ Crash Failure Timeout ] Bug(none) external/wpt/clear-site-data/storage.https.html [ Failure ] Bug(none) external/wpt/fetch/api/abort/serviceworker-intercepted.https.html [ Crash Failure Timeout ] Bug(none) external/wpt/FileAPI/historical.https.html [ Crash Failure Timeout ] Bug(none) external/wpt/FileAPI/url/url_xmlhttprequest.html [ Crash Failure Timeout ] -Bug(none) external/wpt/IndexedDB [ Failure Timeout ] -Bug(none) external/wpt/WebIDL/ecmascript-binding/es-exceptions/exceptions.html [ Failure Timeout ] -Bug(none) external/wpt/WebIDL/ecmascript-binding/has-instance.html [ Failure Timeout ] Bug(none) external/wpt/XMLHttpRequest [ Crash Failure Timeout ] Bug(none) external/wpt/background-fetch/interfaces-worker.https.html [ Crash Failure Timeout ] -Bug(none) external/wpt/battery-status/battery-discharging-manual.https.html [ Failure Timeout ] -Bug(none) external/wpt/battery-status/battery-full-manual.https.html [ Failure Timeout ] -Bug(none) external/wpt/battery-status/battery-iframe.https.html [ Failure Timeout ] -Bug(none) external/wpt/battery-status/battery-interface-idlharness.https.html [ Failure Timeout ] -Bug(none) external/wpt/battery-status/battery-promise-window.https.html [ Failure Timeout ] -Bug(none) external/wpt/battery-status/battery-promise.https.html [ Failure Timeout ] -Bug(none) external/wpt/beacon/headers/header-content-type.html [ Failure Timeout ] -Bug(none) external/wpt/beacon/headers/header-referrer-no-referrer-when-downgrade.https.html [ Failure Timeout ] -Bug(none) external/wpt/beacon/headers/header-referrer-strict-origin-when-cross-origin.https.html [ Failure Timeout ] -Bug(none) external/wpt/beacon/headers/header-referrer-strict-origin.https.html [ Failure Timeout ] -Bug(none) external/wpt/beacon/headers/header-referrer-unsafe-url.https.html [ Failure Timeout ] Bug(none) external/wpt/clear-site-data/navigation.https.html [ Timeout ] Bug(none) external/wpt/content-security-policy/child-src/child-src-about-blank-allowed-by-default.sub.html [ Failure Timeout ] Bug(none) external/wpt/content-security-policy/child-src/child-src-about-blank-allowed-by-scheme.sub.html [ Failure Timeout ] @@ -253,46 +217,25 @@ Bug(none) external/wpt/content-security-policy/script-src/script-src-report-only-policy-works-with-hash-policy.html [ Failure ] Bug(none) external/wpt/content-security-policy/style-src/style-src-multiple-policies-multiple-hashing-algorithms.html [ Failure ] Bug(none) external/wpt/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy.html [ Failure ] -Bug(none) external/wpt/content-security-policy/securitypolicyviolation/img-src-redirect-upgrade-reporting.https.html [ Failure Timeout ] Bug(none) external/wpt/content-security-policy/securitypolicyviolation/inside-service-worker.https.html [ Crash Failure Timeout ] -Bug(none) external/wpt/content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html [ Failure Timeout ] Bug(none) external/wpt/content-security-policy/svg/svg-inline.sub.html [ Failure Timeout ] -Bug(none) external/wpt/content-security-policy/worker-src/dedicated-child.sub.html [ Failure Timeout ] -Bug(none) external/wpt/content-security-policy/worker-src/dedicated-fallback.sub.html [ Failure Timeout Failure ] -Bug(none) external/wpt/content-security-policy/worker-src/dedicated-list.sub.html [ Failure Timeout ] -Bug(none) external/wpt/content-security-policy/worker-src/dedicated-self.sub.html [ Failure Timeout ] Bug(none) external/wpt/content-security-policy/worker-src/service-child.https.sub.html [ Crash Failure Timeout ] Bug(none) external/wpt/content-security-policy/worker-src/service-fallback.https.sub.html [ Crash Failure Timeout ] Bug(none) external/wpt/content-security-policy/worker-src/service-list.https.sub.html [ Crash Failure Timeout ] -Bug(none) external/wpt/content-security-policy/worker-src/service-none.https.sub.html [ Failure Timeout ] Bug(none) external/wpt/content-security-policy/worker-src/service-self.https.sub.html [ Crash Failure Timeout ] Bug(none) external/wpt/content-security-policy/worker-src/shared-child.sub.html [ Failure Timeout ] Bug(none) external/wpt/content-security-policy/worker-src/shared-fallback.sub.html [ Failure Timeout ] Bug(none) external/wpt/content-security-policy/worker-src/shared-list.sub.html [ Failure Timeout ] -Bug(none) external/wpt/content-security-policy/worker-src/shared-self.sub.html [ Failure Timeout ] Bug(none) external/wpt/cookies/secure/set-from-dom.https.sub.html [ Failure Timeout ] Bug(none) external/wpt/cookies/secure/set-from-http.https.sub.html [ Failure Timeout ] -Bug(none) external/wpt/cookies/secure/set-from-ws.https.sub.html [ Failure Timeout ] -Bug(none) external/wpt/cookies/secure/set-from-wss.https.sub.html [ Failure Timeout ] Bug(none) external/wpt/cors/allow-headers.htm [ Failure Timeout ] -Bug(none) external/wpt/cors/basic.htm [ Failure Timeout ] Bug(none) external/wpt/cors/origin.htm [ Failure Timeout ] Bug(none) external/wpt/cors/preflight-cache.htm [ Failure Timeout ] Bug(none) external/wpt/cors/request-headers.htm [ Failure Timeout ] Bug(none) external/wpt/cors/response-headers.htm [ Failure Timeout ] Bug(none) external/wpt/cors/simple-requests.htm [ Failure Timeout ] -Bug(none) external/wpt/css-font-display/font-display.html [ Failure Timeout ] -Bug(none) external/wpt/css/CSS2/floats-clear/floats-015.xht [ Failure Timeout ] -Bug(none) external/wpt/css/css-grid-1/alignment/grid-content-distribution-018.html [ Failure Timeout ] -Bug(none) external/wpt/css/css-shapes-1/shape-outside/shape-box/shape-outside-box-003.html [ Failure Timeout ] -Bug(none) external/wpt/css/css-shapes-1/shape-outside/values/shape-outside-ellipse-004.html [ Failure Timeout ] Bug(none) external/wpt/cssom-view/scrolling-quirks-vs-nonquirks.html [ Failure Timeout ] Bug(none) external/wpt/cssom-view/scrollingElement.html [ Failure Timeout ] -Bug(none) external/wpt/custom-elements/custom-element-registry/per-global.html [ Failure Timeout ] -Bug(none) external/wpt/dom/nodes/Document-URL.sub.html [ Failure Timeout ] -Bug(none) external/wpt/dom/nodes/Document-characterSet-normalization.html [ Crash Failure Timeout ] -Bug(none) external/wpt/dom/nodes/Document-createElement-namespace.html [ Failure Timeout ] -Bug(none) external/wpt/dom/nodes/Element-remove.html [ Failure Timeout ] Bug(none) external/wpt/domxpath/xml_xpath_runner.html [ Failure Timeout ] Bug(none) external/wpt/eventsource/dedicated-worker/eventsource-onopen.htm [ Failure Timeout ] Bug(none) external/wpt/fetch/api/basic/accept-header.any.html [ Failure ] @@ -308,36 +251,10 @@ Bug(none) external/wpt/fetch/api/policies/referrer-origin-when-cross-origin-service-worker.https.html [ Crash Failure Timeout ] Bug(none) external/wpt/fetch/api/policies/referrer-unsafe-url-service-worker.https.html [ Crash Failure Timeout ] Bug(none) external/wpt/fetch/api/response/response-cancel-stream.html [ Timeout ] -Bug(none) external/wpt/fullscreen/api/document-exit-fullscreen-active-document.html [ Failure Timeout ] -Bug(none) external/wpt/fullscreen/api/document-fullscreen-enabled-active-document.html [ Failure Timeout ] -Bug(none) external/wpt/fullscreen/api/element-request-fullscreen-active-document.html [ Failure Timeout ] -Bug(none) external/wpt/hr-time/test_cross_frame_start.html [ Failure Timeout ] -Bug(none) external/wpt/hr-time/window-worker-time-origin.html [ Timeout ] Bug(none) external/wpt/html/browsers/browsing-the-web/navigating-across-documents/012.html [ Failure Timeout ] -Bug(none) external/wpt/html/browsers/browsing-the-web/read-media/pageload-video.html [ Crash Pass Failure Timeout ] -Bug(none) external/wpt/html/browsers/browsing-the-web/unloading-documents/005.html [ Crash ] -Bug(none) external/wpt/html/browsers/history/the-location-interface/location-pathname-setter-question-mark.html [ Failure Timeout ] Bug(none) external/wpt/html/browsers/history/the-location-interface/location-protocol-setter-non-broken-weird.html [ Failure Timeout Failure ] -Bug(none) external/wpt/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html [ Failure Timeout ] -Bug(none) external/wpt/html/browsers/history/the-location-interface/location-prototype-setting-cross-origin.sub.html [ Failure Timeout ] -Bug(none) external/wpt/html/browsers/history/the-location-interface/location-prototype-setting-goes-cross-origin-domain.sub.html [ Failure Timeout ] Bug(none) external/wpt/html/browsers/offline/appcache/workers/appcache-worker.html [ Timeout ] -Bug(none) external/wpt/html/browsers/offline/application-cache-api/api_status_idle.html [ Failure Timeout ] -Bug(none) external/wpt/html/browsers/the-window-object/Window-document.html [ Failure Timeout ] -Bug(none) external/wpt/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/creating_browsing_context_test_01.html [ Failure Timeout ] -Bug(none) external/wpt/html/browsers/the-windowproxy-exotic-object/windowproxy-prototype-setting-cross-origin.sub.html [ Failure Timeout ] -Bug(none) external/wpt/html/browsers/the-windowproxy-exotic-object/windowproxy-prototype-setting-goes-cross-origin-domain.sub.html [ Failure Timeout ] -Bug(none) external/wpt/html/browsers/windows/browsing-context-names/choose-_blank-002.html [ Failure Timeout ] -Bug(none) external/wpt/html/browsers/windows/browsing-context-names/choose-default-001.html [ Failure Timeout ] -Bug(none) external/wpt/html/browsers/windows/nested-browsing-contexts/window-parent-null.html [ Failure Timeout ] -Bug(none) external/wpt/html/browsers/windows/nested-browsing-contexts/window-parent.html [ Failure Timeout ] -Bug(none) external/wpt/html/browsers/windows/nested-browsing-contexts/window-top-null.html [ Failure Timeout ] -Bug(none) external/wpt/html/browsers/windows/nested-browsing-contexts/window-top.html [ Failure Timeout ] -Bug(none) external/wpt/html/browsers/windows/noreferrer-null-opener.html [ Failure Timeout ] -Bug(none) external/wpt/html/dom/self-origin.sub.html [ Failure Timeout ] Bug(none) external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https.html [ Crash Failure Timeout ] -Bug(none) external/wpt/html/infrastructure/urls/terminology-0/document-base-url.html [ Failure Timeout ] -Bug(none) external/wpt/html/rendering/non-replaced-elements/the-page/iframe-marginwidth-marginheight.html [ Failure Timeout ] Bug(none) external/wpt/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html [ Failure Timeout ] Bug(none) external/wpt/html/semantics/embedded-content/media-elements/ready-states/autoplay-with-slow-text-tracks.html [ Failure Timeout ] Bug(none) external/wpt/html/semantics/embedded-content/media-elements/video_008.htm [ Failure Timeout ] @@ -354,15 +271,12 @@ Bug(none) external/wpt/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-agent-formalism/canblock-serviceworker.https.html [ Crash Failure Timeout ] Bug(none) external/wpt/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-events.serviceworker.https.html [ Crash Failure Timeout ] Bug(none) external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/Worker_Self_Origin.html [ Failure Timeout ] -Bug(none) external/wpt/media-source/mediasource-config-change-webm-a-bitrate.html [ Failure Timeout ] Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-wss/websocket-request/top-level/keep-scheme-redirect/websocket-allowed.https.html [ Failure Timeout ] Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-wss/websocket-request/top-level/no-redirect/websocket-allowed.https.html [ Failure Timeout ] Bug(none) external/wpt/navigation-timing/nav2_test_attributes_values.html [ Failure Timeout ] Bug(none) external/wpt/navigation-timing/nav2_test_unloadEvents_previous_document_cross_origin.sub.html [ Failure Timeout ] Bug(none) external/wpt/notifications/shownotification-resolve-manual.https.html [ Failure Timeout ] Bug(none) external/wpt/offscreen-canvas [ Crash Failure Timeout ] -Bug(none) external/wpt/orientation-sensor/idlharness.https.html [ Failure Timeout ] -Bug(none) external/wpt/pointerevents/pointerevent_touch-action-table-test_touch-manual.html [ Failure Timeout ] Bug(none) external/wpt/preload/fetch-destination.https.html [ Crash Failure Timeout ] Bug(none) external/wpt/preload/single-download-preload.html [ Failure Timeout ] Bug(none) external/wpt/resource-timing/resource_TAO_match_origin.htm [ Failure Timeout ] @@ -371,20 +285,7 @@ Bug(none) external/wpt/resource-timing/resource_cached.htm [ Failure Timeout ] Bug(none) external/wpt/resource-timing/resource_connection_reuse.html [ Failure Timeout ] Bug(none) external/wpt/resource-timing/test_resource_timing.html [ Failure Timeout ] -Bug(none) external/wpt/secure-contexts/basic-popup-and-iframe-tests.html [ Failure Timeout ] Bug(none) external/wpt/service-workers [ Crash Failure Timeout ] -Bug(none) external/wpt/storage/estimate-indexeddb-worker.https.html [ Failure Timeout ] -Bug(none) external/wpt/storage/estimate-indexeddb.https.html [ Failure Timeout ] -Bug(none) external/wpt/storage/interfaces.https.html [ Failure Timeout ] -Bug(none) external/wpt/storage/opaque-origin.https.html [ Failure Timeout ] -Bug(none) external/wpt/storage/persist-permission-manual.https.html [ Failure Timeout ] -Bug(none) external/wpt/storage/persisted-worker.https.html [ Failure Timeout ] -Bug(none) external/wpt/storage/persisted.https.html [ Failure Timeout ] -Bug(none) external/wpt/storage/storagemanager-estimate.https.html [ Failure Timeout ] -Bug(none) external/wpt/storage/storagemanager-persist-worker.https.html [ Failure Timeout ] -Bug(none) external/wpt/storage/storagemanager-persist.https.html [ Failure Timeout ] -Bug(none) external/wpt/storage/storagemanager-persisted-worker.https.html [ Failure Timeout ] -Bug(none) external/wpt/storage/storagemanager-persisted.https.html [ Failure Timeout ] Bug(none) external/wpt/streams/byte-length-queuing-strategy.serviceworker.https.html [ Crash Failure Timeout ] Bug(none) external/wpt/streams/count-queuing-strategy.serviceworker.https.html [ Crash Failure Timeout ] Bug(none) external/wpt/streams/piping/close-propagation-backward.serviceworker.https.html [ Crash Failure Timeout ] @@ -430,23 +331,9 @@ Bug(none) external/wpt/streams/writable-streams/start.serviceworker.https.html [ Crash Failure Timeout ] Bug(none) external/wpt/streams/writable-streams/write.serviceworker.https.html [ Crash Failure Timeout ] Bug(none) external/wpt/html/syntax/parsing/html5lib_tests1.html?run_type=uri [ Timeout ] -Bug(none) external/wpt/url/failure.html [ Failure Timeout ] Bug(none) external/wpt/wasm/wasm_service_worker_test.https.html [ Crash Timeout ] -Bug(none) external/wpt/web-animations/interfaces/AnimationTimeline/document-timeline.html [ Failure ] -Bug(none) external/wpt/web-share/idlharness.https.html [ Failure Timeout ] -Bug(none) external/wpt/web-share/share-url-invalid.https.html [ Failure Timeout ] -Bug(none) external/wpt/web-share/share-without-user-gesture.https.html [ Failure Timeout ] -Bug(none) external/wpt/webaudio/the-audio-api/the-audiobuffer-interface/idl-test.html [ Failure Timeout ] -Bug(none) external/wpt/webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test.html [ Failure Timeout ] -Bug(none) external/wpt/webaudio/the-audio-api/the-audioparam-interface/idl-test.html [ Failure Timeout ] -Bug(none) external/wpt/webaudio/the-audio-api/the-constantsourcenode-interface/test-constantsourcenode.html [ Failure Timeout ] -Bug(none) external/wpt/webaudio/the-audio-api/the-delaynode-interface/idl-test.html [ Failure Timeout ] -Bug(none) external/wpt/webaudio/the-audio-api/the-gainnode-interface/idl-test.html [ Failure Timeout ] -Bug(none) external/wpt/webaudio/the-audio-api/the-iirfilternode-interface/test-iirfilternode.html [ Failure Timeout ] Bug(none) external/wpt/websockets/cookies/003.html [ Failure ] -Bug(none) external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_future.html [ Failure Timeout ] Bug(none) external/wpt/workers/SharedWorker_blobUrl.html [ Failure Timeout ] -Bug(none) external/wpt/workers/name-property.html [ Failure Timeout ] Bug(none) fast/canvas/canvas-createImageBitmap-drawImage.html [ Crash Failure ] Bug(none) fast/canvas/webgl/texImage-imageBitmap-from-imageBitmap-from-blob.html [ Crash Failure ] Bug(none) fast/canvas/canvas-createImageBitmap-invalid-blob-in-workers.html [ Crash ] @@ -456,120 +343,20 @@ Bug(none) fast/canvas/canvas-createImageBitmap-invalid-args.html [ Crash ] Bug(none) fast/canvas/canvas-createImageBitmap-size-tooBig.html [ Crash ] Bug(none) fast/canvas/webgl/texImage-imageBitmap-from-blob-resize.html [ Crash Failure ] -Bug(none) fast/css/counters/counter-traverse-table-cell.html [ Failure ] -Bug(none) fast/css/font-face-attribute-remove.html [ Timeout ] -Bug(none) fast/css/object-fit-grow-landscape.html [ Failure ] -Bug(none) fast/css/object-fit-grow-portrait.html [ Failure ] -Bug(none) fast/dnd/file-drag-drop-on-page.html [ Failure ] -Bug(none) fast/dom/Document/xml-document-focus.xml [ Failure ] -Bug(none) fast/dom/Element/offsetLeft-offsetTop-body-quirk.html [ Failure ] -Bug(none) fast/dom/Element/offsetLeft-offsetTop-html.html [ Failure ] -Bug(none) fast/dom/HTMLAnchorElement/anchor-download-unset.html [ Timeout ] -Bug(none) fast/dom/HTMLAnchorElement/anchor-nodownload.html [ Timeout ] -Bug(none) fast/dom/HTMLLinkElement/prefetch.html [ Failure ] -Bug(none) fast/dom/HTMLLinkElement/subresource.html [ Failure ] -Bug(none) fast/dom/HTMLObjectElement/update-data.html [ Timeout ] -Bug(none) fast/dom/NodeList/nodelist-reachable.html [ Timeout ] Bug(none) fast/dom/Range/surround-contents-font-face-crash.svg [ Timeout ] -Bug(none) fast/dom/StyleSheet/gc-parent-rule.html [ Timeout ] -Bug(none) fast/dom/StyleSheet/gc-rule-children-wrappers.html [ Timeout ] -Bug(none) fast/dom/StyleSheet/gc-styleheet-wrapper.xhtml [ Failure Timeout ] -Bug(none) fast/dom/Window/customized-property-survives-gc.html [ Timeout ] -Bug(none) fast/dom/Window/property-access-on-cached-properties-after-frame-navigated.html [ Timeout ] -Bug(none) fast/dom/Window/property-access-on-cached-window-after-frame-navigated.html [ Timeout ] -Bug(none) fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced.html [ Timeout ] -Bug(none) fast/dom/child-insertion-notify-crash.html [ Timeout ] -Bug(none) fast/dom/css-delete-doc.html [ Timeout ] -Bug(none) fast/dom/document-navigation-error-no-crash.html [ Timeout ] -Bug(none) fast/dom/gc-dom-tree-lifetime.html [ Timeout ] -Bug(none) fast/dom/gc-image-element-2.html [ Timeout ] -Bug(none) fast/dom/node-filter-gc.html [ Timeout ] Bug(none) fast/dom/split-cdata.xml [ Timeout ] -Bug(none) fast/encoding/char-encoding.html [ Timeout ] -Bug(none) fast/events/attribute-listener-cloned-from-frameless-doc-context-2.html [ Timeout ] Bug(none) fast/events/attribute-listener-cloned-from-frameless-doc.xhtml [ Timeout ] -Bug(none) fast/events/attribute-listener-extracted-from-frameless-doc-context-2.html [ Timeout ] -Bug(none) fast/events/before-unload-adopt-within-subframes.html [ Timeout ] -Bug(none) fast/events/before-unload-remove-and-add-subframe.html [ Timeout ] -Bug(none) fast/events/click-after-mousedown-cancel.html [ Timeout ] -Bug(none) fast/events/crash-on-querying-event-path.html [ Timeout ] -Bug(none) fast/events/drag-and-drop-autoscroll-inner-frame.html [ Failure ] Bug(none) fast/events/event-on-xhr-document.html [ Failure ] -Bug(none) fast/events/event-properties-gc.html [ Timeout ] -Bug(none) fast/events/media-focus-in-standalone-media-document.html [ Crash Timeout ] -Bug(none) fast/events/message-port-gc-closed-cloned.html [ Timeout ] -Bug(none) fast/events/message-port-gc-closed.html [ Timeout ] Bug(none) fast/events/message-port-transferables.html [ Timeout ] -Bug(none) fast/events/resize-subframe.html [ Failure ] -Bug(none) fast/events/touch/gesture/long-press-focuses-frame.html [ Failure ] -Bug(none) fast/events/wheel/mouse-wheel-scroll-latching.html [ Timeout Pass ] -Bug(none) fast/events/wheel/wheel-scroll-latching-on-scrollbar.html [ Crash Timeout Pass ] -Bug(none) fast/files/apply-blob-url-to-img.html [ Timeout ] Bug(none) fast/files/apply-blob-url-to-xhr.html [ Crash Timeout ] Bug(none) fast/files/workers/worker-apply-blob-url-to-xhr.html [ Crash Failure Timeout ] -Bug(none) fast/files/workers/worker-read-file-async.html [ Failure ] -Bug(none) fast/files/workers/worker-read-file-constructor-async.html [ Timeout ] -Bug(none) fast/files/workers/worker-read-file-sync.html [ Failure ] Bug(none) fast/files/xhr-response-blob.html [ Crash Failure ] -Bug(none) fast/filesystem/file-writer-truncate-extend.html [ Failure ] -Bug(none) fast/filesystem/file-writer-write-overlapped.html [ Failure ] -Bug(none) fast/filesystem/filesystem-reference.html [ Timeout ] -Bug(none) fast/filesystem/form-reading-from-file.html [ Failure ] -Bug(none) fast/filesystem/snapshot-file-with-gc.html [ Failure ] -Bug(none) fast/filesystem/workers/file-writer-sync-truncate-extend.html [ Failure ] -Bug(none) fast/filesystem/workers/file-writer-sync-write-overlapped.html [ Failure ] -Bug(none) fast/filesystem/workers/file-writer-truncate-extend.html [ Failure ] -Bug(none) fast/filesystem/workers/file-writer-write-overlapped.html [ Failure ] -Bug(none) fast/forms/file/recover-file-input-in-unposted-form.html [ Crash Pass Timeout ] -Bug(none) fast/forms/select/input-select-after-resize.html [ Failure ] -Bug(none) fast/forms/select/option-add-crash.html [ Timeout ] -Bug(none) fast/forms/select/select-set-length-with-mutation-remove.html [ Timeout ] -Bug(none) fast/frames/content-opacity-1.html [ Failure ] -Bug(none) fast/frames/frame-navigation.html [ Failure ] -Bug(none) fast/frames/frame-src-attribute.html [ Timeout ] -Bug(none) fast/frames/frameset-style-recalc.html [ Failure ] -Bug(none) fast/frames/negative-remaining-length-crash.html [ Failure ] -Bug(none) fast/frames/sandboxed-iframe-plugins.html [ Failure ] -Bug(none) fast/frames/set-parent-src-synchronously-xhtml.xhtml [ Crash ] -Bug(none) fast/harness/internals-observe-gc.html [ Timeout ] -Bug(none) fast/harness/perftests/measure-time.html [ Timeout ] -Bug(none) fast/harness/perftests/runs-per-second-iterations.html [ Timeout ] -Bug(none) fast/harness/perftests/runs-per-second-log.html [ Timeout ] Bug(none) fast/history/history-back-twice-with-subframes-assert.html [ Timeout ] -Bug(none) fast/html/imports/import-expando-gc.html [ Timeout ] -Bug(none) fast/js/nested-object-gc.html [ Timeout ] -Bug(none) fast/js/with-scope-gc.html [ Timeout ] -Bug(none) fast/loader/document-destruction-within-unload.html [ Crash ] Bug(none) fast/loader/local-svg-parsed-as-svg.svg [ Timeout ] -Bug(none) fast/loader/main-document-url-for-non-http-loads.html [ Failure ] Bug(none) fast/loader/object-with-rejected-resource.html [ Failure ] -Bug(none) fast/loader/reload-zero-byte-plugin.html [ Timeout ] -Bug(none) fast/loader/sandboxed-plugin-crash.html [ Crash ] -Bug(none) fast/loader/simultaneous-reloads-assert.html [ Failure ] -Bug(none) fast/loader/stateobjects/pushstate-in-data-url-denied.html [ Failure ] -Bug(none) fast/loader/url-strip-cr-lf-tab.html [ Failure ] -Bug(none) fast/media/mq-color-gamut-picture.html [ Failure ] -Bug(none) fast/mediastream/MediaStreamTrack-clone.html [ Timeout ] -Bug(none) fast/mediastream/MediaStreamTrack-contentHint.html [ Timeout ] Bug(none) fast/parser/compatMode-in-xhtml.xhtml [ Timeout ] Bug(none) fast/parser/external-entities-in-xslt.xml [ Failure ] -Bug(none) fast/parser/xhtml-close-while-parsing.xhtml [ Crash ] -Bug(none) fast/parser/xhtml-document-with-html-object.xhtml [ Timeout ] -Bug(none) fast/parser/xhtml-dom-character-data-modified-crash.html [ Crash ] -Bug(none) fast/parser/xhtml-synchronous-detach-crash.html [ Crash ] -Bug(none) fast/peerconnection/RTCPeerConnection-lifetime.html [ Timeout ] -Bug(none) fast/replaced/frame-removed-during-resize-smaller.html [ Timeout ] -Bug(none) fast/replaced/frame-removed-during-resize.html [ Timeout ] Bug(none) fast/serviceworker/access-container-on-local-file.html [ Failure ] -Bug(none) fast/spatial-navigation/snav-hidden-iframe-zero-size.html [ Failure ] -Bug(none) fast/spatial-navigation/snav-hidden-iframe.html [ Failure ] -Bug(none) fast/spatial-navigation/snav-iframe-nested.html [ Failure ] -Bug(none) fast/spatial-navigation/snav-iframe-no-focusable-content.html [ Failure ] -Bug(none) fast/spatial-navigation/snav-iframe-no-scrollable-content.html [ Failure ] -Bug(none) fast/spatial-navigation/snav-iframe-recursive-offset-parent.html [ Failure ] -Bug(none) fast/spatial-navigation/snav-iframe-with-offscreen-focusable-element.html [ Failure ] -Bug(none) fast/spatial-navigation/snav-media-elements.html [ Timeout ] -Bug(none) fast/tokenizer/image-empty-crash.html [ Timeout ] Bug(none) fast/workers/shared-worker-console-log.html [ Timeout ] Bug(none) fast/workers/close-context-messageport-crash.html [ Timeout ] Bug(none) fast/xmlhttprequest/xmlhttprequest-bad-mimetype.html [ Failure ] @@ -589,15 +376,6 @@ Bug(none) fast/xsl/xslt-processor.html [ Failure ] Bug(none) fast/xsl/xslt-relative-path.xml [ Failure ] Bug(none) fast/xsl/xslt-second-level-import.xml [ Skip ] -Bug(none) fullscreen/full-screen-iframe-allowed-video.html [ Timeout ] -Bug(none) fullscreen/full-screen-iframe-legacy.html [ Timeout ] -Bug(none) fullscreen/full-screen-iframe-without-allow-attribute-allowed-from-parent.html [ Failure ] -Bug(none) fullscreen/video-controls-timeline.html [ Timeout ] -Bug(none) fullscreen/video-specified-size.html [ Timeout ] -Bug(none) harness-tests/mojo-helpers.html [ Timeout ] -Bug(none) html/document_metadata/head-check.html [ Timeout ] -Bug(none) html/marquee/marquee-clone-crash.html [ Timeout ] -Bug(none) html5lib/generated/run-tests1-data.html [ Timeout ] Bug(none) http/tests/appcache/404-manifest.html [ Failure ] Bug(none) http/tests/appcache/abort-cache-ondownloading-manifest-404.html [ Timeout ] Bug(none) http/tests/appcache/access-via-redirect.php [ Timeout ] @@ -989,77 +767,8 @@ Bug(none) http/tests/local/formdata/send-form-data.html [ Failure ] Bug(none) http/tests/local/formdata/upload-events.html [ Failure ] Bug(none) http/tests/local/serviceworker/fetch-request-body-file.html [ Crash Timeout ] -Bug(none) http/tests/media/audio-seekable-contains-zero-without-ranges.html [ Timeout ] -Bug(none) http/tests/media/audio-timeline-seek-outside-seekable.html [ Timeout ] -Bug(none) http/tests/media/autoplay-crossorigin.html [ Timeout ] -Bug(none) http/tests/media/controls/controls-list-add-hide.html [ Timeout ] -Bug(none) http/tests/media/controls/controls-list-remove-show.html [ Timeout ] -Bug(none) http/tests/media/controls/video-controls-overflow-menu-correct-ordering.html [ Timeout ] -Bug(none) http/tests/media/controls/video-controls-overflow-menu-updates-appropriately.html [ Timeout ] -Bug(none) http/tests/media/encrypted-media/encrypted-media-encrypted-event-same-origin.html [ Timeout ] -Bug(none) http/tests/media/gc-while-network-loading.html [ Timeout ] -Bug(none) http/tests/media/media-document.html [ Crash ] -Bug(none) http/tests/media/media-source/mediasource-addsourcebuffer.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-append-buffer.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-appendwindow.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-avtracks.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-buffered.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-config-change-webm-a-bitrate.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-config-change-webm-av-audio-bitrate.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-config-change-webm-av-framesize.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-config-change-webm-av-video-bitrate.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-detach.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-duration-boundaryconditions.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-duration.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-errors.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-getvideoplaybackquality.html [ Failure Timeout ] -Bug(none) http/tests/media/media-source/mediasource-initsegmentreceived-alg.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-play-then-seek-back.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-play.html [ Failure Timeout ] -Bug(none) http/tests/media/media-source/mediasource-precise-duration.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-redundant-seek.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-remove.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-removesourcebuffer.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-seek-beyond-duration.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-seek-during-pending-seek.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-seekable.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-sequencemode-append-buffer.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-sequencemode-crbug-616565.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-sourcebuffer-mode.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-sourcebuffer-trackdefaults.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-sourcebufferlist.html [ Timeout ] -Bug(none) http/tests/media/media-source/mediasource-timestamp-offset.html [ Timeout ] -Bug(none) http/tests/media/media-source/stream_memory_tests/mediasource-appendbuffer-quota-exceeded-default-buffers.html [ Timeout ] -Bug(none) http/tests/media/mixed-range-response.html [ Timeout ] -Bug(none) http/tests/media/preload-conditions.html [ Timeout ] -Bug(none) http/tests/media/progress-events-generated-correctly.html [ Timeout ] -Bug(none) http/tests/media/reload-after-dialog.html [ Timeout ] -Bug(none) http/tests/media/remove-while-loading.html [ Timeout ] -Bug(none) http/tests/media/video-buffered-range-contains-currentTime.html [ Timeout ] Bug(none) http/tests/media/video-buffered.html [ Timeout ] -Bug(none) http/tests/media/video-cancel-load.html [ Timeout ] -Bug(none) http/tests/media/video-controls-download-button-displayed.html [ Timeout ] -Bug(none) http/tests/media/video-controls-download-button-not-displayed-hide-download-ui.html [ Timeout ] -Bug(none) http/tests/media/video-controls-download-button-not-displayed-mediastream.html [ Timeout ] -Bug(none) http/tests/media/video-controls-download-button-saves-media.html [ Timeout ] -Bug(none) http/tests/media/video-controls-overflow-menu-download-button.html [ Timeout ] -Bug(none) http/tests/media/video-cookie.html [ Timeout ] -Bug(none) http/tests/media/video-error-abort.html [ Timeout ] Bug(none) http/tests/media/video-in-iframe-crash.html [ Crash Timeout ] -Bug(none) http/tests/media/video-load-metadata-decode-error.html [ Timeout ] -Bug(none) http/tests/media/video-load-suspend.html [ Timeout ] -Bug(none) http/tests/media/video-load-twice.html [ Timeout ] -Bug(none) http/tests/media/video-load-with-userpass.html [ Timeout ] -Bug(none) http/tests/media/video-play-progress.html [ Timeout ] -Bug(none) http/tests/media/video-play-stall-before-meta-data.html [ Timeout ] -Bug(none) http/tests/media/video-preload-metadata.html [ Timeout ] -Bug(none) http/tests/media/video-query-url.html [ Timeout ] -Bug(none) http/tests/media/video-referer.html [ Timeout ] -Bug(none) http/tests/media/video-seek-to-duration.html [ Timeout ] -Bug(none) http/tests/media/video-seek-to-middle.html [ Timeout ] -Bug(none) http/tests/media/video-served-as-text.html [ Timeout ] -Bug(none) http/tests/media/video-throttled-load-metadata.html [ Timeout ] -Bug(none) http/tests/media/video-useragent.html [ Timeout ] Bug(none) http/tests/misc/adopt-iframe-src-attr-after-remove.html [ Timeout ] Bug(none) http/tests/misc/createElementNamespace1.xml [ Failure ] Bug(none) http/tests/misc/detach-and-location-change-in-onload.html [ Timeout ] @@ -1372,17 +1081,6 @@ Bug(none) http/tests/workers/shared-worker-secure-context.https.html [ Timeout ] Bug(none) http/tests/workers/text-encoding.html [ Failure ] Bug(none) http/tests/xmlhttprequest [ Crash Failure Timeout ] -Bug(none) imagecapture/MediaStreamTrack-applyConstraints-getSettings.html [ Timeout ] -Bug(none) imagecapture/MediaStreamTrack-applyConstraints-reject.html [ Timeout ] -Bug(none) imagecapture/MediaStreamTrack-applyConstraints.html [ Timeout ] -Bug(none) imagecapture/MediaStreamTrack-getCapabilities.html [ Timeout ] -Bug(none) imagecapture/MediaStreamTrack-getSettings.html [ Timeout ] -Bug(none) imagecapture/getPhotoCapabilities.html [ Timeout ] -Bug(none) imagecapture/getPhotoSettings.html [ Timeout ] -Bug(none) imagecapture/setOptions-reject.html [ Timeout ] -Bug(none) imagecapture/setOptions.html [ Timeout ] -Bug(none) imagecapture/takePhoto-with-PhotoSettings.html [ Timeout ] -Bug(none) imagecapture/takePhoto.html [ Timeout ] Bug(none) inspector-enabled/console/console-uncaught-promise-no-inspector.html [ Timeout ] Bug(none) inspector-protocol/accessibility/accessibility-nameSources-buttons.js [ Timeout ] Bug(none) inspector-protocol/css/css-get-background-colors.js [ Timeout ] @@ -1559,343 +1257,6 @@ Bug(none) installedapp/getinstalledrelatedapps-empty.html [ Timeout ] Bug(none) installedapp/getinstalledrelatedapps.html [ Timeout ] Bug(none) loader/iframe-src-change-onload-crash.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_canplay.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_canplay_manual.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_canplaythrough.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_canplaythrough_manual.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_loadeddata.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_loadeddata_manual.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_loadedmetadata.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_loadedmetadata_manual.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_loadstart.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_loadstart_manual.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_order_canplay_canplaythrough.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_order_canplay_playing.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_order_loadedmetadata_loadeddata.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_order_loadstart_progress.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_pause_manual.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_play.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_play_manual.html [ Failure Timeout ] -Bug(none) media/W3C/audio/events/event_playing.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_playing_manual.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_progress.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_progress_manual.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_timeupdate.html [ Timeout ] -Bug(none) media/W3C/audio/events/event_timeupdate_manual.html [ Timeout ] -Bug(none) media/W3C/audio/networkState/networkState_during_loadstart.html [ Timeout ] -Bug(none) media/W3C/audio/paused/paused_false_during_play.html [ Timeout ] -Bug(none) media/W3C/audio/paused/paused_true_during_pause.html [ Timeout ] -Bug(none) media/W3C/audio/readyState/readyState_during_canplay.html [ Timeout ] -Bug(none) media/W3C/audio/readyState/readyState_during_canplaythrough.html [ Timeout ] -Bug(none) media/W3C/audio/readyState/readyState_during_loadeddata.html [ Timeout ] -Bug(none) media/W3C/audio/readyState/readyState_during_loadedmetadata.html [ Timeout ] -Bug(none) media/W3C/audio/readyState/readyState_during_playing.html [ Timeout ] -Bug(none) media/W3C/audio/src/src_removal_does_not_trigger_loadstart.html [ Timeout ] -Bug(none) media/W3C/video/events/event_canplay.html [ Timeout ] -Bug(none) media/W3C/video/events/event_canplay_manual.html [ Timeout ] -Bug(none) media/W3C/video/events/event_canplaythrough.html [ Timeout ] -Bug(none) media/W3C/video/events/event_canplaythrough_manual.html [ Timeout ] -Bug(none) media/W3C/video/events/event_loadeddata.html [ Timeout ] -Bug(none) media/W3C/video/events/event_loadeddata_manual.html [ Timeout ] -Bug(none) media/W3C/video/events/event_loadedmetadata.html [ Timeout ] -Bug(none) media/W3C/video/events/event_loadedmetadata_manual.html [ Timeout ] -Bug(none) media/W3C/video/events/event_loadstart.html [ Timeout ] -Bug(none) media/W3C/video/events/event_loadstart_manual.html [ Timeout ] -Bug(none) media/W3C/video/events/event_order_canplay_canplaythrough.html [ Timeout ] -Bug(none) media/W3C/video/events/event_order_canplay_playing.html [ Timeout ] -Bug(none) media/W3C/video/events/event_order_loadedmetadata_loadeddata.html [ Timeout ] -Bug(none) media/W3C/video/events/event_order_loadstart_progress.html [ Timeout ] -Bug(none) media/W3C/video/events/event_pause_manual.html [ Timeout ] -Bug(none) media/W3C/video/events/event_play.html [ Timeout ] -Bug(none) media/W3C/video/events/event_play_manual.html [ Timeout ] -Bug(none) media/W3C/video/events/event_playing.html [ Timeout ] -Bug(none) media/W3C/video/events/event_playing_manual.html [ Timeout ] -Bug(none) media/W3C/video/events/event_progress.html [ Timeout ] -Bug(none) media/W3C/video/events/event_progress_manual.html [ Timeout ] -Bug(none) media/W3C/video/events/event_timeupdate.html [ Timeout ] -Bug(none) media/W3C/video/events/event_timeupdate_manual.html [ Timeout ] -Bug(none) media/W3C/video/networkState/networkState_during_loadstart.html [ Timeout ] -Bug(none) media/W3C/video/networkState/networkState_during_progress.html [ Timeout ] -Bug(none) media/W3C/video/paused/paused_false_during_play.html [ Timeout ] -Bug(none) media/W3C/video/paused/paused_true_during_pause.html [ Timeout ] -Bug(none) media/W3C/video/readyState/readyState_during_canplay.html [ Timeout ] -Bug(none) media/W3C/video/readyState/readyState_during_canplaythrough.html [ Timeout ] -Bug(none) media/W3C/video/readyState/readyState_during_loadeddata.html [ Timeout ] -Bug(none) media/W3C/video/readyState/readyState_during_loadedmetadata.html [ Timeout ] -Bug(none) media/W3C/video/readyState/readyState_during_playing.html [ Timeout ] -Bug(none) media/W3C/video/src/src_removal_does_not_trigger_loadstart.html [ Timeout ] -Bug(none) media/audio-concurrent-supported.html [ Timeout ] -Bug(none) media/audio-constructor-preload.html [ Timeout ] -Bug(none) media/audio-constructor-src.html [ Timeout ] -Bug(none) media/audio-constructor.html [ Timeout ] -Bug(none) media/audio-controls-captions.html [ Timeout ] -Bug(none) media/audio-controls-do-not-fade-out.html [ Timeout ] -Bug(none) media/audio-controls-rendering.html [ Timeout ] -Bug(none) media/audio-data-url.html [ Timeout ] -Bug(none) media/audio-delete-while-slider-thumb-clicked.html [ Timeout ] -Bug(none) media/audio-garbage-collect.html [ Timeout ] -Bug(none) media/audio-only-video-intrinsic-size.html [ Timeout ] -Bug(none) media/audio-play-event.html [ Timeout ] -Bug(none) media/auto-play-in-sandbox-with-allow-scripts.html [ Timeout ] -Bug(none) media/autoplay-clears-autoplaying-flag.html [ Timeout ] -Bug(none) media/autoplay-document-move.html [ Timeout ] -Bug(none) media/autoplay-from-mediastream-to-src.html [ Timeout ] -Bug(none) media/autoplay-muted-conditions.html [ Timeout ] -Bug(none) media/autoplay-muted-datasaver-off.html [ Timeout ] -Bug(none) media/autoplay-muted-datasaver-on.html [ Timeout ] -Bug(none) media/autoplay-muted.html [ Timeout ] -Bug(none) media/autoplay-never-visible.html [ Timeout ] -Bug(none) media/autoplay-non-whitelisted-scope.html [ Timeout ] -Bug(none) media/autoplay-unmute-offscreen.html [ Timeout ] -Bug(none) media/autoplay-when-visible-multiple-times.html [ Timeout ] -Bug(none) media/autoplay-when-visible.html [ Timeout ] -Bug(none) media/autoplay-whitelisted-scope.html [ Timeout ] -Bug(none) media/autoplay-with-preload-none.html [ Timeout ] -Bug(none) media/autoplay.html [ Timeout ] -Bug(none) media/avtrack/addtrack.html [ Timeout ] -Bug(none) media/avtrack/audio-track-enabled.html [ Timeout ] -Bug(none) media/avtrack/audio-track-properties.html [ Timeout ] -Bug(none) media/avtrack/forget-on-load.html [ Timeout ] -Bug(none) media/avtrack/gc.html [ Timeout ] -Bug(none) media/avtrack/getTrackById.html [ Timeout ] -Bug(none) media/avtrack/track-switching.html [ Timeout ] -Bug(none) media/avtrack/video-track-properties.html [ Timeout ] -Bug(none) media/avtrack/video-track-selected.html [ Timeout ] -Bug(none) media/color-profile-munsell-bt601-smpte-to-srgb.html [ Failure ] -Bug(none) media/color-profile-munsell-bt709-to-srgb.html [ Failure ] -Bug(none) media/color-profile-video-poster-image.html [ Failure ] -Bug(none) media/color-profile-video-seek-filter.html [ Timeout ] -Bug(none) media/color-profile-video-seek-object-fit.html [ Timeout ] -Bug(none) media/color-profile-video-seek.html [ Timeout ] -Bug(none) media/color-profile-video.html [ Timeout ] -Bug(none) media/controls-after-reload.html [ Timeout ] -Bug(none) media/controls-drag-timebar-rendering.html [ Timeout ] -Bug(none) media/controls-drag-timebar.html [ Timeout ] -Bug(none) media/controls-right-click-on-timebar.html [ Timeout ] -Bug(none) media/controls-strict.html [ Timeout ] -Bug(none) media/controls-styling-strict.html [ Timeout ] -Bug(none) media/controls-styling.html [ Timeout ] -Bug(none) media/controls-timeline.html [ Timeout ] -Bug(none) media/controls-volume-slider-keynav.html [ Timeout ] -Bug(none) media/controls-volume-slider.html [ Timeout ] -Bug(none) media/controls-without-preload.html [ Timeout ] -Bug(none) media/controls/buttons-after-reset.html [ Timeout ] -Bug(none) media/controls/closed-captions-switch-track.html [ Timeout ] -Bug(none) media/controls/controls-cast-button-narrow.html [ Timeout ] -Bug(none) media/controls/controls-cast-button.html [ Timeout ] -Bug(none) media/controls/controls-cast-do-not-fade-out.html [ Timeout ] -Bug(none) media/controls/controls-cast-overlay-slow-fade.html [ Timeout ] -Bug(none) media/controls/controls-overlay-cast-button.html [ Timeout ] -Bug(none) media/controls/overflow-fully-hidden.html [ Timeout ] -Bug(none) media/controls/overlay-play-button-document-move.html [ Timeout ] -Bug(none) media/controls/overlay-play-button-narrow.html [ Timeout ] -Bug(none) media/controls/settings-disable-controls.html [ Timeout ] -Bug(none) media/controls/time-update-after-unload.html [ Timeout ] -Bug(none) media/controls/video-controls-overflow-menu-hide-on-click-outside.html [ Timeout ] -Bug(none) media/controls/video-controls-overflow-menu-hide-on-click-panel.html [ Timeout ] -Bug(none) media/controls/video-controls-overflow-menu-hide-on-click.html [ Timeout ] -Bug(none) media/controls/video-controls-overflow-menu-hide-on-resize.html [ Timeout ] -Bug(none) media/controls/video-controls-overflow-menu-text.html [ Timeout ] -Bug(none) media/controls/video-controls-overflow-menu-visibility.html [ Timeout ] -Bug(none) media/controls/video-controls-with-cast-rendering.html [ Timeout ] -Bug(none) media/controls/video-enter-exit-fullscreen-while-hovering-shows-controls.html [ Timeout ] -Bug(none) media/controls/video-overlay-cast-covering.html [ Timeout ] -Bug(none) media/controls/video-overlay-cast-dark-rendering.html [ Timeout ] -Bug(none) media/controls/video-overlay-cast-light-rendering.html [ Failure ] -Bug(none) media/controls/video-overlay-play-button.html [ Timeout ] -Bug(none) media/controls/volumechange-muted-attribute.html [ Timeout ] -Bug(none) media/controls/volumechange-stopimmediatepropagation.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-async-creation-with-gc.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-async-setcert-with-gc.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-lifetime-mediakeys-with-session.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-lifetime-mediakeys.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-lifetime-mediakeysession-reference.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-lifetime-mediakeysession-release-noreference.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-lifetime-mediakeysession-release.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-lifetime-multiple-mediakeys.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-lifetime-reload.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-onencrypted.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-playback-encrypted-and-clear-sources.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-playback-multiple-sessions.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-playback-setmediakeys-after-src.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-playback-setmediakeys-before-src.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-playback-two-videos.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-reset-src-after-setmediakeys.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-reset-src-during-setmediakeys.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-setmediakeys-again-after-playback.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-setmediakeys-again-after-resetting-src.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-setmediakeys-at-same-time.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-setmediakeys-multiple-times-with-different-mediakeys.html [ Timeout ] -Bug(none) media/encrypted-media/encrypted-media-waiting-for-a-key.html [ Timeout ] -Bug(none) media/event-attributes.html [ Timeout ] -Bug(none) media/fullscreen-controls-visible-last.html [ Timeout ] -Bug(none) media/gc-while-playing.html [ Timeout ] -Bug(none) media/gc-while-seeking.html [ Timeout ] -Bug(none) media/media-can-load-when-hidden.html [ Timeout ] -Bug(none) media/media-captions-no-controls.html [ Timeout ] -Bug(none) media/media-continues-playing-after-replace-source.html [ Timeout ] -Bug(none) media/media-controls-hide-menu-stoppropagation-iframe.html [ Timeout ] -Bug(none) media/media-controls-hide-menu-stoppropagation.html [ Timeout ] -Bug(none) media/media-controls-invalid-url.html [ Timeout ] -Bug(none) media/media-controls-overflow-hidden.html [ Timeout ] -Bug(none) media/media-controls-overflow-visible.html [ Timeout ] -Bug(none) media/media-controls-tap-show-controls-without-activating.html [ Timeout ] -Bug(none) media/media-document-audio-repaint.html [ Crash Timeout ] -Bug(none) media/media-document-audio-size.html [ Crash Timeout ] -Bug(none) media/media-element-play-after-eos.html [ Timeout ] -Bug(none) media/media-ended.html [ Timeout ] -Bug(none) media/media-extension-with-fragment.html [ Timeout ] -Bug(none) media/media-load-event.html [ Timeout ] -Bug(none) media/media-play-promise.html [ Timeout ] -Bug(none) media/media-source-append-multiple.html [ Timeout ] -Bug(none) media/mediasession/mojo/callback-alive-after-gc.html [ Timeout ] -Bug(none) media/mediasession/mojo/file-image-removed.html [ Timeout ] -Bug(none) media/mediasession/mojo/media-control-action-reaches-client.html [ Timeout ] -Bug(none) media/mediasession/mojo/media-control-set-handler-notifies-service.html [ Timeout ] -Bug(none) media/mediasession/mojo/metadata-async.html [ Timeout ] -Bug(none) media/mediasession/mojo/metadata-propagated-twice.html [ Timeout ] -Bug(none) media/mediasession/mojo/metadata-propagated.html [ Timeout ] -Bug(none) media/mediasession/mojo/metadata-session-link.html [ Timeout ] -Bug(none) media/mediasession/mojo/playback-state-propagated.html [ Timeout ] -Bug(none) media/mediasession/mojo/set-null-metadata.html [ Timeout ] -Bug(none) media/no-autoplay-with-user-gesture-requirement.html [ Timeout ] -Bug(none) media/play-promise-crash.html [ Timeout ] -Bug(none) media/remove-from-document.html [ Timeout ] -Bug(none) media/seek-to-currentTime.html [ Timeout ] -Bug(none) media/sources-fallback-codecs.html [ Timeout ] -Bug(none) media/track [ Failure Timeout ] -Bug(none) media/video-append-source.html [ Timeout ] -Bug(none) media/video-aspect-ratio.html [ Timeout ] -Bug(none) media/video-autoplay.html [ Timeout ] -Bug(none) media/video-black-bg-in-media-document.html [ Crash ] -Bug(none) media/video-buffered-unknown-duration.html [ Timeout ] -Bug(none) media/video-buffered.html [ Timeout ] -Bug(none) media/video-canvas-alpha.html [ Timeout ] -Bug(none) media/video-canvas-draw.html [ Timeout ] -Bug(none) media/video-colorspace-yuv420.html [ Failure ] -Bug(none) media/video-colorspace-yuv422.html [ Failure ] -Bug(none) media/video-controls-always-visible-when-control-hovered.html [ Timeout ] -Bug(none) media/video-controls-attribute-fullscreen.html [ Timeout ] -Bug(none) media/video-controls-auto-hide-after-play-by-touch.html [ Timeout ] -Bug(none) media/video-controls-dont-show-on-focus-when-disabled.html [ Timeout ] -Bug(none) media/video-controls-download-button-not-displayed-local.html [ Timeout ] -Bug(none) media/video-controls-focus-movement-on-hide.html [ Timeout ] -Bug(none) media/video-controls-fullscreen-iframe-allowed.html [ Timeout ] -Bug(none) media/video-controls-fullscreen-iframe-not-allowed.html [ Timeout ] -Bug(none) media/video-controls-fullscreen-not-supported.html [ Timeout ] -Bug(none) media/video-controls-fullscreen.html [ Timeout ] -Bug(none) media/video-controls-hidden-audio.html [ Timeout ] -Bug(none) media/video-controls-hide-after-touch-on-control.html [ Timeout ] -Bug(none) media/video-controls-hide-on-move-outside-controls.html [ Timeout ] -Bug(none) media/video-controls-in-media-document.html [ Crash Timeout ] -Bug(none) media/video-controls-mouse-events-captured.html [ Timeout ] -Bug(none) media/video-controls-muted-video-can-unmute.html [ Timeout ] -Bug(none) media/video-controls-overflow-menu-closed-captions-button.html [ Timeout ] -Bug(none) media/video-controls-overflow-menu-closed-captions-list-hide-on-click-outside.html [ Timeout ] -Bug(none) media/video-controls-overflow-menu-fullscreen-button.html [ Timeout ] -Bug(none) media/video-controls-overflow-menu-last-button-visible.html [ Timeout ] -Bug(none) media/video-controls-overflow-menu-mute-button.html [ Timeout ] -Bug(none) media/video-controls-overflow-menu-play-button.html [ Timeout ] -Bug(none) media/video-controls-rendering.html [ Timeout ] -Bug(none) media/video-controls-show-on-focus.html [ Timeout ] -Bug(none) media/video-controls-toggling.html [ Timeout ] -Bug(none) media/video-controls-touch-events-captured.html [ Timeout ] -Bug(none) media/video-controls-track-selection-menu.html [ Timeout ] -Bug(none) media/video-controls-transformed.html [ Timeout ] -Bug(none) media/video-controls-visibility-multimodal-mouse-after-touch.html [ Timeout ] -Bug(none) media/video-controls-visibility-multimodal-touch-after-mouse.html [ Timeout ] -Bug(none) media/video-controls-visible-audio-only.html [ Timeout ] -Bug(none) media/video-controls-zoomed.html [ Timeout ] -Bug(none) media/video-controls.html [ Timeout ] -Bug(none) media/video-currentTime-before-have-metadata-media-fragment-uri.html [ Timeout ] -Bug(none) media/video-currentTime-before-have-metadata.html [ Timeout ] -Bug(none) media/video-currentTime-delay.html [ Timeout ] -Bug(none) media/video-currentTime-set.html [ Timeout ] -Bug(none) media/video-currentTime-set2.html [ Timeout ] -Bug(none) media/video-currentTime.html [ Timeout ] -Bug(none) media/video-defaultmuted.html [ Timeout ] -Bug(none) media/video-delay-load-event.html [ Timeout Failure ] -Bug(none) media/video-display-aspect-ratio.html [ Timeout ] -Bug(none) media/video-display-none-crash.html [ Timeout ] -Bug(none) media/video-display-toggle.html [ Timeout ] -Bug(none) media/video-dom-autoplay.html [ Timeout ] -Bug(none) media/video-dom-src.html [ Timeout ] -Bug(none) media/video-double-seek-currentTime.html [ Timeout ] -Bug(none) media/video-duration-known-after-eos.html [ Timeout ] -Bug(none) media/video-enter-fullscreen-without-user-gesture.html [ Timeout ] -Bug(none) media/video-force-preload-none-to-metadata-on-load.html [ Timeout ] -Bug(none) media/video-force-preload-none-to-metadata-on-play.html [ Timeout ] -Bug(none) media/video-frame-accurate-seek.html [ Timeout ] -Bug(none) media/video-layer-crash.html [ Timeout ] -Bug(none) media/video-load-networkState.html [ Timeout ] -Bug(none) media/video-load-preload-none.html [ Timeout ] -Bug(none) media/video-load-readyState.html [ Timeout ] -Bug(none) media/video-loop-from-ended.html [ Timeout ] -Bug(none) media/video-loop.html [ Timeout ] -Bug(none) media/video-move-to-new-document-crash.html [ Timeout ] -Bug(none) media/video-move-to-new-document.html [ Timeout ] -Bug(none) media/video-muted.html [ Timeout ] -Bug(none) media/video-no-autoplay.html [ Timeout ] -Bug(none) media/video-no-controls-events-not-absorbed.html [ Timeout ] -Bug(none) media/video-no-timeupdate-before-playback.html [ Timeout ] -Bug(none) media/video-not-paused-while-looping.html [ Timeout ] -Bug(none) media/video-object-fit-change.html [ Timeout ] -Bug(none) media/video-object-fit.html [ Timeout ] -Bug(none) media/video-pause-empty-events.html [ Timeout ] -Bug(none) media/video-pause-immediately.html [ Failure Pass Timeout ] -Bug(none) media/video-persistence.html [ Timeout ] -Bug(none) media/video-play-empty-events.html [ Timeout ] -Bug(none) media/video-play-pause-events.html [ Timeout ] -Bug(none) media/video-play-require-user-gesture.html [ Timeout ] -Bug(none) media/video-playbackrate.html [ Timeout ] -Bug(none) media/video-played-collapse.html [ Timeout ] -Bug(none) media/video-played-ranges-1.html [ Timeout ] -Bug(none) media/video-played-reset.html [ Failure Pass Timeout ] -Bug(none) media/video-playing-and-pause.html [ Timeout ] -Bug(none) media/video-plays-past-end-of-test.html [ Timeout ] -Bug(none) media/video-poster-delayed.html [ Timeout ] -Bug(none) media/video-prefixed-fullscreen.html [ Timeout ] -Bug(none) media/video-preload-none-to-metadata-after-load-crash.html [ Timeout ] -Bug(none) media/video-preload.html [ Timeout ] -Bug(none) media/video-remove-insert-repaints.html [ Timeout ] -Bug(none) media/video-replaces-poster.html [ Timeout ] -Bug(none) media/video-scales-in-media-document.html [ Crash ] -Bug(none) media/video-seek-by-small-increment.html [ Timeout ] -Bug(none) media/video-seek-past-end-paused.html [ Timeout ] -Bug(none) media/video-seek-past-end-playing.html [ Timeout ] -Bug(none) media/video-seek-to-duration-with-playbackrate-zero.html [ Timeout ] -Bug(none) media/video-seekable.html [ Timeout ] -Bug(none) media/video-seeking.html [ Timeout ] -Bug(none) media/video-set-rate-from-pause.html [ Timeout ] -Bug(none) media/video-single-valid-source.html [ Timeout ] -Bug(none) media/video-size.html [ Timeout ] -Bug(none) media/video-source-add-after-remove.html [ Timeout ] -Bug(none) media/video-source-error.html [ Timeout ] -Bug(none) media/video-source-load.html [ Timeout ] -Bug(none) media/video-source-type-params.html [ Timeout ] -Bug(none) media/video-source-type.html [ Timeout ] -Bug(none) media/video-source.html [ Timeout ] -Bug(none) media/video-src-blob.html [ Failure ] -Bug(none) media/video-src-change.html [ Timeout ] -Bug(none) media/video-src-empty.html [ Timeout ] -Bug(none) media/video-src-remove.html [ Timeout ] -Bug(none) media/video-src-set.html [ Timeout ] -Bug(none) media/video-src-source.html [ Timeout ] -Bug(none) media/video-src.html [ Timeout ] -Bug(none) media/video-srcobject-mediastream-src-file.html [ Timeout ] -Bug(none) media/video-timeupdate-during-playback.html [ Timeout ] -Bug(none) media/video-transformed.html [ Timeout ] -Bug(none) media/video-volume.html [ Timeout ] -Bug(none) media/video-webkit-appearance.html [ Timeout ] -Bug(none) media/video-zoom-controls.html [ Failure Timeout ] -Bug(none) media/video-zoom.html [ Failure Timeout ] -Bug(none) media/viewport-in-standalone-media-document.html [ Crash ] -Bug(none) mhtml/invalid-bad-boundary.mht [ Timeout ] -Bug(none) netinfo/gc-frame-listeners.html [ Timeout ] -Bug(none) nfc/mock-nfc.html [ Timeout ] -Bug(none) nfc/nfc-block-iframe.html [ Timeout ] -Bug(none) nfc/push.html [ Timeout ] -Bug(none) nfc/watch.html [ Timeout ] Bug(none) paint/invalidation/media-audio-no-spurious-repaints.html [ Timeout ] Bug(none) paint/invalidation/svg/relative-sized-image.xhtml [ Failure ] Bug(none) paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem.html [ Failure ] @@ -1925,153 +1286,9 @@ Bug(none) presentation/presentationconnectionavailableevent-ctor-mock.html [ Timeout ] Bug(none) printing/subframes-percentage-height.html [ Failure ] Bug(none) scrollbars/listbox-scrollbar-combinations.html [ Failure ] -Bug(none) sensor/accelerometer.html [ Timeout ] -Bug(none) sensor/ambient-light-sensor.html [ Timeout ] -Bug(none) sensor/gyroscope.html [ Timeout ] -Bug(none) sensor/magnetometer.html [ Timeout ] -Bug(none) sensor/mock-sensor.html [ Timeout ] -Bug(none) sensor/orientation-sensor.html [ Timeout ] -Bug(none) shapedetection/detection-HTMLCanvasElement.html [ Timeout ] -Bug(none) shapedetection/detection-HTMLImageElement.html [ Timeout ] -Bug(none) shapedetection/detection-HTMLVideoElement.html [ Timeout ] -Bug(none) shapedetection/detection-ImageBitmap.html [ Timeout ] -Bug(none) shapedetection/detection-ImageData.html [ Timeout ] -Bug(none) shapedetection/detection-on-worker.html [ Timeout ] -Bug(none) shapedetection/detection-options.html [ Timeout ] -Bug(none) shapedetection/detection-security-test.html [ Timeout ] -Bug(none) shapedetection/detector-same-object.html [ Timeout ] Bug(none) storage/domstorage/events/basic.html [ Failure Timeout ] -Bug(none) storage/indexeddb/cursor-request-cycle.html [ Timeout ] -Bug(none) storage/indexeddb/cursor-value.html [ Timeout ] -Bug(none) storage/indexeddb/empty-crash.html [ Timeout ] -Bug(none) storage/indexeddb/key-cursor-request-cycle.html [ Timeout ] -Bug(none) storage/indexeddb/key-generator.html [ Timeout ] -Bug(none) storage/indexeddb/structured-clone.html [ Failure ] -Bug(none) storage/indexeddb/versionchangerequest-activedomobject.html [ Timeout ] -Bug(none) storage/websql/change-version.html [ Timeout ] -Bug(none) storage/websql/database-removed-context-crash.html [ Timeout ] -Bug(none) storage/websql/multiple-transactions.html [ Timeout ] -Bug(none) storage/websql/transaction-error-callback-isolated-world.html [ Timeout ] -Bug(none) storage/websql/transaction-success-callback-isolated-world.html [ Timeout ] -Bug(none) svg/W3C-SVG-1.1-SE/filters-image-03-f.svg [ Failure ] -Bug(none) svg/W3C-SVG-1.1-SE/filters-image-05-f.svg [ Failure ] -Bug(none) svg/W3C-SVG-1.1/render-groups-01-b.svg [ Failure ] -Bug(none) svg/W3C-SVG-1.1/render-groups-03-t.svg [ Failure ] -Bug(none) svg/W3C-SVG-1.1/struct-image-06-t.svg [ Failure ] -Bug(none) svg/W3C-SVG-1.1/struct-use-01-t.svg [ Failure ] -Bug(none) svg/animations/mpath-remove-from-dependents-on-delete-crash.html [ Timeout ] -Bug(none) svg/animations/target-condition-crash.html [ Timeout ] -Bug(none) svg/as-border-image/svg-as-border-image.html [ Failure ] -Bug(none) svg/as-image/image-preserveAspectRatio-all.svg [ Failure ] -Bug(none) svg/custom/g-outside-svg.html [ Failure ] -Bug(none) svg/custom/group-opacity.svg [ Failure ] -Bug(none) svg/dom/SVGAnimatedListPropertyTearOff-crash.html [ Timeout ] -Bug(none) svg/dom/SVGMatrixTearOff-crash.html [ Timeout ] -Bug(none) svg/dom/getScreenCTM-ancestor-transform.html [ Failure ] -Bug(none) svg/filters/feImage-preserveAspectRatio-all.svg [ Failure ] -Bug(none) svg/filters/feImage-preserveAspectratio.svg [ Failure ] -Bug(none) svg/filters/filter-source-position.svg [ Failure ] -Bug(none) svg/filters/filteredImage.svg [ Failure ] -Bug(none) svg/zoom/page/zoom-svg-through-object-with-absolute-size-2.xhtml [ Failure ] -Bug(none) svg/zoom/page/zoom-svg-through-object-with-absolute-size.xhtml [ Failure ] -Bug(none) svg/zoom/page/zoom-svg-through-object-with-percentage-size.xhtml [ Failure ] Bug(none) tables/mozilla/core/col_widths_fix_autoFixPer.html [ Timeout ] Bug(none) tables/mozilla_expected_failures/marvin/backgr_fixed-bg.html [ Failure ] Bug(none) traversal/node-iterator-009.html [ Failure ] Bug(none) traversal/tree-walker-006.html [ Failure ] -Bug(none) vibration/vibration-iframe.html [ Timeout ] -Bug(none) vibration/vibration.html [ Timeout ] -Bug(none) virtual [ Crash Failure Timeout ] -Bug(none) vr/events_vrdisplayactivate.html [ Timeout ] -Bug(none) vr/events_vrdisplayconnect.html [ Timeout ] -Bug(none) vr/events_vrdisplaypresentchange.html [ Timeout ] -Bug(none) vr/exitPresent_reject_notpresenting.html [ Timeout ] -Bug(none) vr/exitPresent_resolve.html [ Timeout ] -Bug(none) vr/getEyeParameters_match.html [ Timeout ] -Bug(none) vr/getFrameData_noupdate.html [ Timeout ] -Bug(none) vr/getFrameData_oneframeupdate.html [ Timeout ] -Bug(none) vr/getFrameData_samewithinframe.html [ Failure Timeout ] -Bug(none) vr/getLayers_notpresenting.html [ Timeout ] -Bug(none) vr/getLayers_presenting.html [ Timeout ] -Bug(none) vr/getLayers_presenting_nondefaultbounds.html [ Timeout ] -Bug(none) vr/getLayers_update.html [ Timeout ] -Bug(none) vr/getVRDisplays_one_display.html [ Timeout ] -Bug(none) vr/getVRDisplays_two_display.html [ Timeout ] -Bug(none) vr/getVRDisplays_zero_display.html [ Timeout ] -Bug(none) vr/multiple_requestAnimationFrame_called.html [ Timeout ] -Bug(none) vr/requestAnimationFrame_called.html [ Timeout ] -Bug(none) vr/requestAnimationFrame_consistentTimestamps.html [ Timeout ] -Bug(none) vr/requestAnimationFrame_handoff.html [ Timeout ] -Bug(none) vr/requestAnimationFrame_invalidhandle.html [ Timeout ] -Bug(none) vr/requestAnimationFrame_submitFrame_combinations.html [ Timeout ] -Bug(none) vr/requestAnimationFrame_unregister.html [ Timeout ] -Bug(none) vr/requestPresent_reject_badleftbounds.html [ Timeout ] -Bug(none) vr/requestPresent_reject_NaN_bounds.html [ Timeout ] -Bug(none) vr/requestPresent_reject_badrightbounds.html [ Timeout ] -Bug(none) vr/requestPresent_reject_nogesture.html [ Timeout ] -Bug(none) vr/requestPresent_reject_nolayers.html [ Timeout ] -Bug(none) vr/requestPresent_reject_nosource.html [ Timeout ] -Bug(none) vr/requestPresent_reject_notsupported.html [ Timeout ] -Bug(none) vr/requestPresent_reject_nowebgl.html [ Timeout ] -Bug(none) vr/requestPresent_reject_nullsource.html [ Timeout ] -Bug(none) vr/requestPresent_reject_toomanylayers.html [ Timeout ] -Bug(none) vr/requestPresent_resolve.html [ Timeout ] -Bug(none) vr/requestPresent_resolve_repeatwithgesture.html [ Timeout ] -Bug(none) vr/requestPresent_resolve_repeatwithoutgesture.html [ Timeout ] -Bug(none) vr/requestPresent_resolve_then_reject.html [ Timeout ] -Bug(none) vr/requestPresent_resolve_webgl2.html [ Timeout ] -Bug(none) vr/stageParameters_match.html [ Timeout ] -Bug(none) webaudio/Analyser/realtimeanalyser-basic.html [ Timeout ] -Bug(none) webaudio/Analyser/realtimeanalyser-fft-scaling.html [ Timeout ] -Bug(none) webaudio/Analyser/realtimeanalyser-fft-sizing.html [ Timeout ] -Bug(none) webaudio/Analyser/realtimeanalyser-float-data.html [ Timeout ] -Bug(none) webaudio/Analyser/realtimeanalyser-freq-data.html [ Timeout ] -Bug(none) webaudio/AudioBuffer/audiobuffer-copy-channel.html [ Timeout ] -Bug(none) webaudio/AudioBuffer/audiobuffer-getChannelData.html [ Timeout ] -Bug(none) webaudio/AudioBuffer/audiobuffer.html [ Timeout ] -Bug(none) webaudio/AudioBufferSource/audiobuffersource-channels.html [ Timeout ] -Bug(none) webaudio/AudioContext/audiocontext-close-basic.html [ Timeout ] -Bug(none) webaudio/AudioContext/audiocontext-getoutputtimestamp.html [ Timeout ] -Bug(none) webaudio/AudioContext/audiocontext-listener-should-not-crash.html [ Timeout ] -Bug(none) webaudio/AudioContext/audiocontext-max-contexts.html [ Timeout ] -Bug(none) webaudio/AudioContext/audiocontext-suspend-resume.html [ Timeout ] -Bug(none) webaudio/AudioContext/audiocontextoptions.html [ Timeout ] -Bug(none) webaudio/AudioNode/audionode-connect-method-chaining.html [ Timeout ] -Bug(none) webaudio/AudioNode/audionode-disconnect-audioparam.html [ Timeout ] -Bug(none) webaudio/AudioNode/audionode.html [ Timeout ] -Bug(none) webaudio/AudioParam/audioparam-exceptional-values.html [ Timeout ] -Bug(none) webaudio/AudioParam/audioparam-method-chaining.html [ Timeout ] -Bug(none) webaudio/BiquadFilter/biquad-automation.html [ Timeout ] -Bug(none) webaudio/BiquadFilter/biquad-getFrequencyResponse.html [ Timeout ] -Bug(none) webaudio/BiquadFilter/biquadfilternode-basic.html [ Timeout ] -Bug(none) webaudio/ConstantSource/constant-source-basic.html [ Timeout ] -Bug(none) webaudio/Convolver/convolver-setBuffer-null.html [ Timeout ] -Bug(none) webaudio/DynamicsCompressor/dynamicscompressor-basic.html [ Timeout ] -Bug(none) webaudio/Gain/gain-basic.html [ Timeout ] -Bug(none) webaudio/IIRFilter/iir-tail-time.html [ Timeout ] -Bug(none) webaudio/IIRFilter/iirfilter.html [ Timeout ] -Bug(none) webaudio/MediaElementAudioSource/mediaelementaudiosourcenode.html [ Timeout ] -Bug(none) webaudio/MediaStreamAudioDestination/mediastreamaudiodestinationnode.html [ Timeout ] -Bug(none) webaudio/MediaStreamAudioSource/mediastreamaudiosourcenode.html [ Timeout ] -Bug(none) webaudio/Panner/pannernode-basic.html [ Timeout ] -Bug(none) webaudio/PeriodicWave/periodicwave-lengths.html [ Timeout ] -Bug(none) webaudio/StereoPanner/stereopannernode-basic.html [ Timeout ] -Bug(none) webaudio/audio-scheduled-source-basic.html [ Timeout ] -Bug(none) webaudio/codec-tests/webm/webm-decode.html [ Timeout ] -Bug(none) webaudio/constructor/mediastreamaudiodestination.html [ Timeout ] -Bug(none) webaudio/constructor/mediastreamaudiosource.html [ Timeout ] -Bug(none) webaudio/decodeAudioData/decode-audio-data-basic.html [ Failure Pass Timeout ] -Bug(none) webaudio/dom-exceptions.html [ Timeout ] -Bug(none) webaudio/internals/audiocontext-close.html [ Timeout ] -Bug(none) webaudio/internals/audiocontext-lock-threading-race.html [ Timeout ] -Bug(none) webaudio/internals/audiosource-premature-gc.html [ Timeout ] -Bug(none) webaudio/internals/audiosummingjunction-crash.html [ Timeout ] -Bug(none) webaudio/internals/mediaelementaudiosourcenode-wrapper.html [ Timeout ] -Bug(none) webaudio/test-basic.html [ Timeout ] -Bug(none) webaudio/unit-tests/audit.html [ Timeout ] -Bug(none) webshare/share-arity.html [ Timeout ] -Bug(none) webshare/share-error.html [ Timeout ] -Bug(none) webshare/share-nonutf8-encoding.html [ Timeout ] -Bug(none) webshare/share-success.html [ Timeout ] -Bug(none) webshare/share-types.html [ Timeout ] -Bug(none) webshare/share-url-relative.html [ Timeout ] +Bug(none) virtual [ Crash Failure Timeout ] \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-transforms-2/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/css/css-transforms-2/OWNERS new file mode 100644 index 0000000..2c3d32a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-transforms-2/OWNERS
@@ -0,0 +1,2 @@ +# TEAM: paint-dev@chromium.org +# COMPONENT: Blink>Transforms
diff --git a/third_party/WebKit/LayoutTests/external/wpt/images/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/images/OWNERS new file mode 100644 index 0000000..990a4f1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/images/OWNERS
@@ -0,0 +1,2 @@ +# TEAM: paint-dev@chromium.org +# COMPONENT: Blink>Image
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/svg/OWNERS index 212e449..9e4d106 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/svg/OWNERS +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/OWNERS
@@ -1 +1,2 @@ -foolip@chromium.org +# TEAM: paint-dev@chromium.org +# COMPONENT: Blink>SVG
diff --git a/third_party/WebKit/Source/core/css/StyleSheetContentsFuzzer.cpp b/third_party/WebKit/Source/core/css/StyleSheetContentsFuzzer.cpp index a2a3c73..f23bc97a 100644 --- a/third_party/WebKit/Source/core/css/StyleSheetContentsFuzzer.cpp +++ b/third_party/WebKit/Source/core/css/StyleSheetContentsFuzzer.cpp
@@ -14,8 +14,17 @@ blink::CSSParserContext::Create(blink::kHTMLStandardMode); blink::StyleSheetContents* styleSheet = blink::StyleSheetContents::Create(context); + styleSheet->ParseString(String::FromUTF8WithLatin1Fallback( reinterpret_cast<const char*>(data), size)); + +#if defined(ADDRESS_SANITIZER) + // LSAN needs unreachable objects to be released to avoid reporting them + // incorrectly as a memory leak. + blink::ThreadState* currentThreadState = blink::ThreadState::Current(); + currentThreadState->CollectAllGarbage(); +#endif + return 0; }
diff --git a/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.cpp index ce88a75..c46a77ca 100644 --- a/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.cpp +++ b/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.cpp
@@ -833,32 +833,45 @@ if (web_event.GetType() == WebInputEvent::kRawKeyDown || web_event.GetType() == WebInputEvent::kKeyDown) { - if ((web_event.GetModifiers() & WebInputEvent::kInputModifiers) == - kEditingModifier && - // Only copy/cut if there's a selection, so that we only ever do - // this for Pepper plugins that support copying/cutting. - // Windowless NPAPI plugins will get the event as before. - web_plugin_->HasSelection()) { - if (web_event.windows_key_code == VKEY_C || - web_event.windows_key_code == VKEY_INSERT) { - Copy(); - event->SetDefaultHandled(); - return; + int input_modifiers = + web_event.GetModifiers() & WebInputEvent::kInputModifiers; + if (input_modifiers == kEditingModifier) { + // Only copy/cut if there's a selection, so that we only ever do + // this for Pepper plugins that support copying/cutting. + // Windowless NPAPI plugins will get the event as before. + if (web_plugin_->HasSelection()) { + if (web_event.windows_key_code == VKEY_C || + web_event.windows_key_code == VKEY_INSERT) { + Copy(); + event->SetDefaultHandled(); + return; + } + if (web_event.windows_key_code == VKEY_X && + ExecuteEditCommand("Cut", "")) { + event->SetDefaultHandled(); + return; + } } - // Ask the plugin if it can cut text before executing "Cut". - if (web_event.windows_key_code == VKEY_X && - ExecuteEditCommand("Cut", "")) { + // Ask the plugin if it can edit text before executing "Paste". + if (web_event.windows_key_code == VKEY_V && web_plugin_->CanEditText() && + ExecuteEditCommand("Paste", "")) { event->SetDefaultHandled(); return; } } - // Alternate shortcut for "Cut" is Shift + Delete. - if ((web_event.GetModifiers() & WebInputEvent::kInputModifiers) == - WebInputEvent::kShiftKey && - web_event.windows_key_code == VKEY_DELETE && - web_plugin_->HasSelection() && ExecuteEditCommand("Cut", "")) { - event->SetDefaultHandled(); - return; + // Alternate shortcuts for "Cut" and "Paste" are Shift + Delete and Shift + + // Insert, respectively. + else if (input_modifiers == WebInputEvent::kShiftKey) { + if (web_event.windows_key_code == VKEY_DELETE && + web_plugin_->HasSelection() && ExecuteEditCommand("Cut", "")) { + event->SetDefaultHandled(); + return; + } + if (web_event.windows_key_code == VKEY_INSERT && + web_plugin_->CanEditText() && ExecuteEditCommand("Paste", "")) { + event->SetDefaultHandled(); + return; + } } }
diff --git a/third_party/WebKit/Source/core/exported/WebPluginContainerTest.cpp b/third_party/WebKit/Source/core/exported/WebPluginContainerTest.cpp index c9056f7e..189dce59 100644 --- a/third_party/WebKit/Source/core/exported/WebPluginContainerTest.cpp +++ b/third_party/WebKit/Source/core/exported/WebPluginContainerTest.cpp
@@ -138,12 +138,12 @@ TestPluginWebFrameClient* const test_client_; }; -// Subclass of FakeWebPlugin used for testing the Cut edit command, so -// HasSelection() and CanEditText() return true by default. +// Subclass of FakeWebPlugin used for testing edit commands, so HasSelection() +// and CanEditText() return true by default. class TestPluginWithEditableText : public FakeWebPlugin { public: explicit TestPluginWithEditableText(const WebPluginParams& params) - : FakeWebPlugin(params), cut_called_(false) {} + : FakeWebPlugin(params), cut_called_(false), paste_called_(false) {} bool HasSelection() const override { return true; } bool CanEditText() const override { return true; } @@ -153,16 +153,25 @@ cut_called_ = true; return true; } + if (name == "Paste") { + paste_called_ = true; + return true; + } return false; } bool IsCutCalled() const { return cut_called_; } - void ResetCutStatus() { cut_called_ = false; } + bool IsPasteCalled() const { return paste_called_; } + void ResetEditCommandState() { + cut_called_ = false; + paste_called_ = false; + } private: ~TestPluginWithEditableText() override {} bool cut_called_; + bool paste_called_; }; class TestPluginWebFrameClient : public FrameTestHelpers::TestWebFrameClient { @@ -532,7 +541,7 @@ EXPECT_TRUE(test_plugin->IsCutCalled()); // Reset Cut status for next time. - test_plugin->ResetCutStatus(); + test_plugin->ResetEditCommandState(); modifier_key = static_cast<WebInputEvent::Modifiers>( WebInputEvent::kShiftKey | WebInputEvent::kNumLockOn | @@ -545,6 +554,59 @@ EXPECT_TRUE(test_plugin->IsCutCalled()); } +// Verifies |Ctrl-V| and |Shift-Insert| keyboard events, results in the "Paste" +// command being invoked. +TEST_F(WebPluginContainerTest, PasteInsertKeyboardEventsTest) { + RegisterMockedURL("plugin_container.html"); + // Must outlive |web_view_helper|. + TestPluginWebFrameClient plugin_web_frame_client; + FrameTestHelpers::WebViewHelper web_view_helper; + + // Use TestPluginWithEditableText for testing "Paste". + plugin_web_frame_client.SetHasEditableText(true); + + WebViewBase* web_view = web_view_helper.InitializeAndLoad( + base_url_ + "plugin_container.html", &plugin_web_frame_client); + EnablePlugins(web_view, WebSize(300, 300)); + + WebElement plugin_container_one_element = + web_view->MainFrameImpl()->GetDocument().GetElementById( + WebString::FromUTF8("translated-plugin")); + + WebPlugin* plugin = + ToWebPluginContainerImpl(plugin_container_one_element.PluginContainer()) + ->Plugin(); + TestPluginWithEditableText* test_plugin = + static_cast<TestPluginWithEditableText*>(plugin); + + WebInputEvent::Modifiers modifier_key = static_cast<WebInputEvent::Modifiers>( + WebInputEvent::kControlKey | WebInputEvent::kNumLockOn | + WebInputEvent::kIsLeft); +#if defined(OS_MACOSX) + modifier_key = static_cast<WebInputEvent::Modifiers>( + WebInputEvent::kMetaKey | WebInputEvent::kNumLockOn | + WebInputEvent::kIsLeft); +#endif + CreateAndHandleKeyboardEvent(&plugin_container_one_element, modifier_key, + VKEY_V); + + // Check that "Paste" command is invoked. + EXPECT_TRUE(test_plugin->IsPasteCalled()); + + // Reset Paste status for next time. + test_plugin->ResetEditCommandState(); + + modifier_key = static_cast<WebInputEvent::Modifiers>( + WebInputEvent::kShiftKey | WebInputEvent::kNumLockOn | + WebInputEvent::kIsLeft); + + CreateAndHandleKeyboardEvent(&plugin_container_one_element, modifier_key, + VKEY_INSERT); + + // Check that "Paste" command is invoked. + EXPECT_TRUE(test_plugin->IsPasteCalled()); +} + // A class to facilitate testing that events are correctly received by plugins. class EventTestPlugin : public FakeWebPlugin { public:
diff --git a/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.cpp b/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.cpp index bd1285dc..c0685815 100644 --- a/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.cpp
@@ -200,12 +200,20 @@ DCHECK(document_->GetFrame()); DCHECK(document_->GetFrame()->View()); - LocalFrameView* view = + LocalFrameView* child_view = ToLocalFrameView(frame_owner.OwnedEmbeddedContentView()); - view->UpdateGeometry(); + + // We can get here as a result of the "post layout resize" on the main frame. + // That happens from inside LocalFrameView::PerformLayout. Calling + // UpdateGeometry on the iframe causes it to layout which calls + // Document::UpdateStyleAndLayout. That tries to recurse up the hierarchy, + // reentering Layout on this Document. Thus, we avoid calling this here if + // we're in layout; it'll get called when this Document finishes laying out. + if (!document_->GetFrame()->View()->IsInPerformLayout()) + child_view->UpdateGeometry(); if (&EffectiveRootScroller() == frame_owner) - view->SetLayoutSize(document_->GetFrame()->View()->GetLayoutSize()); + child_view->SetLayoutSize(document_->GetFrame()->View()->GetLayoutSize()); } PaintLayer* RootScrollerController::RootScrollerPaintLayer() const {
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp index 43ccd2a..3923d54ba 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
@@ -90,7 +90,7 @@ DCHECK(!RuntimeEnabledFeatures::RootLayerScrollingEnabled()); auto element_id = CompositorElementIdFromLayoutObjectId( frame_view.GetLayoutView()->UniqueId(), - CompositorElementIdNamespace::kScrollTranslation); + CompositorElementIdNamespace::kScroll); if (auto* existing_scroll = frame_view.ScrollNode()) { auto existing_reasons = existing_scroll->GetMainThreadScrollingReasons(); existing_scroll->Update( @@ -1019,7 +1019,7 @@ } auto element_id = CompositorElementIdFromLayoutObjectId( - object.UniqueId(), CompositorElementIdNamespace::kScrollTranslation); + object.UniqueId(), CompositorElementIdNamespace::kScroll); // TODO(pdr): Set the correct compositing reasons here. auto result = properties.UpdateScroll(
diff --git a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp index 26731351..6fd3de4 100644 --- a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp +++ b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
@@ -644,10 +644,6 @@ return; } - TRACE_EVENT_BEGIN0("gpu", "VRDisplay::Flush_1"); - context_gl_->Flush(); - TRACE_EVENT_END0("gpu", "VRDisplay::Flush_1"); - // Check if the canvas got resized, if yes send a bounds update. int current_width = rendering_context_->drawingBufferWidth(); int current_height = rendering_context_->drawingBufferHeight(); @@ -679,18 +675,26 @@ } } - TRACE_EVENT_BEGIN0("gpu", "VRDisplay::GetImage"); - RefPtr<Image> image_ref = rendering_context_->GetImage( - kPreferAcceleration, kSnapshotReasonCreateImageBitmap); - TRACE_EVENT_END0("gpu", "VRDisplay::GetImage"); + TRACE_EVENT_BEGIN0("gpu", "VRDisplay::GetStaticBitmapImage"); + RefPtr<Image> image_ref = rendering_context_->GetStaticBitmapImage(); + TRACE_EVENT_END0("gpu", "VRDisplay::GetStaticBitmapImage"); // Hardware-accelerated rendering should always be texture backed, // as implemented by AcceleratedStaticBitmapImage. Ensure this is // the case, don't attempt to render if using an unexpected drawing // path. if (!image_ref.Get() || !image_ref->IsTextureBacked()) { - NOTREACHED() << "WebVR requires hardware-accelerated rendering to texture"; - return; + TRACE_EVENT0("gpu", "VRDisplay::GetImage_SlowFallback"); + // We get a non-texture-backed image when running layout tests + // on desktop builds. Add a slow fallback so that these continue + // working. + image_ref = rendering_context_->GetImage(kPreferAcceleration, + kSnapshotReasonCreateImageBitmap); + if (!image_ref.Get() || !image_ref->IsTextureBacked()) { + NOTREACHED() + << "WebVR requires hardware-accelerated rendering to texture"; + return; + } } // The AcceleratedStaticBitmapImage must be kept alive until the @@ -712,11 +716,6 @@ TRACE_EVENT_BEGIN0("gpu", "VRDisplay::GetMailbox"); auto mailbox = static_image->GetMailbox(); TRACE_EVENT_END0("gpu", "VRDisplay::GetMailbox"); - // Flush to avoid black screen flashes which appear to be related to - // "fence sync must be flushed before generating sync token" GL errors. - TRACE_EVENT_BEGIN0("gpu", "VRDisplay::Flush_2"); - context_gl_->Flush(); - TRACE_EVENT_END0("gpu", "VRDisplay::Flush_2"); auto sync_token = static_image->GetSyncToken(); // Wait for the previous render to finish, to avoid losing frames in the
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp index e8b8cc1..bdb0c063 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -726,16 +726,7 @@ exception_state); } - RefPtr<StaticBitmapImage> image; - if (CreationAttributes().preserveDrawingBuffer()) { - SkImageInfo image_info = - SkImageInfo::Make(width, height, kRGBA_8888_SkColorType, - CreationAttributes().alpha() ? kPremul_SkAlphaType - : kOpaque_SkAlphaType); - image = MakeImageSnapshot(image_info); - } else { - image = GetDrawingBuffer()->TransferToStaticBitmapImage(); - } + RefPtr<StaticBitmapImage> image = GetStaticBitmapImage(); return host()->Commit( std::move(image), SkIRect::MakeWH(width, height), @@ -743,6 +734,23 @@ script_state, exception_state); } +PassRefPtr<StaticBitmapImage> +WebGLRenderingContextBase::GetStaticBitmapImage() { + if (!GetDrawingBuffer()) + return nullptr; + + if (CreationAttributes().preserveDrawingBuffer()) { + int width = GetDrawingBuffer()->Size().Width(); + int height = GetDrawingBuffer()->Size().Height(); + SkImageInfo image_info = + SkImageInfo::Make(width, height, kRGBA_8888_SkColorType, + CreationAttributes().alpha() ? kPremul_SkAlphaType + : kOpaque_SkAlphaType); + return MakeImageSnapshot(image_info); + } + return GetDrawingBuffer()->TransferToStaticBitmapImage(); +} + RefPtr<StaticBitmapImage> WebGLRenderingContextBase::GetImage( AccelerationHint hint, SnapshotReason reason) const {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h index 0bfea30..5e0b7952 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
@@ -598,6 +598,10 @@ // This clears the backbuffer if preserveDrawingBuffer is false. void MarkCompositedAndClearBackbufferIfNeeded(); + // For use by WebVR, commits the current canvas content similar + // to the "commit" JS API. + PassRefPtr<StaticBitmapImage> GetStaticBitmapImage(); + protected: friend class EXTDisjointTimerQuery; friend class EXTDisjointTimerQueryWebGL2;
diff --git a/third_party/WebKit/Source/platform/graphics/CompositorElementId.cpp b/third_party/WebKit/Source/platform/graphics/CompositorElementId.cpp index 0464e68..967f4807 100644 --- a/third_party/WebKit/Source/platform/graphics/CompositorElementId.cpp +++ b/third_party/WebKit/Source/platform/graphics/CompositorElementId.cpp
@@ -29,8 +29,7 @@ DCHECK(namespace_id == CompositorElementIdNamespace::kPrimary || namespace_id == CompositorElementIdNamespace::kScroll || namespace_id == CompositorElementIdNamespace::kEffectFilter || - namespace_id == CompositorElementIdNamespace::kEffectMask || - namespace_id == CompositorElementIdNamespace::kScrollTranslation); + namespace_id == CompositorElementIdNamespace::kEffectMask); return CreateCompositorElementId(id, namespace_id); }
diff --git a/third_party/WebKit/Source/platform/graphics/CompositorElementId.h b/third_party/WebKit/Source/platform/graphics/CompositorElementId.h index 1908877f..2ada044 100644 --- a/third_party/WebKit/Source/platform/graphics/CompositorElementId.h +++ b/third_party/WebKit/Source/platform/graphics/CompositorElementId.h
@@ -27,7 +27,6 @@ kEffectFilter, kEffectMask, kEffectRoot, - kScrollTranslation, // A sentinel to indicate the maximum representable namespace id // (the maximum is one less than this value). kMaxRepresentableNamespaceId = 1 << kCompositorNamespaceBitCount
diff --git a/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.cpp index cd297127e..8e1f8e92 100644 --- a/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.cpp +++ b/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.cpp
@@ -103,7 +103,7 @@ GraphicsLayer::RegisterContentsLayer(web_layer_.get()); } -void SurfaceLayerBridge::OnSurfaceCreated( +void SurfaceLayerBridge::OnFirstSurfaceActivation( const viz::SurfaceInfo& surface_info) { if (!current_surface_id_.is_valid() && surface_info.is_valid()) { // First time a SurfaceId is received
diff --git a/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.h b/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.h index 9647aff..0541816a 100644 --- a/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.h +++ b/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.h
@@ -47,7 +47,7 @@ void CreateSolidColorLayer(); // Implementation of blink::mojom::blink::OffscreenCanvasSurfaceClient - void OnSurfaceCreated(const viz::SurfaceInfo&) override; + void OnFirstSurfaceActivation(const viz::SurfaceInfo&) override; void SatisfyCallback(const viz::SurfaceSequence&); void RequireCallback(const viz::SurfaceId&, const viz::SurfaceSequence&);
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp index cbcc572..5e7afc1 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
@@ -149,6 +149,11 @@ .get(); } + CompositorElementId ScrollElementId(unsigned id) { + return CompositorElementIdFromLayoutObjectId( + id, CompositorElementIdNamespace::kScroll); + } + void AddSimpleRectChunk(TestPaintArtifact& artifact) { artifact .Chunk(TransformPaintPropertyNode::Root(), @@ -729,7 +734,7 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, OneScrollNode) { FakeScrollClient scroll_client; - CompositorElementId expected_compositor_element_id = CompositorElementId(2); + CompositorElementId expected_compositor_element_id = ScrollElementId(2); RefPtr<ScrollPaintPropertyNode> scroll = ScrollPaintPropertyNode::Create( ScrollPaintPropertyNode::Root(), IntPoint(), IntSize(11, 13), IntSize(27, 31), true, false, 0 /* mainThreadScrollingReasons */, @@ -838,7 +843,7 @@ RefPtr<EffectPaintPropertyNode> effect = CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.5); - CompositorElementId expected_compositor_element_id_a = CompositorElementId(2); + CompositorElementId expected_compositor_element_id_a = ScrollElementId(2); RefPtr<ScrollPaintPropertyNode> scroll_a = ScrollPaintPropertyNode::Create( ScrollPaintPropertyNode::Root(), IntPoint(), IntSize(2, 3), IntSize(5, 7), false, true, @@ -851,7 +856,7 @@ kCompositingReasonLayerForScrollingContents, CompositorElementId(), scroll_a); - CompositorElementId expected_compositor_element_id_b = CompositorElementId(3); + CompositorElementId expected_compositor_element_id_b = ScrollElementId(3); RefPtr<ScrollPaintPropertyNode> scroll_b = ScrollPaintPropertyNode::Create( scroll_translation_a->ScrollNode(), IntPoint(), IntSize(19, 23), IntSize(29, 31), true, false, 0 /* mainThreadScrollingReasons */,
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.h b/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.h index b13eb8b..e09e370 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.h +++ b/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.h
@@ -82,6 +82,7 @@ user_scrollable_vertical_ = user_scrollable_vertical; main_thread_scrolling_reasons_ = main_thread_scrolling_reasons; compositor_element_id_ = compositor_element_id; + DCHECK(ElementIdNamespaceIsForScrolling()); scroll_client_ = scroll_client; return true; } @@ -171,7 +172,15 @@ user_scrollable_vertical_(user_scrollable_vertical), main_thread_scrolling_reasons_(main_thread_scrolling_reasons), compositor_element_id_(compositor_element_id), - scroll_client_(scroll_client) {} + scroll_client_(scroll_client) { + DCHECK(ElementIdNamespaceIsForScrolling()); + } + + bool ElementIdNamespaceIsForScrolling() const { + return !compositor_element_id_ || + NamespaceFromCompositorElementId(compositor_element_id_) == + CompositorElementIdNamespace::kScroll; + } IntPoint bounds_offset_; IntSize container_bounds_;
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git.py index 7238111..648e19dd 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git.py
@@ -27,7 +27,6 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import datetime import logging import re @@ -120,12 +119,6 @@ return executive.run_command( [cls.executable_name, 'config', '--get-all', key], error_handler=Executive.ignore_error, cwd=cwd).rstrip('\n') - def _discard_local_commits(self): - self.run(['reset', '--hard', self._remote_branch_ref()]) - - def _rebase_in_progress(self): - return self._filesystem.exists(self.absolute_path(self._filesystem.join('.git', 'rebase-apply'))) - def has_working_directory_changes(self, pathspec=None): """Checks whether there are uncommitted changes.""" command = ['diff', 'HEAD', '--no-renames', '--name-only'] @@ -133,13 +126,6 @@ command.extend(['--', pathspec]) return self.run(command) != '' - def _discard_working_directory_changes(self): - # TODO(qyearsley): Could run git clean here too; this wasn't done - # before in order to match svn, but this is no longer a concern. - self.run(['reset', 'HEAD', '--hard']) - if self._rebase_in_progress(): - self.run(['rebase', '--abort']) - def unstaged_changes(self): """Lists files with unstaged changes, including untracked files. @@ -185,14 +171,6 @@ return '' return self._branch_from_ref(ref) - def current_branch_or_ref(self): - """Returns the name of the current branch, or the commit hash if HEAD is detached.""" - branch_name = self.current_branch() - if not branch_name: - # HEAD is detached; use commit SHA instead. - return self.run(['rev-parse', 'HEAD']).strip() - return branch_name - def _upstream_branch(self): current_branch = self.current_branch() return self._branch_from_ref(self.read_git_config( @@ -234,7 +212,6 @@ match = re.search(status_regexp, line) if not match: continue - # status = match.group('status') filename = match.group('filename') filenames.append(filename) return filenames @@ -267,7 +244,7 @@ return self._commit_position_from_git_log(git_log) def create_patch(self, git_commit=None, changed_files=None): - """Returns a byte array (str()) representing the patch file. + """Returns a byte array (str) representing the patch file. Patch files are effectively binary since they may contain files of multiple different encodings. @@ -282,7 +259,6 @@ '--no-renames', '--src-prefix=a/', '--dst-prefix=b/', - ] if order: command.append(order) @@ -305,20 +281,9 @@ git_log = self.git_commit_detail(git_commit) return self._commit_position_from_git_log(git_log) - def checkout_branch(self, name): - self.run(['checkout', '-q', name]) - - def create_clean_branch(self, name): - self.run(['checkout', '-q', '-b', name, self._remote_branch_ref()]) - - # Git-specific methods: def _branch_ref_exists(self, branch_ref): return self.run(['show-ref', '--quiet', '--verify', branch_ref], return_exit_code=True) == 0 - def delete_branch(self, branch_name): - if self._branch_ref_exists('refs/heads/' + branch_name): - self.run(['branch', '-D', branch_name]) - def _remote_merge_base(self): return self.run(['merge-base', self._remote_branch_ref(), 'HEAD']).strip() @@ -344,7 +309,3 @@ if format: args.append('--format=' + format) return self.run(args) - - def affected_files(self, commit): - output = self.run(['log', '-1', '--format=', '--name-only', commit]) - return output.strip().split('\n')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git_mock.py index 1a84e98..c7208a0 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git_mock.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git_mock.py
@@ -33,18 +33,6 @@ def current_branch(self): return 'mock-branch-name' - def current_branch_or_ref(self): - return 'mock-branch-name' - - def checkout_branch(self, name): - pass - - def create_clean_branch(self, name): - pass - - def delete_branch(self, name): - pass - def exists(self, path): # TestRealMain.test_real_main (and several other rebaseline tests) are sensitive to this return value. # We should make those tests more robust, but for now we just return True always (since no test needs otherwise).
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py index 2936d44..ad4d8808d 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py
@@ -207,19 +207,6 @@ return sorted(running_pids) - def process_dump(self): - ps_process = None - if sys.platform in 'win32': - ps_process = self.popen( - ['wmic', 'process', 'get', - 'ProcessId,ParentProcessId,CommandLine'], - stdout=self.PIPE, stderr=self.PIPE) - else: - ps_process = self.popen(['ps', 'aux'], stdout=self.PIPE, stderr=self.PIPE) - - stdout, _ = ps_process.communicate() - return [line.strip() for line in stdout.splitlines()] - def wait_limited(self, pid, limit_in_seconds=None, check_frequency_in_seconds=None): seconds_left = limit_in_seconds or 10 sleep_length = check_frequency_in_seconds or 1
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_mock.py index d366254..efb7e35 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_mock.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_mock.py
@@ -201,9 +201,6 @@ def map(self, thunk, arglist, processes=None): return map(thunk, arglist) - def process_dump(self): - return [] - @property def calls(self): # TODO(crbug.com/718456): Make self.full_calls always be an array of
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py index bac31dc8..c786b93 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py
@@ -281,11 +281,6 @@ """ return self._is_http_test(test_file) or self._is_perf_test(test_file) - def _test_is_expected_missing(self, test_file): - expectations = self._expectations.model().get_expectations(test_file) - return (test_expectations.MISSING in expectations or - test_expectations.NEEDS_MANUAL_REBASELINE in expectations) - def _test_is_slow(self, test_file): expectations = self._expectations.model().get_expectations(test_file) return (test_expectations.SLOW in expectations or
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/models/test_results.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/models/test_results.py index 30f2e55..3918b10 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/models/test_results.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/models/test_results.py
@@ -67,11 +67,5 @@ def __ne__(self, other): return not (self == other) - def has_failure_matching_types(self, *failure_classes): - for failure in self.failures: - if type(failure) in failure_classes: - return True - return False - def dumps(self): return cPickle.dumps(self)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py index 2876324..11fae00 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py
@@ -234,10 +234,6 @@ return 1 return max_locked_shards - def baseline_platform_dir(self): - """Returns the absolute path to the default (version-independent) platform-specific results.""" - return self._filesystem.join(self.layout_tests_dir(), 'platform', self.port_name) - def baseline_version_dir(self): """Returns the absolute path to the platform-and-version-specific results.""" baseline_search_paths = self.baseline_search_path()
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py index 40774ab3..65bbde0 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py
@@ -427,9 +427,6 @@ 'linux': ['precise', 'trusty'] } - def buildbot_archives_baselines(self): - return self._name != 'test-win-win7' - def _path_to_driver(self): # This routine shouldn't normally be called, but it is called by # the mock_drt Driver. We return something, but make sure it's useless.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_manifest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_manifest.py index 745c179..0afdf8d 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_manifest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_manifest.py
@@ -54,19 +54,6 @@ urls.update([item[0] for item in records]) return urls - @memoized - def all_wpt_tests(self): - # TODO(qyearsley): Rename this method to indicate that it - # returns wpt test file paths, which may not be "test names". - if 'items' not in self.raw_dict: - return [] - - all_tests = [] - for test_type in self.test_types: - for path_in_wpt in self.raw_dict['items'][test_type]: - all_tests.append(path_in_wpt) - return all_tests - def is_test_file(self, path_in_wpt): return self._items_for_path(path_in_wpt) is not None
diff --git a/third_party/WebKit/public/blink_typemaps.gni b/third_party/WebKit/public/blink_typemaps.gni index 26ee3c642..68996104 100644 --- a/third_party/WebKit/public/blink_typemaps.gni +++ b/third_party/WebKit/public/blink_typemaps.gni
@@ -4,7 +4,7 @@ typemaps = [ "//cc/ipc/begin_frame_args_for_blink.typemap", - "//cc/ipc/compositor_frame_for_blink.typemap", + "//services/viz/public/cpp/compositing/compositor_frame_for_blink.typemap", "//cc/ipc/frame_sink_id.typemap", "//cc/ipc/local_surface_id.typemap", "//cc/ipc/returned_resource.typemap",
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 92b7852f4..966de20 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
@@ -17,7 +17,7 @@ }; interface OffscreenCanvasSurfaceClient { - OnSurfaceCreated(cc.mojom.SurfaceInfo surface_info); + OnFirstSurfaceActivation(cc.mojom.SurfaceInfo surface_info); }; // Creates OffscreenCanvasSurface and CompositorFrameSink instances for use @@ -35,4 +35,4 @@ CreateCompositorFrameSink(cc.mojom.FrameSinkId frame_sink_id, viz.mojom.CompositorFrameSinkClient client, viz.mojom.CompositorFrameSink& sink); -}; \ No newline at end of file +};
diff --git a/third_party/zlib/google.patch b/third_party/zlib/0000-build.patch similarity index 100% rename from third_party/zlib/google.patch rename to third_party/zlib/0000-build.patch
diff --git a/third_party/zlib/simd.patch b/third_party/zlib/0001-simd.patch similarity index 100% rename from third_party/zlib/simd.patch rename to third_party/zlib/0001-simd.patch
diff --git a/third_party/zlib/0002-uninitializedcheck.patch b/third_party/zlib/0002-uninitializedcheck.patch new file mode 100644 index 0000000..0713c00 --- /dev/null +++ b/third_party/zlib/0002-uninitializedcheck.patch
@@ -0,0 +1,12 @@ +diff --git a/inflate.c b/inflate.c +index ac333e8c2eda..69b769a871b8 100644 +--- a/third_party/zlib/inflate.c ++++ b/third_party/zlib/inflate.c +@@ -228,6 +228,7 @@ int stream_size; + state->strm = strm; + state->window = Z_NULL; + state->mode = HEAD; /* to pass state test in inflateReset2() */ ++ state->check = adler32(0L, Z_NULL, 0); + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state);
diff --git a/third_party/zlib/README.chromium b/third_party/zlib/README.chromium index fe6bc10..8658580 100644 --- a/third_party/zlib/README.chromium +++ b/third_party/zlib/README.chromium
@@ -22,7 +22,9 @@ imported. - The contents of the google directory are original Chromium-specific additions. - - google.patch contains changes from the upstream version, mostly related to - the build. - - Intel SIMD optimisations from https://github.com/jtkukunas/zlib/ have been - integrated. These changes are reflected in simd.patch. + - 0000-build.patch: changes from the upstream version, mostly related to the + build. + - 0001-simd.patch: integrate Intel SIMD optimisations from + https://github.com/jtkukunas/zlib/ + - 0002-uninitializedcheck.patch: default-initialize state->check, see + crbug.com/697481
diff --git a/third_party/zlib/inflate.c b/third_party/zlib/inflate.c index ac333e8..69b769a8 100644 --- a/third_party/zlib/inflate.c +++ b/third_party/zlib/inflate.c
@@ -228,6 +228,7 @@ state->strm = strm; state->window = Z_NULL; state->mode = HEAD; /* to pass state test in inflateReset2() */ + state->check = adler32(0L, Z_NULL, 0); ret = inflateReset2(strm, windowBits); if (ret != Z_OK) { ZFREE(strm, state);
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 9af988a6..b0021aa 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -1131,6 +1131,11 @@ <int value="5" label="Second packaged app installed without showing"/> </enum> +<enum name="AppListFolderOpened"> + <int value="0" label="Original Folder Design"/> + <int value="1" label="Peeking App List Folder Design"/> +</enum> + <enum name="AppListPage"> <int value="0" label="APPS"/> <int value="1" label="SEARCH_RESULTS"/> @@ -1138,6 +1143,13 @@ <int value="3" label="CUSTOM_LAUNCHER_PAGE"/> </enum> +<enum name="AppListPeekingToFullscreenSource"> + <int value="0" label="Swiped Up On Launcher"/> + <int value="1" label="Clicked Expand Arrow"/> + <int value="2" label="Scrolled With Mousepad"/> + <int value="3" label="Scrolled With Mouse"/> +</enum> + <enum name="AppListSearchResult"> <int value="0" label="OMNIBOX"/> <int value="1" label="APP"/> @@ -1157,6 +1169,12 @@ <int value="3" label="RECOMMENDATION"/> </enum> +<enum name="AppListShowSource"> + <int value="0" label="Search Key"/> + <int value="1" label="Shelf Button"/> + <int value="2" label="Swipe Up From Shelf"/> +</enum> + <enum name="AppLoadedInTabSource"> <int value="0" label="SOURCE_APP"/> <int value="1" label="SOURCE_BACKGROUND_PAGE"/> @@ -34873,9 +34891,10 @@ <int value="2" label="Nothing found"/> <int value="3" label="Already prompted"/> <int value="4" label="Cleaner download failed"/> - <int value="5" label="Browser not available"/> + <int value="5" label="Browser not available (deprecated)"/> <int value="6" label="Not on idle state"/> <int value="7" label="IPC connection broken"/> + <int value="8" label="Waiting for browser"/> </enum> <enum name="SoftwareReporterPromptDialogResponse"> @@ -34886,6 +34905,12 @@ <int value="4" label="Closed without user interaction"/> </enum> +<enum name="SoftwareReporterPromptShownWithType"> + <int value="0" label="Legacy prompt shown"/> + <int value="1" label="On transition to infected state"/> + <int value="2" label="On browser window available"/> +</enum> + <enum name="SpareWebContentsStatus"> <int value="0" label="Created"/> <int value="1" label="Used"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index d689d635..17c509d 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -1617,6 +1617,14 @@ </summary> </histogram> +<histogram name="Apps.AppListFolderOpened" enum="AppListFolderOpened"> + <owner>newcomer@chromium.org</owner> + <summary> + The number of times folders are opened in the app list. This is logged when + the folder is clicked. + </summary> +</histogram> + <histogram name="Apps.AppListHowEnabled" enum="AppListEnableSource"> <owner>tapted@chromium.org</owner> <summary> @@ -1635,6 +1643,15 @@ </summary> </histogram> +<histogram name="Apps.AppListPeekingToFullscreenSource" + enum="AppListPeekingToFullscreenSource"> + <owner>newcomer@chromium.org</owner> + <summary> + The source which transitions the app list from Peeking to Fullscreen. This + is logged when the transition method is used. + </summary> +</histogram> + <histogram name="Apps.AppListSearchCommenced" units="searches"> <owner>tapted@chromium.org</owner> <summary> @@ -1676,6 +1693,14 @@ </summary> </histogram> +<histogram name="Apps.AppListShowSource" enum="AppListShowSource"> + <owner>newcomer@chromium.org</owner> + <summary> + The number of times the different sources for showing the app list are used. + This is logged when the app list is shown. + </summary> +</histogram> + <histogram name="Apps.AppListTimeToDiscover" units="ms"> <owner>tapted@chromium.org</owner> <summary> @@ -1711,6 +1736,18 @@ </summary> </histogram> +<histogram name="Apps.AppsInFolders" units="Apps"> +<!-- Name completed by histogram_suffixes + name="AppListFolderExperiment" --> + + <owner>newcomer@chromium.org</owner> + <summary> + The total number of apps in folders ignoring OEM folders. This is logged + each time the app list is initialized. The suffix denotes whether the + fullscreen app list feature has been enabled. + </summary> +</histogram> + <histogram name="Apps.NoteTakingApp.DefaultLaunchResult" enum="NoteTakingAppLaunchResult"> <owner>derat@chromium.org</owner> @@ -67183,6 +67220,14 @@ </summary> </histogram> +<histogram name="SBClientDownload.ZipFileContainsAppDirectory" enum="Boolean"> + <owner>jialiul@chromium.org</owner> + <summary> + A Mac-only metric that records whether a downloaded zip file contains an + .app directory, signifying the presence of installable software. + </summary> +</histogram> + <histogram name="SBClientDownload.ZipFileHasArchiveButNoExecutable" enum="Boolean"> <owner>mattm@chromium.org</owner> @@ -75169,12 +75214,26 @@ </histogram> <histogram name="SoftwareReporter.PromptShown" enum="Boolean"> + <obsolete> + Replaced 2017-08-01 with SoftwareReporter.PromptShownWithType. + </obsolete> <owner>ftirelo@chromium.org</owner> <summary> Whether the user has been prompted to run the Chrome Cleanup Tool. </summary> </histogram> +<histogram name="SoftwareReporter.PromptShownWithType" + enum="SoftwareReporterPromptShownWithType"> + <owner>ftirelo@chromium.org</owner> + <summary> + Whether the user has been prompted to run the Chrome Cleanup Tool and which + type of prompt has been shown. + + This is logged once a prompt is presented to the user. + </summary> +</histogram> + <histogram name="SoftwareReporter.PromptUsage" enum="SRTPromptUsage"> <owner>mad@chromium.org</owner> <summary>Usage of the Software Removal Tool (SRT) Prompt.</summary> @@ -90422,6 +90481,12 @@ <affected-histogram name="Startup.AppListFirstPaintWarmStart"/> </histogram_suffixes> +<histogram_suffixes name="AppListFolderExperiment" separator="."> + <suffix name="FullscreenAppListEnabled" label="Peeking Launcher Enabled"/> + <suffix name="FullscreenAppListDisabled" label="Peeking Launcher Disabled"/> + <affected-histogram name="Apps.AppsInFolders"/> +</histogram_suffixes> + <histogram_suffixes name="ArcUserTypes" separator="."> <suffix name="Managed" label="User with forced Play Store feature"/> <suffix name="Unmanaged" label="User with optional Play Store feature"/>
diff --git a/tools/perf/benchmarks/service_worker.py b/tools/perf/benchmarks/service_worker.py index 66d700d..a6845ea 100644 --- a/tools/perf/benchmarks/service_worker.py +++ b/tools/perf/benchmarks/service_worker.py
@@ -184,7 +184,6 @@ return StoryExpectations() -@benchmark.Disabled('android-webview') # http://crbug.com/653924 @benchmark.Owner(emails=['horo@chromium.org']) class ServiceWorkerMicroBenchmarkPerfTest(perf_benchmark.PerfBenchmark): """This test is a microbenchmark of service worker. @@ -200,11 +199,6 @@ def Name(cls): return 'service_worker.service_worker_micro_benchmark' - @classmethod - def ShouldDisable(cls, possible_browser): # http://crbug.com/597656 - return (possible_browser.browser_type == 'reference' and - possible_browser.platform.GetDeviceTypeName() == 'Nexus 5X') - def GetExpectations(self): class StoryExpectations(story.expectations.StoryExpectations): def SetExpectations(self):
diff --git a/tools/perf/benchmarks/smoothness.py b/tools/perf/benchmarks/smoothness.py index 435954a..fd404a7 100644 --- a/tools/perf/benchmarks/smoothness.py +++ b/tools/perf/benchmarks/smoothness.py
@@ -174,8 +174,6 @@ return StoryExpectations() -@benchmark.Disabled('win') # http://crbug.com/692663 -@benchmark.Disabled('android-webview') # http://crbug.com/653933 @benchmark.Owner(emails=['kbr@chromium.org', 'zmo@chromium.org']) class SmoothnessMaps(perf_benchmark.PerfBenchmark): page_set = page_sets.MapsPageSet @@ -191,8 +189,6 @@ return StoryExpectations() -@benchmark.Disabled('android', - 'mac') # crbug.com/567802 @benchmark.Owner(emails=['ssid@chromium.org']) class SmoothnessKeyDesktopMoveCases(_Smoothness): page_set = page_sets.KeyDesktopMoveCasesPageSet @@ -201,11 +197,6 @@ def Name(cls): return 'smoothness.key_desktop_move_cases' - @classmethod - def ShouldDisable(cls, possible_browser): # http://crbug.com/597656 - return (possible_browser.browser_type == 'reference' and - possible_browser.platform.GetOSName() == 'win') - def GetExpectations(self): class StoryExpectations(story_module.expectations.StoryExpectations): def SetExpectations(self): @@ -240,9 +231,6 @@ return StoryExpectations() -@benchmark.Disabled('android') # crbug.com/589580 -@benchmark.Disabled('android-reference') # crbug.com/588786 -@benchmark.Disabled('mac') # crbug.com/563615 @benchmark.Owner(emails=['alancutter@chromium.org']) class SmoothnessToughAnimationCases(_Smoothness): page_set = page_sets.ToughAnimationCasesPageSet @@ -576,8 +564,6 @@ return StoryExpectations() -@benchmark.Disabled('android') # http://crbug.com/531593 -@benchmark.Disabled('win') # http://crbug.com/652372 class SmoothnessToughImageDecodeCases(_Smoothness): page_set = page_sets.ToughImageDecodeCasesPageSet
diff --git a/tools/perf/benchmarks/start_with_ext.py b/tools/perf/benchmarks/start_with_ext.py index c251088..ce326122 100644 --- a/tools/perf/benchmarks/start_with_ext.py +++ b/tools/perf/benchmarks/start_with_ext.py
@@ -31,8 +31,6 @@ @benchmark.Enabled('has tabs') -@benchmark.Disabled('mac') # crbug.com/563424 -@benchmark.Disabled('win', 'linux', 'reference', 'android') class StartWithExtCold(_StartWithExt): """Measure time to start Chrome cold with extensions.""" options = {'pageset_repeat': 5} @@ -50,8 +48,6 @@ @benchmark.Enabled('has tabs') -@benchmark.Disabled('mac') # crbug.com/563424 -@benchmark.Disabled('win', 'linux', 'reference', 'android') class StartWithExtWarm(_StartWithExt): """Measure time to start Chrome warm with extensions.""" options = {'pageset_repeat': 20}
diff --git a/tools/perf/benchmarks/tracing.py b/tools/perf/benchmarks/tracing.py index 10d12c6d..c0f5bb4 100644 --- a/tools/perf/benchmarks/tracing.py +++ b/tools/perf/benchmarks/tracing.py
@@ -37,9 +37,6 @@ return StoryExpectations() -# TODO(ssid): Enable on reference builds once stable browser starts supporting -# background mode memory-infra. crbug.com/621195. -@benchmark.Disabled('reference') @benchmark.Owner(emails=['ssid@chromium.org']) class TracingWithBackgroundMemoryInfra(perf_benchmark.PerfBenchmark): """Measures the overhead of background memory-infra dumps"""
diff --git a/ui/android/delegated_frame_host_android.cc b/ui/android/delegated_frame_host_android.cc index 14a2a31e..7cc00f54 100644 --- a/ui/android/delegated_frame_host_android.cc +++ b/ui/android/delegated_frame_host_android.cc
@@ -202,7 +202,7 @@ support_->SetNeedsBeginFrame(needs_begin_frames); } -void DelegatedFrameHostAndroid::OnSurfaceCreated( +void DelegatedFrameHostAndroid::OnFirstSurfaceActivation( const viz::SurfaceInfo& surface_info) { // TODO(fsamuel): Once surface synchronization is turned on, the fallback // surface should be set here.
diff --git a/ui/android/delegated_frame_host_android.h b/ui/android/delegated_frame_host_android.h index 75a18fd..00a03ae 100644 --- a/ui/android/delegated_frame_host_android.h +++ b/ui/android/delegated_frame_host_android.h
@@ -95,7 +95,7 @@ void OnNeedsBeginFrames(bool needs_begin_frames) override; // viz::HostFrameSinkClient implementation. - void OnSurfaceCreated(const viz::SurfaceInfo& surface_info) override; + void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override; void CreateNewCompositorFrameSinkSupport();
diff --git a/ui/app_list/app_list_constants.cc b/ui/app_list/app_list_constants.cc index 80d62e83..6cf98b8e4 100644 --- a/ui/app_list/app_list_constants.cc +++ b/ui/app_list/app_list_constants.cc
@@ -152,6 +152,17 @@ const ui::ResourceBundle::FontStyle kItemTextFontStyle = ui::ResourceBundle::SmallFont; +// The UMA histogram that logs usage of the original and redesigned folders. +const char kAppListFolderOpenedHistogram[] = "Apps.AppListFolderOpened"; + +// The UMA histogram that logs how the app list transitions from peeking to +// fullscreen. +const char kAppListPeekingToFullscreenHistogram[] = + "Apps.AppListPeekingToFullscreen"; + +// The UMA histogram that logs how the app list is shown. +const char kAppListToggleMethodHistogram[] = "Apps.AppListShowSource"; + // The UMA histogram that logs which page gets opened by the user. const char kPageOpenedHistogram[] = "Apps.AppListPageOpened";
diff --git a/ui/app_list/app_list_constants.h b/ui/app_list/app_list_constants.h index d4cf5ed8..0efc7bd 100644 --- a/ui/app_list/app_list_constants.h +++ b/ui/app_list/app_list_constants.h
@@ -108,7 +108,39 @@ APP_LIST_EXPORT extern const ui::ResourceBundle::FontStyle kItemTextFontStyle; +// The different ways that the app list can transition from PEEKING to +// FULLSCREEN_ALL_APPS. This enum must not have its order altered as it is used +// in histograms. +enum AppListPeekingToFullscreenSource { + kSwipe = 0, + kExpandArrow = 1, + kMousepadScroll = 2, + kMousewheelScroll = 3, + kMaxPeekingToFullscreen = 4, +}; + +// The different ways the app list can be shown. This enum must not have its +// order altered as it is used in histograms. +enum AppListShowSource { + kSearchKey = 0, + kShelfButton = 1, + kSwipeFromShelf = 2, + kMaxAppListToggleMethod = 3, +}; + +// The two versions of folders. This enum must not have its order altered as it +// is used in histograms. +enum AppListFolderOpened { + kOldFolders = 0, + kFullscreenAppListFolders = 1, + kMaxFolderOpened = 2, +}; + +APP_LIST_EXPORT extern const char kAppListFolderOpenedHistogram[]; +APP_LIST_EXPORT extern const char kAppListPeekingToFullscreenHistogram[]; +APP_LIST_EXPORT extern const char kAppListToggleMethodHistogram[]; APP_LIST_EXPORT extern const char kPageOpenedHistogram[]; + APP_LIST_EXPORT extern const char kSearchResultOpenDisplayTypeHistogram[]; APP_LIST_EXPORT extern const char kSearchQueryLength[]; APP_LIST_EXPORT extern const char kSearchResultDistanceFromOrigin[];
diff --git a/ui/app_list/app_list_model.cc b/ui/app_list/app_list_model.cc index f7653e1..752aba0 100644 --- a/ui/app_list/app_list_model.cc +++ b/ui/app_list/app_list_model.cc
@@ -7,6 +7,8 @@ #include <string> #include <utility> +#include "base/metrics/histogram_macros.h" +#include "ui/app_list/app_list_features.h" #include "ui/app_list/app_list_folder_item.h" #include "ui/app_list/app_list_item.h" #include "ui/app_list/app_list_model_observer.h" @@ -26,7 +28,9 @@ top_level_item_list_->AddObserver(this); } -AppListModel::~AppListModel() { top_level_item_list_->RemoveObserver(this); } +AppListModel::~AppListModel() { + top_level_item_list_->RemoveObserver(this); +} void AppListModel::AddObserver(AppListModelObserver* observer) { observers_.AddObserver(observer); @@ -163,12 +167,10 @@ // Add the items to the new folder. target_item_ptr->set_position( - new_folder->item_list()->CreatePositionBefore( - syncer::StringOrdinal())); + new_folder->item_list()->CreatePositionBefore(syncer::StringOrdinal())); AddItemToFolderItemAndNotify(new_folder, std::move(target_item_ptr)); source_item_ptr->set_position( - new_folder->item_list()->CreatePositionBefore( - syncer::StringOrdinal())); + new_folder->item_list()->CreatePositionBefore(syncer::StringOrdinal())); AddItemToFolderItemAndNotify(new_folder, std::move(source_item_ptr)); return new_folder->id(); @@ -176,8 +178,8 @@ void AppListModel::MoveItemToFolder(AppListItem* item, const std::string& folder_id) { - DVLOG(2) << "MoveItemToFolder: " << folder_id - << " <- " << item->ToDebugString(); + DVLOG(2) << "MoveItemToFolder: " << folder_id << " <- " + << item->ToDebugString(); if (item->folder_id() == folder_id) return; AppListFolderItem* dest_folder = FindOrCreateFolderItem(folder_id); @@ -193,8 +195,8 @@ bool AppListModel::MoveItemToFolderAt(AppListItem* item, const std::string& folder_id, syncer::StringOrdinal position) { - DVLOG(2) << "MoveItemToFolderAt: " << folder_id - << "[" << position.ToDebugString() << "]" + DVLOG(2) << "MoveItemToFolderAt: " << folder_id << "[" + << position.ToDebugString() << "]" << " <- " << item->ToDebugString(); if (item->folder_id() == folder_id) return false; @@ -317,6 +319,27 @@ DeleteItem(folder_ids[i]); } +void AppListModel::RecordItemsInFoldersForUMA() { + int number_of_items_in_folders = 0; + for (size_t i = 0; i < top_level_item_list_->item_count(); i++) { + AppListItem* item = top_level_item_list_->item_at(i); + if (item->GetItemType() != AppListFolderItem::kItemType) + continue; + + AppListFolderItem* folder = static_cast<AppListFolderItem*>(item); + if (folder->folder_type() == AppListFolderItem::FOLDER_TYPE_OEM) + continue; // Don't count OEM folders. + number_of_items_in_folders += folder->item_list()->item_count(); + } + if (features::IsFullscreenAppListEnabled()) { + UMA_HISTOGRAM_COUNTS_100("Apps.AppsInFolders.FullscreenAppListEnabled", + number_of_items_in_folders); + } else { + UMA_HISTOGRAM_COUNTS_100("Apps.AppsInFolders.FullscreenAppListDisabled", + number_of_items_in_folders); + } +} + void AppListModel::SetCustomLauncherPageEnabled(bool enabled) { custom_launcher_page_enabled_ = enabled; for (auto& observer : observers_)
diff --git a/ui/app_list/app_list_model.h b/ui/app_list/app_list_model.h index 1d0644a7..18de509 100644 --- a/ui/app_list/app_list_model.h +++ b/ui/app_list/app_list_model.h
@@ -135,6 +135,10 @@ // is false, removes any non-OEM folders. void SetFoldersEnabled(bool folders_enabled); + // Records the number of items stored in folders for UMA, not counting OEM + // folders. + void RecordItemsInFoldersForUMA(); + // Sets whether or not the custom launcher page should be enabled. void SetCustomLauncherPageEnabled(bool enabled); bool custom_launcher_page_enabled() const {
diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc index 56e4442..8d959d4 100644 --- a/ui/app_list/views/app_list_main_view.cc +++ b/ui/app_list/views/app_list_main_view.cc
@@ -11,6 +11,7 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "base/message_loop/message_loop.h" +#include "base/metrics/histogram_macros.h" #include "base/profiler/scoped_tracker.h" #include "base/strings/string_util.h" #include "ui/app_list/app_list_constants.h" @@ -181,10 +182,13 @@ void AppListMainView::ActivateApp(AppListItem* item, int event_flags) { // TODO(jennyz): Activate the folder via AppListModel notification. - if (item->GetItemType() == AppListFolderItem::kItemType) + if (item->GetItemType() == AppListFolderItem::kItemType) { contents_view_->ShowFolderContent(static_cast<AppListFolderItem*>(item)); - else + UMA_HISTOGRAM_ENUMERATION(kAppListFolderOpenedHistogram, kOldFolders, + kMaxFolderOpened); + } else { item->Activate(event_flags); + } } void AppListMainView::CancelDragInActiveFolder() {
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc index e01e68e..0099119 100644 --- a/ui/app_list/views/app_list_view.cc +++ b/ui/app_list/views/app_list_view.cc
@@ -228,6 +228,7 @@ UMA_HISTOGRAM_TIMES("Apps.AppListCreationTime", base::Time::Now() - start_time); + app_list_main_view_->model()->RecordItemsInFoldersForUMA(); } void AppListView::SetBubbleArrow(views::BubbleBorder::Arrow arrow) { @@ -546,6 +547,8 @@ SetState(FULLSCREEN_SEARCH); break; case PEEKING: + UMA_HISTOGRAM_ENUMERATION(kAppListPeekingToFullscreenHistogram, + kSwipe, kMaxPeekingToFullscreen); SetState(FULLSCREEN_ALL_APPS); break; case CLOSED: @@ -830,6 +833,12 @@ case ui::ET_MOUSEWHEEL: SetState(event->AsMouseWheelEvent()->y_offset() < 0 ? FULLSCREEN_ALL_APPS : CLOSED); + if (app_list_state_ == FULLSCREEN_ALL_APPS) { + UMA_HISTOGRAM_ENUMERATION(kAppListPeekingToFullscreenHistogram, + kMousewheelScroll, kMaxPeekingToFullscreen); + } + // Return true unconditionally because all mousewheel events are large + // enough to transition the app list. return true; case ui::ET_SCROLL: case ui::ET_SCROLL_FLING_START: { @@ -837,6 +846,10 @@ kAppListMinScrollToSwitchStates) { SetState(event->AsScrollEvent()->y_offset() < 0 ? FULLSCREEN_ALL_APPS : CLOSED); + if (app_list_state_ == FULLSCREEN_ALL_APPS) { + UMA_HISTOGRAM_ENUMERATION(kAppListPeekingToFullscreenHistogram, + kMousepadScroll, kMaxPeekingToFullscreen); + } return true; } break;
diff --git a/ui/app_list/views/apps_container_view.cc b/ui/app_list/views/apps_container_view.cc index e297c919..ab652ab5 100644 --- a/ui/app_list/views/apps_container_view.cc +++ b/ui/app_list/views/apps_container_view.cc
@@ -84,8 +84,8 @@ void AppsContainerView::SetDragAndDropHostOfCurrentAppList( ApplicationDragAndDropHost* drag_and_drop_host) { apps_grid_view()->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host); - app_list_folder_view()->items_grid_view()-> - SetDragAndDropHostOfCurrentAppList(drag_and_drop_host); + app_list_folder_view()->items_grid_view()->SetDragAndDropHostOfCurrentAppList( + drag_and_drop_host); } void AppsContainerView::ReparentFolderItemTransit( @@ -230,8 +230,8 @@ // Get the active folder's icon bounds relative to AppsContainerView. AppListItemView* folder_item_view = apps_grid_view_->activated_folder_item_view(); - gfx::Rect to_grid_view = folder_item_view->ConvertRectToParent( - folder_item_view->GetIconBounds()); + gfx::Rect to_grid_view = + folder_item_view->ConvertRectToParent(folder_item_view->GetIconBounds()); gfx::Rect to_container = apps_grid_view_->ConvertRectToParent(to_grid_view); return FolderImage::GetTopIconsBounds(to_container);
diff --git a/ui/app_list/views/expand_arrow_view.cc b/ui/app_list/views/expand_arrow_view.cc index 9a1be87..2f013cb 100644 --- a/ui/app_list/views/expand_arrow_view.cc +++ b/ui/app_list/views/expand_arrow_view.cc
@@ -139,7 +139,8 @@ void ExpandArrowView::TransitToFullscreenAllAppsState() { UMA_HISTOGRAM_ENUMERATION(kPageOpenedHistogram, AppListModel::STATE_APPS, AppListModel::STATE_LAST); - + UMA_HISTOGRAM_ENUMERATION(kAppListPeekingToFullscreenHistogram, kExpandArrow, + kMaxPeekingToFullscreen); contents_view_->SetActiveState(AppListModel::STATE_APPS); app_list_view_->SetState(AppListView::FULLSCREEN_ALL_APPS); }
diff --git a/ui/app_list/views/search_box_view.cc b/ui/app_list/views/search_box_view.cc index 7f3f7a05..872b037 100644 --- a/ui/app_list/views/search_box_view.cc +++ b/ui/app_list/views/search_box_view.cc
@@ -65,6 +65,7 @@ constexpr int kSearchBoxBorderCornerRadiusSearchResult = 4; constexpr int kMicIconSize = 24; constexpr int kCloseIconSize = 24; +constexpr int kSearchBoxFocusBorderCornerRadius = 28; constexpr int kLightVibrantBlendAlpha = 0xE6; @@ -921,9 +922,9 @@ return; selected_ = selected; if (selected) { - SetBorder(views::CreateRoundedRectBorder( - kSearchBoxBorderWidth, kSearchBoxBorderCornerRadiusFullscreen, - kSearchBoxBorderColor)); + SetBorder(views::CreateRoundedRectBorder(kSearchBoxBorderWidth, + kSearchBoxFocusBorderCornerRadius, + kSearchBoxBorderColor)); } else { SetDefaultBorder(); }
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index bc61e1d6..3a64eaf4 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc
@@ -554,7 +554,8 @@ observer.OnCompositingStarted(this, start_time); } -void Compositor::OnSurfaceCreated(const viz::SurfaceInfo& surface_info) { +void Compositor::OnFirstSurfaceActivation( + const viz::SurfaceInfo& surface_info) { // TODO(fsamuel): Once surface synchronization is turned on, the fallback // surface should be set here. }
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h index 95d086f..f70914f 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h
@@ -390,7 +390,7 @@ void DidLoseLayerTreeFrameSink() override {} // viz::HostFrameSinkClient implementation. - void OnSurfaceCreated(const viz::SurfaceInfo& surface_info) override; + void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override; bool IsLocked() { return !active_locks_.empty(); }
diff --git a/ui/events/blink/event_with_callback.cc b/ui/events/blink/event_with_callback.cc index 39793f4e..132e081 100644 --- a/ui/events/blink/event_with_callback.cc +++ b/ui/events/blink/event_with_callback.cc
@@ -72,15 +72,28 @@ InputHandlerProxy::EventDisposition disposition, const LatencyInfo& latency, std::unique_ptr<DidOverscrollParams> did_overscroll_params) { - for (auto& original_event : original_events_) { - std::unique_ptr<DidOverscrollParams> did_overscroll_params_copy; - if (did_overscroll_params) { - did_overscroll_params_copy = - base::MakeUnique<DidOverscrollParams>(*did_overscroll_params); - } - std::move(original_event.callback_) - .Run(disposition, std::move(original_event.event_), latency, - std::move(did_overscroll_params)); + // |original_events_| could be empty if this is the scroll event extracted + // from the matrix multiplication. + if (original_events_.size() == 0) + return; + + // Ack the oldest event with original latency. + std::move(original_events_.front().callback_) + .Run(disposition, std::move(original_events_.front().event_), latency, + did_overscroll_params + ? base::MakeUnique<DidOverscrollParams>(*did_overscroll_params) + : nullptr); + original_events_.pop_front(); + + // Ack other events with coalesced latency to avoid redundant tracking. + LatencyInfo coalesced_latency = latency; + coalesced_latency.set_coalesced(); + for (auto& coalesced_event : original_events_) { + std::move(coalesced_event.callback_) + .Run(disposition, std::move(coalesced_event.event_), coalesced_latency, + did_overscroll_params + ? base::MakeUnique<DidOverscrollParams>(*did_overscroll_params) + : nullptr); } }
diff --git a/ui/events/blink/input_handler_proxy_unittest.cc b/ui/events/blink/input_handler_proxy_unittest.cc index 1c92b8ec..8666ffd 100644 --- a/ui/events/blink/input_handler_proxy_unittest.cc +++ b/ui/events/blink/input_handler_proxy_unittest.cc
@@ -541,6 +541,7 @@ void SetUp() override { bool wheel_scroll_latching_enabled = GetParam(); event_disposition_recorder_.clear(); + latency_info_recorder_.clear(); input_handler_proxy_ = base::MakeUnique<TestInputHandlerProxy>( &mock_input_handler_, &mock_client_, wheel_scroll_latching_enabled); if (input_handler_proxy_->compositor_event_queue_) @@ -603,6 +604,7 @@ const ui::LatencyInfo& latency_info, std::unique_ptr<ui::DidOverscrollParams> overscroll_params) { event_disposition_recorder_.push_back(event_disposition); + latency_info_recorder_.push_back(latency_info); } std::deque<std::unique_ptr<EventWithCallback>>& event_queue() { @@ -620,6 +622,7 @@ std::unique_ptr<TestInputHandlerProxy> input_handler_proxy_; testing::StrictMock<MockInputHandlerProxyClient> mock_client_; std::vector<InputHandlerProxy::EventDisposition> event_disposition_recorder_; + std::vector<ui::LatencyInfo> latency_info_recorder_; base::MessageLoop loop_; base::WeakPtrFactory<InputHandlerProxyEventQueueTest> weak_ptr_factory_; @@ -4122,6 +4125,38 @@ input_handler_proxy_->gesture_scroll_on_impl_thread_for_testing()); } +TEST_P(InputHandlerProxyEventQueueTest, CoalescedLatencyInfo) { + // Handle scroll on compositor. + cc::InputHandlerScrollResult scroll_result_did_scroll_; + scroll_result_did_scroll_.did_scroll = true; + + EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) + .WillOnce(testing::Return(kImplThreadScrollState)); + EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(1); + EXPECT_CALL( + mock_input_handler_, + ScrollBy(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0)))) + .WillOnce(testing::Return(scroll_result_did_scroll_)); + EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_)); + + HandleGestureEvent(WebInputEvent::kGestureScrollBegin); + HandleGestureEvent(WebInputEvent::kGestureScrollUpdate, -20); + HandleGestureEvent(WebInputEvent::kGestureScrollUpdate, -40); + HandleGestureEvent(WebInputEvent::kGestureScrollUpdate, -30); + HandleGestureEvent(WebInputEvent::kGestureScrollEnd); + input_handler_proxy_->DeliverInputForBeginFrame(); + + EXPECT_EQ(0ul, event_queue().size()); + // Should run callbacks for every original events. + EXPECT_EQ(5ul, event_disposition_recorder_.size()); + EXPECT_EQ(5ul, latency_info_recorder_.size()); + EXPECT_EQ(false, latency_info_recorder_[1].coalesced()); + // Coalesced events should have latency set to coalesced. + EXPECT_EQ(true, latency_info_recorder_[2].coalesced()); + EXPECT_EQ(true, latency_info_recorder_[3].coalesced()); + testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); +} + INSTANTIATE_TEST_CASE_P(AnimateInput, InputHandlerProxyTest, testing::ValuesIn(test_types));
diff --git a/chrome/browser/resources/options/info.svg b/ui/webui/resources/images/info.svg similarity index 100% rename from chrome/browser/resources/options/info.svg rename to ui/webui/resources/images/info.svg