diff --git a/DEPS b/DEPS index ddee0bc4..feb40e2b 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': 'df669811b16e317b307b335822c4c7c881c1d163', + 'skia_revision': 'fb49909acafba5e031b90a265a6ce059cda85019', # 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': '71c20abb86b91696bf5d96eadc5290d4c0c566f0', + 'v8_revision': '65ef03f8a0fb9bd4f2cfa9afe60ba312cbb3ea08', # 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': 'd4f2d777c7aa4d9454a74afe92ff17e13da62380', + 'catapult_revision': 'b4eb70c319cb0f38d1a7764e7d9fb56dc96f8bcf', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/ash/accelerators/exit_warning_handler.cc b/ash/accelerators/exit_warning_handler.cc index e240ec0..6e25bbe 100644 --- a/ash/accelerators/exit_warning_handler.cc +++ b/ash/accelerators/exit_warning_handler.cc
@@ -4,11 +4,11 @@ #include "ash/accelerators/exit_warning_handler.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/root_window_controller.h" #include "ash/shell.h" #include "ash/shell_delegate.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" @@ -100,13 +100,13 @@ state_ = WAIT_FOR_DOUBLE_PRESS; Show(); StartTimer(); - ShellPort::Get()->RecordUserMetricsAction(UMA_ACCEL_EXIT_FIRST_Q); + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_ACCEL_EXIT_FIRST_Q); break; case WAIT_FOR_DOUBLE_PRESS: state_ = EXITING; CancelTimer(); Hide(); - ShellPort::Get()->RecordUserMetricsAction(UMA_ACCEL_EXIT_SECOND_Q); + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_ACCEL_EXIT_SECOND_Q); Shell::Get()->shell_delegate()->Exit(); break; case EXITING:
diff --git a/ash/aura/shell_port_classic.cc b/ash/aura/shell_port_classic.cc index f669e5a..4772034 100644 --- a/ash/aura/shell_port_classic.cc +++ b/ash/aura/shell_port_classic.cc
@@ -15,11 +15,9 @@ #include "ash/keyboard/keyboard_ui.h" #include "ash/laser/laser_pointer_controller.h" #include "ash/magnifier/partial_magnification_controller.h" -#include "ash/metrics/task_switch_metrics_recorder.h" #include "ash/public/cpp/config.h" #include "ash/shared/immersive_fullscreen_controller.h" #include "ash/shell.h" -#include "ash/touch/touch_uma.h" #include "ash/virtual_keyboard_controller.h" #include "ash/wm/drag_window_resizer.h" #include "ash/wm/maximize_mode/maximize_mode_event_handler_aura.h" @@ -101,18 +99,6 @@ return Shell::Get()->cursor_manager()->IsMouseEventsEnabled(); } -void ShellPortClassic::RecordUserMetricsAction(UserMetricsAction action) { - Shell::Get()->metrics()->RecordUserMetricsAction(action); -} - -void ShellPortClassic::RecordGestureAction(GestureActionType action) { - TouchUMA::GetInstance()->RecordGestureAction(action); -} - -void ShellPortClassic::RecordTaskSwitchMetric(TaskSwitchSource source) { - Shell::Get()->metrics()->task_switch_metrics_recorder().OnTaskSwitch(source); -} - std::unique_ptr<WindowResizer> ShellPortClassic::CreateDragWindowResizer( std::unique_ptr<WindowResizer> next_window_resizer, wm::WindowState* window_state) {
diff --git a/ash/aura/shell_port_classic.h b/ash/aura/shell_port_classic.h index c007a69..2299cff1 100644 --- a/ash/aura/shell_port_classic.h +++ b/ash/aura/shell_port_classic.h
@@ -42,9 +42,6 @@ void SetCursorSize(ui::CursorSize cursor_size) override; void SetGlobalOverrideCursor(base::Optional<ui::CursorData> cursor) override; bool IsMouseEventsEnabled() override; - void RecordGestureAction(GestureActionType action) override; - void RecordUserMetricsAction(UserMetricsAction action) override; - void RecordTaskSwitchMetric(TaskSwitchSource source) override; std::unique_ptr<WindowResizer> CreateDragWindowResizer( std::unique_ptr<WindowResizer> next_window_resizer, wm::WindowState* window_state) override;
diff --git a/ash/frame/caption_buttons/frame_caption_button_container_view.cc b/ash/frame/caption_buttons/frame_caption_button_container_view.cc index 7f529cd..730cee9 100644 --- a/ash/frame/caption_buttons/frame_caption_button_container_view.cc +++ b/ash/frame/caption_buttons/frame_caption_button_container_view.cc
@@ -9,8 +9,9 @@ #include "ash/frame/caption_buttons/frame_caption_button.h" #include "ash/frame/caption_buttons/frame_size_button.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/shell.h" -#include "ash/shell_port.h" +#include "ash/touch/touch_uma.h" #include "ash/wm/maximize_mode/maximize_mode_controller.h" #include "ui/base/hit_test.h" #include "ui/base/l10n/l10n_util.h" @@ -334,7 +335,7 @@ } if (event.IsGestureEvent()) - ShellPort::Get()->RecordGestureAction(GESTURE_FRAMEMAXIMIZE_TAP); + TouchUMA::GetInstance()->RecordGestureAction(GESTURE_FRAMEMAXIMIZE_TAP); } else if (sender == close_button_) { frame_->Close(); action = UMA_WINDOW_CLOSE_BUTTON_CLICK; @@ -346,7 +347,7 @@ } else { return; } - ShellPort::Get()->RecordUserMetricsAction(action); + Shell::Get()->metrics()->RecordUserMetricsAction(action); } bool FrameCaptionButtonContainerView::IsMinimizeButtonVisible() const {
diff --git a/ash/frame/caption_buttons/frame_size_button.cc b/ash/frame/caption_buttons/frame_size_button.cc index 5da8501..071a6c0 100644 --- a/ash/frame/caption_buttons/frame_size_button.cc +++ b/ash/frame/caption_buttons/frame_size_button.cc
@@ -4,7 +4,8 @@ #include "ash/frame/caption_buttons/frame_size_button.h" -#include "ash/shell_port.h" +#include "ash/metrics/user_metrics_recorder.h" +#include "ash/shell.h" #include "ash/wm/window_positioning_utils.h" #include "ash/wm/window_state.h" #include "ash/wm/wm_event.h" @@ -251,7 +252,7 @@ ? wm::WM_EVENT_SNAP_LEFT : wm::WM_EVENT_SNAP_RIGHT); window_state->OnWMEvent(&snap_event); - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( snap_type_ == SNAP_LEFT ? UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_LEFT : UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_RIGHT); SetButtonsToNormalMode(FrameSizeButtonDelegate::ANIMATE_NO);
diff --git a/ash/metrics/desktop_task_switch_metric_recorder.cc b/ash/metrics/desktop_task_switch_metric_recorder.cc index e93f51e..4d9cda0 100644 --- a/ash/metrics/desktop_task_switch_metric_recorder.cc +++ b/ash/metrics/desktop_task_switch_metric_recorder.cc
@@ -4,8 +4,8 @@ #include "ash/metrics/desktop_task_switch_metric_recorder.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/wm/window_util.h" #include "ui/wm/public/activation_client.h" @@ -28,7 +28,7 @@ if (last_active_task_window_ != gained_active && reason == ::wm::ActivationChangeObserver::ActivationReason::INPUT_EVENT) { - ShellPort::Get()->RecordUserMetricsAction(UMA_DESKTOP_SWITCH_TASK); + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_DESKTOP_SWITCH_TASK); } last_active_task_window_ = gained_active; }
diff --git a/ash/mus/bridge/shell_port_mash.cc b/ash/mus/bridge/shell_port_mash.cc index 965c70f..1e74a19 100644 --- a/ash/mus/bridge/shell_port_mash.cc +++ b/ash/mus/bridge/shell_port_mash.cc
@@ -31,7 +31,6 @@ #include "ash/shared/immersive_fullscreen_controller.h" #include "ash/shell.h" #include "ash/system/tray/system_tray_delegate.h" -#include "ash/touch/touch_uma.h" #include "ash/virtual_keyboard_controller.h" #include "ash/wallpaper/wallpaper_delegate.h" #include "ash/wm/drag_window_resizer.h" @@ -163,34 +162,6 @@ return true; } -void ShellPortMash::RecordGestureAction(GestureActionType action) { - if (GetAshConfig() == Config::MUS) { - TouchUMA::GetInstance()->RecordGestureAction(action); - return; - } - // TODO: http://crbug.com/616581. - NOTIMPLEMENTED(); -} - -void ShellPortMash::RecordUserMetricsAction(UserMetricsAction action) { - if (GetAshConfig() == Config::MUS) { - Shell::Get()->metrics()->RecordUserMetricsAction(action); - return; - } - // TODO: http://crbug.com/616581. - NOTIMPLEMENTED(); -} - -void ShellPortMash::RecordTaskSwitchMetric(TaskSwitchSource source) { - if (GetAshConfig() == Config::MUS) { - Shell::Get()->metrics()->task_switch_metrics_recorder().OnTaskSwitch( - source); - return; - } - // TODO: http://crbug.com/616581. - NOTIMPLEMENTED(); -} - std::unique_ptr<WindowResizer> ShellPortMash::CreateDragWindowResizer( std::unique_ptr<WindowResizer> next_window_resizer, wm::WindowState* window_state) {
diff --git a/ash/mus/bridge/shell_port_mash.h b/ash/mus/bridge/shell_port_mash.h index 83028f1..7f8160a 100644 --- a/ash/mus/bridge/shell_port_mash.h +++ b/ash/mus/bridge/shell_port_mash.h
@@ -67,9 +67,6 @@ void SetCursorSize(ui::CursorSize cursor_size) override; void SetGlobalOverrideCursor(base::Optional<ui::CursorData> cursor) override; bool IsMouseEventsEnabled() override; - void RecordGestureAction(GestureActionType action) override; - void RecordUserMetricsAction(UserMetricsAction action) override; - void RecordTaskSwitchMetric(TaskSwitchSource source) override; std::unique_ptr<WindowResizer> CreateDragWindowResizer( std::unique_ptr<WindowResizer> next_window_resizer, wm::WindowState* window_state) override;
diff --git a/ash/shelf/shelf_alignment_menu.cc b/ash/shelf/shelf_alignment_menu.cc index ccd8130..a5c6d07 100644 --- a/ash/shelf/shelf_alignment_menu.cc +++ b/ash/shelf/shelf_alignment_menu.cc
@@ -5,9 +5,10 @@ #include "ash/shelf/shelf_alignment_menu.h" #include "ash/metrics/user_metrics_action.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/shelf_types.h" #include "ash/shelf/shelf.h" -#include "ash/shell_port.h" +#include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" namespace ash { @@ -48,15 +49,18 @@ void ShelfAlignmentMenu::ExecuteCommand(int command_id, int event_flags) { switch (static_cast<MenuItem>(command_id)) { case MENU_ALIGN_LEFT: - ShellPort::Get()->RecordUserMetricsAction(UMA_SHELF_ALIGNMENT_SET_LEFT); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_SHELF_ALIGNMENT_SET_LEFT); shelf_->SetAlignment(SHELF_ALIGNMENT_LEFT); break; case MENU_ALIGN_BOTTOM: - ShellPort::Get()->RecordUserMetricsAction(UMA_SHELF_ALIGNMENT_SET_BOTTOM); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_SHELF_ALIGNMENT_SET_BOTTOM); shelf_->SetAlignment(SHELF_ALIGNMENT_BOTTOM); break; case MENU_ALIGN_RIGHT: - ShellPort::Get()->RecordUserMetricsAction(UMA_SHELF_ALIGNMENT_SET_RIGHT); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_SHELF_ALIGNMENT_SET_RIGHT); shelf_->SetAlignment(SHELF_ALIGNMENT_RIGHT); break; }
diff --git a/ash/shelf/shelf_button_pressed_metric_tracker.cc b/ash/shelf/shelf_button_pressed_metric_tracker.cc index 08a93e1..d7f29ff7 100644 --- a/ash/shelf/shelf_button_pressed_metric_tracker.cc +++ b/ash/shelf/shelf_button_pressed_metric_tracker.cc
@@ -4,7 +4,8 @@ #include "ash/shelf/shelf_button_pressed_metric_tracker.h" -#include "ash/shell_port.h" +#include "ash/metrics/user_metrics_recorder.h" +#include "ash/shell.h" #include "base/metrics/histogram_macros.h" #include "base/time/default_tick_clock.h" #include "ui/views/controls/button/button.h" @@ -48,10 +49,10 @@ void ShelfButtonPressedMetricTracker::RecordButtonPressedSource( const ui::Event& event) { if (event.IsMouseEvent()) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_LAUNCHER_BUTTON_PRESSED_WITH_MOUSE); } else if (event.IsGestureEvent()) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_LAUNCHER_BUTTON_PRESSED_WITH_TOUCH); } } @@ -63,13 +64,16 @@ case SHELF_ACTION_APP_LIST_SHOWN: break; case SHELF_ACTION_NEW_WINDOW_CREATED: - ShellPort::Get()->RecordUserMetricsAction(UMA_LAUNCHER_LAUNCH_TASK); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_LAUNCHER_LAUNCH_TASK); break; case SHELF_ACTION_WINDOW_ACTIVATED: - ShellPort::Get()->RecordUserMetricsAction(UMA_LAUNCHER_SWITCH_TASK); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_LAUNCHER_SWITCH_TASK); break; case SHELF_ACTION_WINDOW_MINIMIZED: - ShellPort::Get()->RecordUserMetricsAction(UMA_LAUNCHER_MINIMIZE_TASK); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_LAUNCHER_MINIMIZE_TASK); break; } }
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc index c11b9eb..acbef66d 100644 --- a/ash/shelf/shelf_view.cc +++ b/ash/shelf/shelf_view.cc
@@ -9,6 +9,7 @@ #include "ash/ash_constants.h" #include "ash/drag_drop/drag_image_view.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/config.h" #include "ash/public/cpp/shelf_item_delegate.h" #include "ash/public/cpp/shelf_model.h" @@ -442,11 +443,12 @@ case TYPE_PINNED_APP: case TYPE_BROWSER_SHORTCUT: case TYPE_APP: - ShellPort::Get()->RecordUserMetricsAction(UMA_LAUNCHER_CLICK_ON_APP); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_LAUNCHER_CLICK_ON_APP); break; case TYPE_APP_LIST: - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON); break;
diff --git a/ash/shell.cc b/ash/shell.cc index 97aa2e7..f647df2 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -628,8 +628,7 @@ const Config config = shell_port_->GetAshConfig(); - if (config != Config::MASH) - user_metrics_recorder_->OnShellShuttingDown(); + user_metrics_recorder_->OnShellShuttingDown(); shell_delegate_->PreShutdown(); @@ -1112,8 +1111,7 @@ for (auto& observer : shell_observers_) observer.OnShellInitialized(); - if (config != Config::MASH) - user_metrics_recorder_->OnShellInitialized(); + user_metrics_recorder_->OnShellInitialized(); } void Shell::InitRootWindow(aura::Window* root_window) {
diff --git a/ash/shell_port.h b/ash/shell_port.h index a4632615..c029491 100644 --- a/ash/shell_port.h +++ b/ash/shell_port.h
@@ -11,8 +11,6 @@ #include <vector> #include "ash/ash_export.h" -#include "ash/metrics/gesture_action_type.h" -#include "ash/metrics/user_metrics_action.h" #include "ash/wm/lock_state_observer.h" #include "base/observer_list.h" #include "base/optional.h" @@ -111,10 +109,6 @@ base::Optional<ui::CursorData> cursor) = 0; virtual bool IsMouseEventsEnabled() = 0; - virtual void RecordGestureAction(GestureActionType action) = 0; - virtual void RecordUserMetricsAction(UserMetricsAction action) = 0; - virtual void RecordTaskSwitchMetric(TaskSwitchSource source) = 0; - // Shows the context menu for the wallpaper or shelf at |location_in_screen|. void ShowContextMenu(const gfx::Point& location_in_screen, ui::MenuSourceType source_type);
diff --git a/ash/system/audio/tray_audio.cc b/ash/system/audio/tray_audio.cc index 0f3d880..ea3cd95 100644 --- a/ash/system/audio/tray_audio.cc +++ b/ash/system/audio/tray_audio.cc
@@ -4,10 +4,10 @@ #include "ash/system/audio/tray_audio.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/root_window_controller.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/system/audio/audio_detailed_view.h" #include "ash/system/audio/volume_view.h" #include "ash/system/tray/system_tray.h" @@ -69,7 +69,7 @@ volume_view_ = new tray::VolumeView(this, false); return volume_view_; } else { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_DETAILED_AUDIO_VIEW); audio_detail_view_ = new tray::AudioDetailedView(this); return audio_detail_view_;
diff --git a/ash/system/audio/volume_view.cc b/ash/system/audio/volume_view.cc index 1a7fad8..9dd9d15 100644 --- a/ash/system/audio/volume_view.cc +++ b/ash/system/audio/volume_view.cc
@@ -7,8 +7,9 @@ #include <algorithm> #include "ash/metrics/user_metrics_action.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/vector_icons/vector_icons.h" -#include "ash/shell_port.h" +#include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/tray/actionable_view.h" #include "ash/system/tray/system_tray_item.h" @@ -267,7 +268,7 @@ int current_volume = CrasAudioHandler::Get()->GetOutputVolumePercent(); if (new_volume == current_volume) return; - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( is_default_view_ ? UMA_STATUS_AREA_CHANGED_VOLUME_MENU : UMA_STATUS_AREA_CHANGED_VOLUME_POPUP); if (new_volume > current_volume)
diff --git a/ash/system/bluetooth/tray_bluetooth.cc b/ash/system/bluetooth/tray_bluetooth.cc index b665240..3a49c98 100644 --- a/ash/system/bluetooth/tray_bluetooth.cc +++ b/ash/system/bluetooth/tray_bluetooth.cc
@@ -9,9 +9,9 @@ #include <set> #include <string> +#include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/bluetooth/tray_bluetooth_helper.h" #include "ash/system/tray/hover_highlight_view.h" @@ -388,7 +388,7 @@ const ui::Event& event) override { if (sender == toggle_) { TrayBluetoothHelper* helper = Shell::Get()->tray_bluetooth_helper(); - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( helper->GetBluetoothEnabled() ? UMA_STATUS_AREA_BLUETOOTH_DISABLED : UMA_STATUS_AREA_BLUETOOTH_ENABLED); helper->ToggleBluetoothEnabled(); @@ -545,7 +545,7 @@ views::View* TrayBluetooth::CreateDetailedView(LoginStatus status) { if (!Shell::Get()->tray_bluetooth_helper()->GetBluetoothAvailable()) return nullptr; - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_DETAILED_BLUETOOTH_VIEW); CHECK(detailed_ == nullptr); detailed_ = new tray::BluetoothDetailedView(this, status);
diff --git a/ash/system/brightness/tray_brightness.cc b/ash/system/brightness/tray_brightness.cc index b4ad50f..b933437 100644 --- a/ash/system/brightness/tray_brightness.cc +++ b/ash/system/brightness/tray_brightness.cc
@@ -6,10 +6,10 @@ #include <algorithm> +#include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/shell_observer.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/brightness_control_delegate.h" #include "ash/system/tray/tray_constants.h" @@ -216,7 +216,7 @@ views::View* TrayBrightness::CreateDetailedView(LoginStatus status) { CHECK(brightness_view_ == nullptr); - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_DETAILED_BRIGHTNESS_VIEW); brightness_view_ = new tray::BrightnessView(false, current_percent_); return brightness_view_; @@ -239,7 +239,8 @@ } void TrayBrightness::BrightnessChanged(int level, bool user_initiated) { - ShellPort::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_BRIGHTNESS_CHANGED); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_STATUS_AREA_BRIGHTNESS_CHANGED); double percent = static_cast<double>(level); HandleBrightnessChanged(percent, user_initiated); }
diff --git a/ash/system/cast/tray_cast.cc b/ash/system/cast/tray_cast.cc index f0ea1cc..348bec8e 100644 --- a/ash/system/cast/tray_cast.cc +++ b/ash/system/cast/tray_cast.cc
@@ -9,10 +9,10 @@ #include <utility> #include <vector> +#include "ash/metrics/user_metrics_recorder.h" #include "ash/public/interfaces/cast_config.mojom.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/screen_security/screen_tray_item.h" #include "ash/system/tray/hover_highlight_view.h" @@ -129,7 +129,8 @@ void CastCastView::StopCasting() { Shell::Get()->cast_config()->StopCasting(displayed_route_.Clone()); - ShellPort::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_CAST_STOP_CAST); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_STATUS_AREA_CAST_STOP_CAST); } void CastCastView::UpdateLabel( @@ -401,7 +402,7 @@ auto it = view_to_sink_map_.find(view); if (it != view_to_sink_map_.end()) { Shell::Get()->cast_config()->CastToSink(it->second.Clone()); - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_DETAILED_CAST_VIEW_LAUNCH_CAST); } } @@ -458,7 +459,8 @@ } views::View* TrayCast::CreateDetailedView(LoginStatus status) { - ShellPort::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_DETAILED_CAST_VIEW); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_STATUS_AREA_DETAILED_CAST_VIEW); CHECK(detailed_ == nullptr); detailed_ = new tray::CastDetailedView(this, sinks_and_routes_); return detailed_;
diff --git a/ash/system/ime/tray_ime_chromeos.cc b/ash/system/ime/tray_ime_chromeos.cc index 26baa3b..a5b3e82 100644 --- a/ash/system/ime/tray_ime_chromeos.cc +++ b/ash/system/ime/tray_ime_chromeos.cc
@@ -8,9 +8,9 @@ #include <vector> #include "ash/ime/ime_controller.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/tray/system_tray.h" #include "ash/system/tray/system_tray_controller.h" @@ -128,7 +128,7 @@ } void ShowSettings() { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_IME_SHOW_DETAILED); Shell::Get()->system_tray_controller()->ShowIMESettings(); if (owner()->system_tray())
diff --git a/ash/system/ime_menu/ime_list_view.cc b/ash/system/ime_menu/ime_list_view.cc index 51f46ed..282e734f 100644 --- a/ash/system/ime_menu/ime_list_view.cc +++ b/ash/system/ime_menu/ime_list_view.cc
@@ -6,6 +6,7 @@ #include "ash/ime/ime_controller.h" #include "ash/ime/ime_switch_type.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/public/interfaces/ime_info.mojom.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" @@ -297,7 +298,8 @@ void ImeListView::HandleViewClicked(views::View* view) { std::map<views::View*, std::string>::const_iterator ime = ime_map_.find(view); if (ime != ime_map_.end()) { - ShellPort::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_IME_SWITCH_MODE); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_STATUS_AREA_IME_SWITCH_MODE); std::string ime_id = ime->second; last_selected_item_id_ = ime_id; InputMethodManager::Get()->GetActiveIMEState()->ChangeInputMethod(
diff --git a/ash/system/ime_menu/ime_menu_tray.cc b/ash/system/ime_menu/ime_menu_tray.cc index d41378ac..53c376e 100644 --- a/ash/system/ime_menu/ime_menu_tray.cc +++ b/ash/system/ime_menu/ime_menu_tray.cc
@@ -7,11 +7,11 @@ #include "ash/accessibility_delegate.h" #include "ash/ash_constants.h" #include "ash/ime/ime_controller.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/root_window_controller.h" #include "ash/session/session_controller.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/ime_menu/ime_list_view.h" #include "ash/system/tray/system_menu_button.h" @@ -56,7 +56,8 @@ // Shows language and input settings page. void ShowIMESettings() { - ShellPort::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_IME_SHOW_DETAILED); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_STATUS_AREA_IME_SHOW_DETAILED); Shell::Get()->system_tray_controller()->ShowIMESettings(); }
diff --git a/ash/system/keyboard_brightness_controller.cc b/ash/system/keyboard_brightness_controller.cc index 95af101..7fc3b16 100644 --- a/ash/system/keyboard_brightness_controller.cc +++ b/ash/system/keyboard_brightness_controller.cc
@@ -4,7 +4,8 @@ #include "ash/system/keyboard_brightness_controller.h" -#include "ash/shell_port.h" +#include "ash/metrics/user_metrics_recorder.h" +#include "ash/shell.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/power_manager_client.h" #include "ui/base/accelerators/accelerator.h" @@ -14,7 +15,7 @@ void KeyboardBrightnessController::HandleKeyboardBrightnessDown( const ui::Accelerator& accelerator) { if (accelerator.key_code() == ui::VKEY_BRIGHTNESS_DOWN) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_ACCEL_KEYBOARD_BRIGHTNESS_DOWN_F6); } @@ -26,7 +27,7 @@ void KeyboardBrightnessController::HandleKeyboardBrightnessUp( const ui::Accelerator& accelerator) { if (accelerator.key_code() == ui::VKEY_BRIGHTNESS_UP) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_ACCEL_KEYBOARD_BRIGHTNESS_UP_F7); }
diff --git a/ash/system/network/network_list.cc b/ash/system/network/network_list.cc index c87091d..34d04ff 100644 --- a/ash/system/network/network_list.cc +++ b/ash/system/network/network_list.cc
@@ -7,9 +7,9 @@ #include <memory> #include <utility> +#include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/network/network_icon.h" #include "ash/system/network/network_icon_animation.h" @@ -262,7 +262,7 @@ void ButtonPressed(views::Button* sender, const ui::Event& event) override { if (sender == join_) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_NETWORK_JOIN_OTHER_CLICKED); Shell::Get()->system_tray_controller()->ShowNetworkCreate( shill::kTypeWifi);
diff --git a/ash/system/network/network_state_list_detailed_view.cc b/ash/system/network/network_state_list_detailed_view.cc index 4aba214..2b103a59 100644 --- a/ash/system/network/network_state_list_detailed_view.cc +++ b/ash/system/network/network_state_list_detailed_view.cc
@@ -6,9 +6,9 @@ #include <algorithm> +#include "ash/metrics/user_metrics_recorder.h" #include "ash/session/session_controller.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/tray/system_menu_button.h" #include "ash/system/tray/system_tray.h" @@ -222,14 +222,14 @@ NetworkHandler::Get()->network_state_handler()->GetNetworkStateFromGuid( guid); if (!network || network->IsConnectedState() || network->IsConnectingState()) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( list_type_ == LIST_TYPE_VPN ? UMA_STATUS_AREA_SHOW_VPN_CONNECTION_DETAILS : UMA_STATUS_AREA_SHOW_NETWORK_CONNECTION_DETAILS); Shell::Get()->system_tray_controller()->ShowNetworkSettings( network ? network->guid() : std::string()); } else { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( list_type_ == LIST_TYPE_VPN ? UMA_STATUS_AREA_CONNECT_TO_VPN : UMA_STATUS_AREA_CONNECT_TO_CONFIGURED_NETWORK); @@ -272,7 +272,7 @@ } void NetworkStateListDetailedView::ShowSettings() { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( list_type_ == LIST_TYPE_VPN ? UMA_STATUS_AREA_VPN_SETTINGS_OPENED : UMA_STATUS_AREA_NETWORK_SETTINGS_OPENED); Shell::Get()->system_tray_controller()->ShowNetworkSettings(std::string());
diff --git a/ash/system/network/tray_network.cc b/ash/system/network/tray_network.cc index 6455d7357..b780785 100644 --- a/ash/system/network/tray_network.cc +++ b/ash/system/network/tray_network.cc
@@ -4,8 +4,8 @@ #include "ash/system/network/tray_network.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/network/network_icon.h" #include "ash/system/network/network_icon_animation.h" @@ -242,7 +242,7 @@ views::View* TrayNetwork::CreateDetailedView(LoginStatus status) { CHECK(detailed_ == nullptr); - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_DETAILED_NETWORK_VIEW); if (!chromeos::NetworkHandler::IsInitialized()) return nullptr; @@ -267,7 +267,7 @@ // This will always be triggered by a user action (e.g. keyboard shortcut) NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); bool enabled = handler->IsTechnologyEnabled(NetworkTypePattern::WiFi()); - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( enabled ? UMA_STATUS_AREA_DISABLE_WIFI : UMA_STATUS_AREA_ENABLE_WIFI); handler->SetTechnologyEnabled(NetworkTypePattern::WiFi(), !enabled, chromeos::network_handler::ErrorCallback());
diff --git a/ash/system/network/tray_vpn.cc b/ash/system/network/tray_vpn.cc index 8eadaf2a..6d9d5b4 100644 --- a/ash/system/network/tray_vpn.cc +++ b/ash/system/network/tray_vpn.cc
@@ -4,10 +4,10 @@ #include "ash/system/network/tray_vpn.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/session/session_controller.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/network/network_icon.h" #include "ash/system/network/network_icon_animation.h" @@ -172,7 +172,8 @@ if (!chromeos::NetworkHandler::IsInitialized()) return nullptr; - ShellPort::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_DETAILED_VPN_VIEW); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_STATUS_AREA_DETAILED_VPN_VIEW); detailed_ = new tray::VPNListView(this, status); detailed_->Init(); return detailed_;
diff --git a/ash/system/network/vpn_list_view.cc b/ash/system/network/vpn_list_view.cc index 1a1625e..db283e2 100644 --- a/ash/system/network/vpn_list_view.cc +++ b/ash/system/network/vpn_list_view.cc
@@ -7,9 +7,9 @@ #include <memory> #include <vector> +#include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/network/network_icon.h" #include "ash/system/network/network_icon_animation.h" @@ -95,12 +95,12 @@ // If the user clicks on a provider entry, request that the "add network" // dialog for this provider be shown. if (vpn_provider_.third_party) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_VPN_ADD_THIRD_PARTY_CLICKED); Shell::Get()->system_tray_controller()->ShowThirdPartyVpnCreate( vpn_provider_.extension_id); } else { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_VPN_ADD_BUILT_IN_CLICKED); Shell::Get()->system_tray_controller()->ShowNetworkCreate( shill::kTypeVPN);
diff --git a/ash/system/overview/overview_button_tray.cc b/ash/system/overview/overview_button_tray.cc index fe543b53..cf3d55b 100644 --- a/ash/system/overview/overview_button_tray.cc +++ b/ash/system/overview/overview_button_tray.cc
@@ -4,11 +4,11 @@ #include "ash/system/overview/overview_button_tray.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/session/session_controller.h" #include "ash/shelf/shelf_constants.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/tray/tray_constants.h" #include "ash/system/tray/tray_container.h" @@ -81,7 +81,7 @@ // screen is locked, a modal dialog is open or is running in kiosk app // session. bool performed = controller->ToggleOverview(); - ShellPort::Get()->RecordUserMetricsAction(UMA_TRAY_OVERVIEW); + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_TRAY_OVERVIEW); return performed; }
diff --git a/ash/system/screen_layout_observer.cc b/ash/system/screen_layout_observer.cc index f4ddd45..5420a5a 100644 --- a/ash/system/screen_layout_observer.cc +++ b/ash/system/screen_layout_observer.cc
@@ -10,10 +10,10 @@ #include "ash/display/screen_orientation_controller_chromeos.h" #include "ash/metrics/user_metrics_action.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/grit/ash_resources.h" #include "ash/session/session_controller.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/devicetype_utils.h" #include "ash/system/system_notifier.h" @@ -66,12 +66,12 @@ // Callback to handle a user selecting the notification view. void OpenSettingsFromNotification() { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_DISPLAY_NOTIFICATION_SELECTED); // Settings may be blocked, e.g. at the lock screen. if (Shell::Get()->session_controller()->ShouldEnableSettings()) { Shell::Get()->system_tray_controller()->ShowDisplaySettings(); - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_DISPLAY_NOTIFICATION_SHOW_SETTINGS); } } @@ -345,7 +345,7 @@ new message_center::HandleNotificationClickedDelegate( base::Bind(&OpenSettingsFromNotification)))); - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_DISPLAY_NOTIFICATION_CREATED); message_center::MessageCenter::Get()->AddNotification( std::move(notification));
diff --git a/ash/system/screen_security/screen_capture_tray_item.cc b/ash/system/screen_security/screen_capture_tray_item.cc index bdc3599..0ab2707 100644 --- a/ash/system/screen_security/screen_capture_tray_item.cc +++ b/ash/system/screen_security/screen_capture_tray_item.cc
@@ -7,9 +7,9 @@ #include <utility> #include "ash/metrics/user_metrics_action.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/grit/ash_resources.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/system_notifier.h" #include "ash/system/tray/system_tray_notifier.h" @@ -68,12 +68,12 @@ } void ScreenCaptureTrayItem::RecordStoppedFromDefaultViewMetric() { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_SCREEN_CAPTURE_DEFAULT_STOP); } void ScreenCaptureTrayItem::RecordStoppedFromNotificationViewMetric() { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_SCREEN_CAPTURE_NOTIFICATION_STOP); }
diff --git a/ash/system/tiles/tiles_default_view.cc b/ash/system/tiles/tiles_default_view.cc index 4cfe1d2..d5cfdc40 100644 --- a/ash/system/tiles/tiles_default_view.cc +++ b/ash/system/tiles/tiles_default_view.cc
@@ -5,10 +5,10 @@ #include "ash/system/tiles/tiles_default_view.h" #include "ash/metrics/user_metrics_action.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/session/session_controller.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/shutdown_controller.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/night_light/night_light_controller.h" @@ -117,23 +117,23 @@ const ui::Event& event) { DCHECK(sender); if (sender == settings_button_) { - ShellPort::Get()->RecordUserMetricsAction(UMA_TRAY_SETTINGS); + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_TRAY_SETTINGS); Shell::Get()->system_tray_controller()->ShowSettings(); } else if (sender == help_button_) { - ShellPort::Get()->RecordUserMetricsAction(UMA_TRAY_HELP); + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_TRAY_HELP); Shell::Get()->system_tray_controller()->ShowHelp(); } else if (NightLightController::IsFeatureEnabled() && sender == night_light_button_) { - ShellPort::Get()->RecordUserMetricsAction(UMA_TRAY_NIGHT_LIGHT); + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_TRAY_NIGHT_LIGHT); Shell::Get()->night_light_controller()->Toggle(); night_light_button_->Update(); } else if (sender == lock_button_) { - ShellPort::Get()->RecordUserMetricsAction(UMA_TRAY_LOCK_SCREEN); + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_TRAY_LOCK_SCREEN); chromeos::DBusThreadManager::Get() ->GetSessionManagerClient() ->RequestLockScreen(); } else if (sender == power_button_) { - ShellPort::Get()->RecordUserMetricsAction(UMA_TRAY_SHUT_DOWN); + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_TRAY_SHUT_DOWN); Shell::Get()->lock_state_controller()->RequestShutdown(); } }
diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc index 78f29291..35798e8 100644 --- a/ash/system/tray/system_tray.cc +++ b/ash/system/tray/system_tray.cc
@@ -10,6 +10,7 @@ #include "ash/key_event_watcher.h" #include "ash/login_status.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/config.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/root_window_controller.h" @@ -307,7 +308,8 @@ void SystemTray::ShowDefaultView(BubbleCreationType creation_type) { if (creation_type != BUBBLE_USE_EXISTING) - ShellPort::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_MENU_OPENED); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_STATUS_AREA_MENU_OPENED); ShowItems(GetTrayItems(), false, true, creation_type, false); }
diff --git a/ash/system/tray_accessibility.cc b/ash/system/tray_accessibility.cc index 6b17e76..331c990 100644 --- a/ash/system/tray_accessibility.cc +++ b/ash/system/tray_accessibility.cc
@@ -9,10 +9,10 @@ #include "ash/accessibility_delegate.h" #include "ash/accessibility_types.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/session/session_controller.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/system_notifier.h" #include "ash/system/tray/hover_highlight_view.h" @@ -298,7 +298,7 @@ } else { return; } - ShellPort::Get()->RecordUserMetricsAction(user_action); + Shell::Get()->metrics()->RecordUserMetricsAction(user_action); } void AccessibilityDetailedView::HandleButtonPressed(views::Button* sender, @@ -399,7 +399,7 @@ views::View* TrayAccessibility::CreateDetailedView(LoginStatus status) { CHECK(detailed_menu_ == nullptr); - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_DETAILED_ACCESSIBILITY); detailed_menu_ = CreateDetailedMenu(); return detailed_menu_;
diff --git a/ash/system/tray_caps_lock.cc b/ash/system/tray_caps_lock.cc index d3cdc26..eb635096 100644 --- a/ash/system/tray_caps_lock.cc +++ b/ash/system/tray_caps_lock.cc
@@ -5,9 +5,9 @@ #include "ash/system/tray_caps_lock.h" #include "ash/accessibility_delegate.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/system_notifier.h" #include "ash/system/tray/actionable_view.h" @@ -146,7 +146,7 @@ chromeos::input_method::ImeKeyboard* keyboard = chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard(); if (keyboard) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( keyboard->CapsLockIsEnabled() ? UMA_STATUS_AREA_CAPS_LOCK_DISABLED_BY_CLICK : UMA_STATUS_AREA_CAPS_LOCK_ENABLED_BY_CLICK); @@ -199,7 +199,7 @@ message_center::MessageCenter::Get(); if (caps_lock_enabled_) { if (!message_shown_) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_CAPS_LOCK_POPUP); message_center->AddNotification(CreateNotification());
diff --git a/ash/system/tray_tracing.cc b/ash/system/tray_tracing.cc index 8eeaf78..5a353e21 100644 --- a/ash/system/tray_tracing.cc +++ b/ash/system/tray_tracing.cc
@@ -5,9 +5,9 @@ #include "ash/system/tray_tracing.h" #include "ash/metrics/user_metrics_action.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/tray/actionable_view.h" #include "ash/system/tray/system_tray.h" @@ -55,7 +55,7 @@ private: bool PerformAction(const ui::Event& event) override { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_TRACING_DEFAULT_SELECTED); Shell::Get()->system_tray_controller()->ShowChromeSlow(); CloseSystemBubble();
diff --git a/ash/system/update/tray_update.cc b/ash/system/update/tray_update.cc index 1f2ca3d..c9ba3a9 100644 --- a/ash/system/update/tray_update.cc +++ b/ash/system/update/tray_update.cc
@@ -5,11 +5,11 @@ #include "ash/system/update/tray_update.h" #include "ash/metrics/user_metrics_action.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/public/interfaces/update.mojom.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/session/session_controller.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/tray/system_tray.h" #include "ash/system/tray/system_tray_controller.h" @@ -124,7 +124,7 @@ DCHECK(update_required_ || update_over_cellular_available_); if (update_required_) { Shell::Get()->system_tray_controller()->RequestRestartForUpdate(); - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_STATUS_AREA_OS_UPDATE_DEFAULT_SELECTED); } else { // Shows the about chrome OS page and checks for update after the page is
diff --git a/ash/system/user/user_view.cc b/ash/system/user/user_view.cc index b4cac927..a4ab4ba1 100644 --- a/ash/system/user/user_view.cc +++ b/ash/system/user/user_view.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <utility> +#include "ash/metrics/user_metrics_recorder.h" #include "ash/multi_profile_uma.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/resources/vector_icons/vector_icons.h" @@ -247,7 +248,7 @@ void UserView::ButtonPressed(views::Button* sender, const ui::Event& event) { if (sender == logout_button_) { - ShellPort::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_SIGN_OUT); + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_STATUS_AREA_SIGN_OUT); HideUserDropdownWidget(); Shell::Get()->system_tray_controller()->SignOut(); } else if (sender == user_card_container_ &&
diff --git a/ash/touch/touch_uma.cc b/ash/touch/touch_uma.cc index c3187fe64..0939094 100644 --- a/ash/touch/touch_uma.cc +++ b/ash/touch/touch_uma.cc
@@ -4,7 +4,8 @@ #include "ash/touch/touch_uma.h" -#include "ash/shell_port.h" +#include "ash/metrics/user_metrics_recorder.h" +#include "ash/shell.h" #include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" #include "ui/aura/env.h" @@ -113,7 +114,7 @@ kBucketCountForLocation, kBucketCountForLocation + 1); if (event.type() == ui::ET_TOUCH_PRESSED) { - ShellPort::Get()->RecordUserMetricsAction(UMA_TOUCHSCREEN_TAP_DOWN); + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_TOUCHSCREEN_TAP_DOWN); if (details->last_release_time_.ToInternalValue()) { // Measuring the interval between a touch-release and the next
diff --git a/ash/wm/gestures/overview_gesture_handler.cc b/ash/wm/gestures/overview_gesture_handler.cc index d00475d8..938bb97c 100644 --- a/ash/wm/gestures/overview_gesture_handler.cc +++ b/ash/wm/gestures/overview_gesture_handler.cc
@@ -4,8 +4,8 @@ #include "ash/wm/gestures/overview_gesture_handler.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/wm/overview/window_selector_controller.h" #include "ui/events/event.h" #include "ui/events/event_constants.h" @@ -66,7 +66,8 @@ // Reset scroll amount on toggling. scroll_x_ = scroll_y_ = 0; - ShellPort::Get()->RecordUserMetricsAction(UMA_TOUCHPAD_GESTURE_OVERVIEW); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_TOUCHPAD_GESTURE_OVERVIEW); if (window_selector_controller->IsSelecting() && window_selector_controller->AcceptSelection()) { return true;
diff --git a/ash/wm/lock_state_controller.cc b/ash/wm/lock_state_controller.cc index afc90816..215776d 100644 --- a/ash/wm/lock_state_controller.cc +++ b/ash/wm/lock_state_controller.cc
@@ -10,6 +10,7 @@ #include "ash/accessibility_delegate.h" #include "ash/cancel_mode.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/interfaces/shutdown.mojom.h" #include "ash/shell.h" @@ -300,7 +301,8 @@ void LockStateController::OnRealPowerTimeout() { VLOG(1) << "OnRealPowerTimeout"; DCHECK(shutting_down_); - ShellPort::Get()->RecordUserMetricsAction(UMA_ACCEL_SHUT_DOWN_POWER_BUTTON); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_ACCEL_SHUT_DOWN_POWER_BUTTON); // Shut down or reboot based on device policy. shutdown_controller_->ShutDownOrReboot(); } @@ -465,7 +467,7 @@ } if (request_lock) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( shutdown_after_lock_ ? UMA_ACCEL_LOCK_SCREEN_POWER_BUTTON : UMA_ACCEL_LOCK_SCREEN_LOCK_BUTTON); chromeos::DBusThreadManager::Get()
diff --git a/ash/wm/maximize_mode/maximize_mode_controller.cc b/ash/wm/maximize_mode/maximize_mode_controller.cc index e373eec..b8be143 100644 --- a/ash/wm/maximize_mode/maximize_mode_controller.cc +++ b/ash/wm/maximize_mode/maximize_mode_controller.cc
@@ -7,9 +7,9 @@ #include <utility> #include "ash/ash_switches.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/shell.h" #include "ash/shell_delegate.h" -#include "ash/shell_port.h" #include "ash/wm/maximize_mode/maximize_mode_window_manager.h" #include "ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard.h" #include "base/bind.h" @@ -131,7 +131,7 @@ scoped_session_observer_(this), weak_factory_(this) { Shell::Get()->AddShellObserver(this); - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_MAXIMIZE_MODE_INITIALLY_DISABLED); // TODO(jonross): Do not create MaximizeModeController if the flag is @@ -179,7 +179,7 @@ maximize_mode_window_manager_.reset(new MaximizeModeWindowManager()); // TODO(jonross): Move the maximize mode notifications from ShellObserver // to MaximizeModeController::Observer - ShellPort::Get()->RecordUserMetricsAction(UMA_MAXIMIZE_MODE_ENABLED); + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_MAXIMIZE_MODE_ENABLED); Shell::Get()->NotifyMaximizeModeStarted(); observers_.ForAllPtrs([](mojom::TouchViewObserver* observer) { @@ -190,7 +190,8 @@ maximize_mode_window_manager_->SetIgnoreWmEventsForExit(); Shell::Get()->NotifyMaximizeModeEnding(); maximize_mode_window_manager_.reset(); - ShellPort::Get()->RecordUserMetricsAction(UMA_MAXIMIZE_MODE_DISABLED); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_MAXIMIZE_MODE_DISABLED); Shell::Get()->NotifyMaximizeModeEnded(); observers_.ForAllPtrs([](mojom::TouchViewObserver* observer) {
diff --git a/ash/wm/overview/window_selector.cc b/ash/wm/overview/window_selector.cc index 76bdee5..0f078e0 100644 --- a/ash/wm/overview/window_selector.cc +++ b/ash/wm/overview/window_selector.cc
@@ -13,12 +13,12 @@ #include "ash/accessibility_delegate.h" #include "ash/accessibility_types.h" #include "ash/metrics/user_metrics_action.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/root_window_controller.h" #include "ash/screen_util.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/wm/mru_window_tracker.h" #include "ash/wm/overview/window_grid.h" #include "ash/wm/overview/window_selector_delegate.h" @@ -310,7 +310,7 @@ Shell::Get()->activation_client()->AddObserver(this); display::Screen::GetScreen()->AddObserver(this); - ShellPort::Get()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); // Send an a11y alert. Shell::Get()->accessibility_delegate()->TriggerAccessibilityAlert( A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); @@ -428,7 +428,7 @@ // a window other than the window that was active prior to entering overview // mode (i.e., the window at the front of the MRU list). if (window_list[0] != window) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_WINDOW_OVERVIEW_ACTIVE_WINDOW_CHANGED); } const auto it = std::find(window_list.begin(), window_list.end(), window); @@ -481,7 +481,8 @@ // Allow the textfield to handle 'W' key when not used with Ctrl. return false; } - ShellPort::Get()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW_CLOSE_KEY); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_WINDOW_OVERVIEW_CLOSE_KEY); grid_list_[selected_grid_index_]->SelectedWindow()->CloseWindow(); break; case ui::VKEY_RETURN: @@ -493,7 +494,8 @@ UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.WindowSelector.KeyPressesOverItemsRatio", (num_key_presses_ * 100) / num_items_, 1, 300, 30); - ShellPort::Get()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW_ENTER_KEY); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_WINDOW_OVERVIEW_ENTER_KEY); SelectWindow(grid_list_[selected_grid_index_]->SelectedWindow()); break; default:
diff --git a/ash/wm/overview/window_selector_item.cc b/ash/wm/overview/window_selector_item.cc index 723e54b..78406fc 100644 --- a/ash/wm/overview/window_selector_item.cc +++ b/ash/wm/overview/window_selector_item.cc
@@ -8,11 +8,11 @@ #include <vector> #include "ash/metrics/user_metrics_action.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/root_window_controller.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/wm/maximize_mode/maximize_mode_controller.h" #include "ash/wm/overview/cleanup_animation_observer.h" #include "ash/wm/overview/overview_animation_type.h" @@ -531,11 +531,12 @@ void WindowSelectorItem::ButtonPressed(views::Button* sender, const ui::Event& event) { if (sender == close_button_) { - ShellPort::Get()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW_CLOSE_BUTTON); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_WINDOW_OVERVIEW_CLOSE_BUTTON); if (ash::Shell::Get() ->maximize_mode_controller() ->IsMaximizeModeWindowManagerEnabled()) { - ash::ShellPort::Get()->RecordUserMetricsAction( + ash::Shell::Get()->metrics()->RecordUserMetricsAction( ash::UMA_TABLET_WINDOW_CLOSE_THROUGH_OVERVIEW_CLOSE_BUTTON); } CloseWindow();
diff --git a/ash/wm/panels/panel_window_event_handler.cc b/ash/wm/panels/panel_window_event_handler.cc index 4de0b0c..bb129a89a 100644 --- a/ash/wm/panels/panel_window_event_handler.cc +++ b/ash/wm/panels/panel_window_event_handler.cc
@@ -4,7 +4,8 @@ #include "ash/wm/panels/panel_window_event_handler.h" -#include "ash/shell_port.h" +#include "ash/metrics/user_metrics_recorder.h" +#include "ash/shell.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "ui/aura/window.h" @@ -24,7 +25,8 @@ event->flags() & ui::EF_IS_DOUBLE_CLICK && event->IsOnlyLeftMouseButton() && wm::GetNonClientComponent(target, event->location()) == HTCAPTION) { - ShellPort::Get()->RecordUserMetricsAction(UMA_PANEL_MINIMIZE_CAPTION_CLICK); + Shell::Get()->metrics()->RecordUserMetricsAction( + UMA_PANEL_MINIMIZE_CAPTION_CLICK); wm::GetWindowState(target)->Minimize(); event->StopPropagation(); return; @@ -36,7 +38,7 @@ if (!event->handled() && event->type() == ui::ET_GESTURE_TAP && event->details().tap_count() == 2 && wm::GetNonClientComponent(target, event->location()) == HTCAPTION) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_PANEL_MINIMIZE_CAPTION_GESTURE); wm::GetWindowState(target)->Minimize(); event->StopPropagation();
diff --git a/ash/wm/window_cycle_controller.cc b/ash/wm/window_cycle_controller.cc index 4ef3d16..567d5e62 100644 --- a/ash/wm/window_cycle_controller.cc +++ b/ash/wm/window_cycle_controller.cc
@@ -4,7 +4,9 @@ #include "ash/wm/window_cycle_controller.h" +#include "ash/metrics/task_switch_metrics_recorder.h" #include "ash/metrics/task_switch_source.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/session/session_controller.h" #include "ash/shell.h" @@ -81,7 +83,7 @@ window_cycle_list_.reset(new WindowCycleList(window_list)); event_filter_ = ShellPort::Get()->CreateWindowCycleEventFilter(); cycle_start_time_ = base::Time::Now(); - ShellPort::Get()->RecordUserMetricsAction(UMA_WINDOW_CYCLE); + Shell::Get()->metrics()->RecordUserMetricsAction(UMA_WINDOW_CYCLE); UMA_HISTOGRAM_COUNTS_100("Ash.WindowCycleController.Items", window_list.size()); } @@ -118,7 +120,7 @@ if (active_window_after_window_cycle != nullptr && active_window_before_window_cycle_ != active_window_after_window_cycle) { - ShellPort::Get()->RecordTaskSwitchMetric( + Shell::Get()->metrics()->task_switch_metrics_recorder().OnTaskSwitch( TaskSwitchSource::WINDOW_CYCLE_CONTROLLER); } active_window_before_window_cycle_ = nullptr;
diff --git a/ash/wm/workspace/workspace_event_handler.cc b/ash/wm/workspace/workspace_event_handler.cc index 5db36d9..ebbbc037 100644 --- a/ash/wm/workspace/workspace_event_handler.cc +++ b/ash/wm/workspace/workspace_event_handler.cc
@@ -4,7 +4,9 @@ #include "ash/wm/workspace/workspace_event_handler.h" -#include "ash/shell_port.h" +#include "ash/metrics/user_metrics_recorder.h" +#include "ash/shell.h" +#include "ash/touch/touch_uma.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" @@ -49,7 +51,7 @@ if (event->flags() & ui::EF_IS_DOUBLE_CLICK) { int component = wm::GetNonClientComponent(target, event->location()); if (component == HTCAPTION && component == click_component_) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_TOGGLE_MAXIMIZE_CAPTION_CLICK); const wm::WMEvent wm_event(wm::WM_EVENT_TOGGLE_MAXIMIZE_CAPTION); target_state->OnWMEvent(&wm_event); @@ -81,14 +83,14 @@ return; if (event->details().tap_count() != 2) { - ShellPort::Get()->RecordGestureAction(GESTURE_FRAMEVIEW_TAP); + TouchUMA::GetInstance()->RecordGestureAction(GESTURE_FRAMEVIEW_TAP); return; } if (click_component_ == previous_target_component) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_TOGGLE_MAXIMIZE_CAPTION_GESTURE); - ShellPort::Get()->RecordGestureAction(GESTURE_MAXIMIZE_DOUBLETAP); + TouchUMA::GetInstance()->RecordGestureAction(GESTURE_MAXIMIZE_DOUBLETAP); const wm::WMEvent wm_event(wm::WM_EVENT_TOGGLE_MAXIMIZE_CAPTION); wm::GetWindowState(target)->OnWMEvent(&wm_event); event->StopPropagation(); @@ -103,13 +105,13 @@ if ((event->flags() & ui::EF_IS_DOUBLE_CLICK) != 0 && target->delegate()) { const int component = wm::GetNonClientComponent(target, event->location()); if (component == HTBOTTOM || component == HTTOP) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_TOGGLE_SINGLE_AXIS_MAXIMIZE_BORDER_CLICK); const wm::WMEvent wm_event(wm::WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE); target_state->OnWMEvent(&wm_event); event->StopPropagation(); } else if (component == HTLEFT || component == HTRIGHT) { - ShellPort::Get()->RecordUserMetricsAction( + Shell::Get()->metrics()->RecordUserMetricsAction( UMA_TOGGLE_SINGLE_AXIS_MAXIMIZE_BORDER_CLICK); const wm::WMEvent wm_event(wm::WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE); target_state->OnWMEvent(&wm_event);
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc index 477d15ae..47f52d01 100644 --- a/ash/wm/workspace/workspace_window_resizer.cc +++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -10,6 +10,7 @@ #include <vector> #include "ash/metrics/user_metrics_action.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/root_window_controller.h" #include "ash/screen_util.h" @@ -408,9 +409,9 @@ const wm::WMEvent event(snap_type_ == SNAP_LEFT ? wm::WM_EVENT_SNAP_LEFT : wm::WM_EVENT_SNAP_RIGHT); window_state()->OnWMEvent(&event); - ShellPort::Get()->RecordUserMetricsAction(snap_type_ == SNAP_LEFT - ? UMA_DRAG_MAXIMIZE_LEFT - : UMA_DRAG_MAXIMIZE_RIGHT); + Shell::Get()->metrics()->RecordUserMetricsAction( + snap_type_ == SNAP_LEFT ? UMA_DRAG_MAXIMIZE_LEFT + : UMA_DRAG_MAXIMIZE_RIGHT); snapped = true; }
diff --git a/build/android/gradle/root.jinja b/build/android/gradle/root.jinja index 0d92ba5..ba418b4 100644 --- a/build/android/gradle/root.jinja +++ b/build/android/gradle/root.jinja
@@ -8,6 +8,6 @@ jcenter() } dependencies { - classpath "com.android.tools.build:gradle:2.3.2" + classpath "com.android.tools.build:gradle:2.3.3" } }
diff --git a/build_overrides/pdfium.gni b/build_overrides/pdfium.gni index 377cdbeb..fb37646 100644 --- a/build_overrides/pdfium.gni +++ b/build_overrides/pdfium.gni
@@ -15,8 +15,8 @@ # Disable use of Skia backend. pdf_use_skia_override = false -# Enable use of Skia backend, paths only. -pdf_use_skia_paths_override = true +# Disable use of Skia backend, paths only (experimental) +pdf_use_skia_paths_override = false # Enable experimental win32 GDI APIs. pdf_use_win32_gdi_override = true
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java index 2dc9ce5..70892c7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java
@@ -29,6 +29,10 @@ * Stores info for WebAPK. */ public class WebApkInfo extends WebappInfo { + public static final String RESOURCE_NAME = "name"; + public static final String RESOURCE_SHORT_NAME = "short_name"; + public static final String RESOURCE_STRING_TYPE = "string"; + private static final String TAG = "WebApkInfo"; private boolean mForceNavigation; @@ -89,8 +93,24 @@ return null; } - String name = IntentUtils.safeGetString(bundle, WebApkMetaDataKeys.NAME); - String shortName = IntentUtils.safeGetString(bundle, WebApkMetaDataKeys.SHORT_NAME); + Resources res = null; + try { + res = ContextUtils.getApplicationContext() + .getPackageManager() + .getResourcesForApplication(webApkPackageName); + } catch (PackageManager.NameNotFoundException e) { + return null; + } + + int nameId = res.getIdentifier(RESOURCE_NAME, RESOURCE_STRING_TYPE, webApkPackageName); + int shortNameId = + res.getIdentifier(RESOURCE_SHORT_NAME, RESOURCE_STRING_TYPE, webApkPackageName); + String name = nameId != 0 ? res.getString(nameId) + : IntentUtils.safeGetString(bundle, WebApkMetaDataKeys.NAME); + String shortName = shortNameId != 0 + ? res.getString(shortNameId) + : IntentUtils.safeGetString(bundle, WebApkMetaDataKeys.SHORT_NAME); + String scope = IntentUtils.safeGetString(bundle, WebApkMetaDataKeys.SCOPE); int displayMode = displayModeFromString( @@ -110,10 +130,10 @@ Map<String, String> iconUrlToMurmur2HashMap = getIconUrlAndIconMurmur2HashMap(bundle); int primaryIconId = IntentUtils.safeGetInt(bundle, WebApkMetaDataKeys.ICON_ID, 0); - Bitmap primaryIcon = decodeImageResource(webApkPackageName, primaryIconId); + Bitmap primaryIcon = decodeImageResource(res, primaryIconId); int badgeIconId = IntentUtils.safeGetInt(bundle, WebApkMetaDataKeys.BADGE_ICON_ID, 0); - Bitmap badgeIcon = decodeImageResource(webApkPackageName, badgeIconId); + Bitmap badgeIcon = decodeImageResource(res, badgeIconId); return create(WebApkConstants.WEBAPK_ID_PREFIX + webApkPackageName, url, forceNavigation, scope, new Icon(primaryIcon), new Icon(badgeIcon), name, shortName, displayMode, @@ -250,16 +270,10 @@ } /** - * Decodes bitmap from WebAPK's resources. Returns null when resource is not found. + * Decodes bitmap from WebAPK's resources. */ - private static Bitmap decodeImageResource(String webApkPackageName, int resourceId) { - PackageManager packageManager = ContextUtils.getApplicationContext().getPackageManager(); - try { - Resources resources = packageManager.getResourcesForApplication(webApkPackageName); - return BitmapFactory.decodeResource(resources, resourceId); - } catch (PackageManager.NameNotFoundException e) { - return null; - } + private static Bitmap decodeImageResource(Resources webApkResources, int resourceId) { + return BitmapFactory.decodeResource(webApkResources, resourceId); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java index 0758d2a..f55a895 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java
@@ -15,6 +15,7 @@ import org.chromium.chrome.browser.banners.InstallerDelegate; import org.chromium.chrome.browser.browsing_data.UrlFilter; import org.chromium.chrome.browser.browsing_data.UrlFilterBridge; +import org.chromium.webapk.lib.common.WebApkConstants; import java.util.Collections; import java.util.HashMap; @@ -193,7 +194,11 @@ WebappDataStorage storage = entry.getValue(); String webApkPackage = storage.getWebApkPackageName(); if (webApkPackage != null) { - if (isWebApkInstalled(webApkPackage)) { + // Prefix check that the key matches the current scheme instead of an old + // deprecated naming scheme and that the WebApk is still installed. The former is + // necessary as we migrate away from the old naming scheme and garbage collect. + if (entry.getKey().startsWith(WebApkConstants.WEBAPK_ID_PREFIX) + && isWebApkInstalled(webApkPackage)) { continue; } } else if ((currentTime - storage.getLastUsedTime())
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDirectoryManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDirectoryManagerTest.java index 798d5f6..c69d727 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDirectoryManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDirectoryManagerTest.java
@@ -25,6 +25,7 @@ import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; +import org.chromium.webapk.lib.common.WebApkConstants; import java.io.File; import java.util.HashSet; @@ -41,6 +42,9 @@ private static final String WEBAPP_ID_1 = "webapp_1"; private static final String WEBAPP_ID_2 = "webapp_2"; private static final String WEBAPP_ID_3 = "webapp_3"; + private static final String WEBAPK_ID_1 = WebApkConstants.WEBAPK_ID_PREFIX + "webapp_1"; + private static final String WEBAPK_ID_2 = WebApkConstants.WEBAPK_ID_PREFIX + "webapp_2"; + private static final String WEBAPK_ID_3 = WebApkConstants.WEBAPK_ID_PREFIX + "webapp_3"; private static class TestWebappDirectoryManager extends WebappDirectoryManager { private Set<Intent> mBaseIntents = new HashSet<Intent>(); @@ -148,6 +152,41 @@ Assert.assertFalse(directory3.exists()); } + /** + * On Lollipop and higher, the {@link WebappDirectoryManager} also deletes directories for + * *WebApks* that no longer correspond to tasks in Recents. + */ + @Test + @SmallTest + @Feature({"Webapps"}) + public void testDeletesDirectoriesForDeadWebApkTasks() throws Exception { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; + + // Track the three web app directories. + File directory1 = + new File(mWebappDirectoryManager.getBaseWebappDirectory(mMockContext), WEBAPK_ID_1); + File directory2 = + new File(mWebappDirectoryManager.getBaseWebappDirectory(mMockContext), WEBAPK_ID_2); + File directory3 = + new File(mWebappDirectoryManager.getBaseWebappDirectory(mMockContext), WEBAPK_ID_3); + + // Seed the directory with folders for web apps. + Assert.assertTrue(directory1.mkdirs()); + Assert.assertTrue(directory2.mkdirs()); + Assert.assertTrue(directory3.mkdirs()); + + // Indicate that another of the web apps is listed in Recents; in real usage this web app + // would not be in the foreground and would have persisted its state. + mWebappDirectoryManager.mBaseIntents.add( + new Intent(Intent.ACTION_VIEW, Uri.parse("webapp://webapk-webapp_2"))); + + // Only the directory for the background web app should survive. + runCleanup(); + Assert.assertFalse(directory1.exists()); + Assert.assertTrue(directory2.exists()); + Assert.assertFalse(directory3.exists()); + } + @Test @SmallTest @Feature({"Webapps"})
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInfoTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInfoTest.java index ecaf1ae..d7c6f1ca 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInfoTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInfoTest.java
@@ -5,6 +5,8 @@ package org.chromium.chrome.browser.webapps; import android.content.Intent; +import android.content.res.AssetManager; +import android.content.res.Resources; import android.os.Bundle; import org.junit.Assert; @@ -24,6 +26,7 @@ import org.chromium.webapk.lib.common.WebApkMetaDataKeys; import org.chromium.webapk.test.WebApkTestHelper; +import java.util.HashMap; import java.util.Map; /** @@ -49,6 +52,48 @@ private static final String ICON_MURMUR2_HASH = "5"; private static final int SOURCE = ShortcutSource.NOTIFICATION; + /** Fakes the Resources object, allowing lookup of String value. */ + private static class FakeResources extends Resources { + private final Map<String, Integer> mStringIdMap; + private final Map<Integer, String> mIdValueMap; + + // Do not warn about deprecated call to Resources(); the documentation says code is not + // supposed to create its own Resources object, but we are using it to fake out the + // Resources, and there is no other way to do that. + @SuppressWarnings("deprecation") + public FakeResources() { + super(new AssetManager(), null, null); + mStringIdMap = new HashMap<>(); + mIdValueMap = new HashMap<>(); + } + + @Override + public int getIdentifier(String name, String defType, String defPackage) { + String key = getKey(name, defType, defPackage); + return mStringIdMap.containsKey(key) ? mStringIdMap.get(key) : 0; + } + + @Override + public String getString(int id) { + if (!mIdValueMap.containsKey(id)) { + throw new Resources.NotFoundException("id 0x" + Integer.toHexString(id)); + } + + return mIdValueMap.get(id); + } + + public void addStringForTesting( + String name, String defType, String defPackage, int identifier, String value) { + String key = getKey(name, defType, defPackage); + mStringIdMap.put(key, identifier); + mIdValueMap.put(identifier, value); + } + + private String getKey(String name, String defType, String defPackage) { + return defPackage + ":" + defType + "/" + name; + } + } + @Before public void setUp() { ContextUtils.initApplicationContextForTests(RuntimeEnvironment.application); @@ -248,4 +293,55 @@ WebApkInfo info = WebApkInfo.create(intent); Assert.assertEquals(ShortcutSource.UNKNOWN, info.source()); } + + /** + * Test that {@link WebApkInfo#name()} and {@link WebApkInfo#shortName()} return the name and + * short name from the meta data before they are moved to strings in resources. + */ + @Test + public void testNameAndShortNameFromMetadataWhenStringResourcesDoNotExist() { + String name = "WebAPK name"; + String shortName = "WebAPK short name"; + Bundle bundle = new Bundle(); + bundle.putString(WebApkMetaDataKeys.START_URL, START_URL); + bundle.putString(WebApkMetaDataKeys.NAME, name); + bundle.putString(WebApkMetaDataKeys.SHORT_NAME, shortName); + WebApkTestHelper.registerWebApkWithMetaData(WEBAPK_PACKAGE_NAME, bundle); + + Intent intent = new Intent(); + intent.putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, WEBAPK_PACKAGE_NAME); + intent.putExtra(ShortcutHelper.EXTRA_URL, START_URL); + + WebApkInfo info = WebApkInfo.create(intent); + Assert.assertEquals(name, info.name()); + Assert.assertEquals(shortName, info.shortName()); + } + + /** + * Test that {@link WebApkInfo#name()} and {@link WebApkInfo#shortName()} return the string + * values from the WebAPK resources if exist. + */ + @Test + public void testNameAndShortNameFromWebApkStrings() { + Bundle bundle = new Bundle(); + bundle.putString(WebApkMetaDataKeys.START_URL, START_URL); + WebApkTestHelper.registerWebApkWithMetaData(WEBAPK_PACKAGE_NAME, bundle); + + String name = "WebAPK name"; + String shortName = "WebAPK short name"; + FakeResources res = new FakeResources(); + res.addStringForTesting(WebApkInfo.RESOURCE_NAME, WebApkInfo.RESOURCE_STRING_TYPE, + WEBAPK_PACKAGE_NAME, 1, name); + res.addStringForTesting(WebApkInfo.RESOURCE_SHORT_NAME, WebApkInfo.RESOURCE_STRING_TYPE, + WEBAPK_PACKAGE_NAME, 2, shortName); + WebApkTestHelper.setResource(WEBAPK_PACKAGE_NAME, res); + + Intent intent = new Intent(); + intent.putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, WEBAPK_PACKAGE_NAME); + intent.putExtra(ShortcutHelper.EXTRA_URL, START_URL); + + WebApkInfo info = WebApkInfo.create(intent); + Assert.assertEquals(name, info.name()); + Assert.assertEquals(shortName, info.shortName()); + } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java index f52d40af..8e23358 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java
@@ -321,9 +321,9 @@ @Test @Feature({"WebApk"}) public void testCleanupRemovesUninstalledWebApks() throws Exception { - String webappId1 = "webapk:uninstalledWebApk1"; + String webappId1 = WebApkConstants.WEBAPK_ID_PREFIX + "uninstalledWebApk1"; String webApkPackage1 = "uninstalledWebApk1"; - String webappId2 = "webapk:uninstalledWebApk2"; + String webappId2 = WebApkConstants.WEBAPK_ID_PREFIX + "uninstalledWebApk2"; String webApkPackage2 = "uninstalledWebApk2"; FetchStorageCallback storageCallback1 = new FetchStorageCallback( @@ -359,9 +359,9 @@ @Test @Feature({"WebApk"}) public void testCleanupDoesNotRemoveInstalledWebApks() throws Exception { - String webappId = "webapk:installedWebApk"; + String webappId = WebApkConstants.WEBAPK_ID_PREFIX + "installedWebApk"; String webApkPackage = "installedWebApk"; - String uninstalledWebappId = "webapk:uninstalledWebApk"; + String uninstalledWebappId = WebApkConstants.WEBAPK_ID_PREFIX + "uninstalledWebApk"; String uninstalledWebApkPackage = "uninstalledWebApk"; FetchStorageCallback storageCallback = new FetchStorageCallback( @@ -399,6 +399,46 @@ } @Test + @Feature({"WebApk"}) + public void testCleanupDoesRemoveOldInstalledWebApks() throws Exception { + String deprecatedWebappId = "webapk:installedWebApk"; + String webApkPackage = "installedWebApk"; + String installedWebappId = WebApkConstants.WEBAPK_ID_PREFIX + "installedWebApk"; + + FetchStorageCallback storageCallback = + new FetchStorageCallback(createWebApkIntent(deprecatedWebappId, webApkPackage)); + registerWebapp(deprecatedWebappId, storageCallback); + assertTrue(storageCallback.getCallbackCalled()); + + FetchStorageCallback storageCallback2 = + new FetchStorageCallback(createWebApkIntent(installedWebappId, webApkPackage)); + registerWebapp(installedWebappId, storageCallback2); + assertTrue(storageCallback2.getCallbackCalled()); + + // Verify that both WebAPKs are registered. + Set<String> actual = getRegisteredWebapps(); + assertEquals(2, actual.size()); + assertTrue(actual.contains(deprecatedWebappId)); + assertTrue(actual.contains(installedWebappId)); + + RuntimeEnvironment.getRobolectricPackageManager().addPackage(webApkPackage); + + // Set the current time such that the task runs. + long currentTime = System.currentTimeMillis() + WebappRegistry.FULL_CLEANUP_DURATION; + // Because the time is just inside the window, there should be a cleanup of + // uninstalled WebAPKs and the last cleaned up time should be set to the + // current time. + WebappRegistry.getInstance().unregisterOldWebapps(currentTime); + + actual = getRegisteredWebapps(); + assertEquals(1, actual.size()); + assertTrue(actual.contains(installedWebappId)); + + long lastCleanup = mSharedPreferences.getLong(WebappRegistry.KEY_LAST_CLEANUP, -1); + assertEquals(currentTime, lastCleanup); + } + + @Test @Feature({"Webapp"}) public void testClearWebappHistory() throws Exception { final String webapp1Url = "https://www.google.com";
diff --git a/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkConstants.java b/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkConstants.java index 45b6a2c3..7749f979 100644 --- a/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkConstants.java +++ b/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkConstants.java
@@ -11,7 +11,7 @@ public static final String WEBAPK_PACKAGE_PREFIX = "org.chromium.webapk"; // WebAPK id prefix. The id is used for storing WebAPK data in Chrome's SharedPreferences. - public static final String WEBAPK_ID_PREFIX = "webapk:"; + public static final String WEBAPK_ID_PREFIX = "webapk-"; // These EXTRA_* values must stay in sync with // {@link org.chromium.chrome.browser.ShortcutHelper}.
diff --git a/chrome/android/webapk/shell_apk/AndroidManifest.xml b/chrome/android/webapk/shell_apk/AndroidManifest.xml index 44f4572..9aa46e77 100644 --- a/chrome/android/webapk/shell_apk/AndroidManifest.xml +++ b/chrome/android/webapk/shell_apk/AndroidManifest.xml
@@ -15,7 +15,7 @@ <application android:icon="@mipmap/app_icon" - android:label="{{{short_name}}}" + android:label="@string/short_name" android:allowBackup="false"> <activity android:name="org.chromium.webapk.shell_apk.MainActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" @@ -35,8 +35,6 @@ {{#runtime_host}}<meta-data android:name="org.chromium.webapk.shell_apk.runtimeHost" android:value="{{{runtime_host}}}" />{{/runtime_host}} {{#runtime_host_application_name}}<meta-data android:name="org.chromium.webapk.shell_apk.runtimeHostApplicationName" android:value="{{{runtime_host_application_name}}}" />{{/runtime_host_application_name}} <meta-data android:name="org.chromium.webapk.shell_apk.startUrl" android:value="{{{start_url}}}" /> - <meta-data android:name="org.chromium.webapk.shell_apk.name" android:value="{{{name}}}" /> - <meta-data android:name="org.chromium.webapk.shell_apk.shortName" android:value="{{{short_name}}}" /> <meta-data android:name="org.chromium.webapk.shell_apk.scope" android:value="{{{scope_url}}}" /> <meta-data android:name="org.chromium.webapk.shell_apk.displayMode" android:value="{{{display_mode}}}" /> <meta-data android:name="org.chromium.webapk.shell_apk.orientation" android:value="{{{orientation}}}" />
diff --git a/chrome/android/webapk/shell_apk/BUILD.gn b/chrome/android/webapk/shell_apk/BUILD.gn index b87470ce..6a93ecc 100644 --- a/chrome/android/webapk/shell_apk/BUILD.gn +++ b/chrome/android/webapk/shell_apk/BUILD.gn
@@ -23,8 +23,6 @@ # Attributes from Web Manifest. webapk_start_url = "https://pwa.rocks/" - webapk_name = "Progressive Web Apps" - webapk_short_name = "PWA List" webapk_scope_url = "https://pwa.rocks/" webapk_display_mode = "standalone" webapk_orientation = "portrait" @@ -64,8 +62,6 @@ "runtime_host=$webapk_runtime_host", "runtime_host_application_name=$webapk_runtime_host_application_name", "start_url=$webapk_start_url", - "name=$webapk_name", - "short_name=$webapk_short_name", "scope_url=$webapk_scope_url", "display_mode=$webapk_display_mode", "orientation=$webapk_orientation", @@ -92,8 +88,6 @@ # Intentionally omitted: "runtime_host=org.chromium.chrome", "include_label=true", "start_url=$webapk_start_url", - "name=$webapk_name", - "short_name=$webapk_short_name", "scope_url=$webapk_scope_url", "display_mode=$webapk_display_mode", "orientation=$webapk_orientation", @@ -119,8 +113,6 @@ "manifest_package=org.chromium.webapk.test", "runtime_host=org.chromium.chrome", "start_url=https://pwa.rocks", - "name=Test", - "short_name=Test", "scope_url=https://pwa.rocks", "display_mode=standalone", "orientation=portrait",
diff --git a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/WebApkUtilsTest.java b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/WebApkUtilsTest.java index f33a9c8..548f7cbc 100644 --- a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/WebApkUtilsTest.java +++ b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/WebApkUtilsTest.java
@@ -53,8 +53,9 @@ @Before public void setUp() { mContext = RuntimeEnvironment.application; - mPackageManager = - Mockito.spy((RobolectricPackageManager) RuntimeEnvironment.getPackageManager()); + WebApkTestHelper.setUpPackageManager(); + + mPackageManager = Mockito.spy(RuntimeEnvironment.getRobolectricPackageManager()); RuntimeEnvironment.setRobolectricPackageManager(mPackageManager); WebApkUtils.resetCachedHostPackageForTesting(); @@ -81,7 +82,7 @@ setHostBrowserInSharedPreferences(expectedHostBrowser); String hostBrowser = WebApkUtils.getHostBrowserPackageName(mContext); - Assert.assertEquals(hostBrowser, expectedHostBrowser); + Assert.assertEquals(expectedHostBrowser, hostBrowser); } /** @@ -108,7 +109,7 @@ // Simulates there is a host browser stored in the SharedPreference but uninstalled. setHostBrowserInSharedPreferences(BROWSER_UNINSTALLED_SUPPORTING_WEBAPKS); hostBrowser = WebApkUtils.getHostBrowserPackageName(mContext); - Assert.assertEquals(hostBrowser, expectedHostBrowser); + Assert.assertEquals(expectedHostBrowser, hostBrowser); } /** @@ -148,7 +149,7 @@ setHostBrowserInSharedPreferences(null); String hostBrowser = WebApkUtils.getHostBrowserPackageName(mContext); - Assert.assertEquals(hostBrowser, defaultBrowser); + Assert.assertEquals(defaultBrowser, hostBrowser); } /**
diff --git a/chrome/android/webapk/shell_apk/shell_apk_version.gni b/chrome/android/webapk/shell_apk/shell_apk_version.gni index 3bf44efd..cdbf4e0 100644 --- a/chrome/android/webapk/shell_apk/shell_apk_version.gni +++ b/chrome/android/webapk/shell_apk/shell_apk_version.gni
@@ -6,7 +6,7 @@ # (including AndroidManifest.xml) is updated. This version should be incremented # prior to uploading a new ShellAPK to the WebAPK Minting Server. # Does not affect Chrome.apk -template_shell_apk_version = 8 +template_shell_apk_version = 9 # The ShellAPK version expected by Chrome. Chrome will try to update the WebAPK # if the WebAPK's ShellAPK version is less than |expected_shell_apk_version|.
diff --git a/chrome/android/webapk/strings/android_webapk_strings.grd b/chrome/android/webapk/strings/android_webapk_strings.grd index 1ca3d61f..4dfa9d7 100644 --- a/chrome/android/webapk/strings/android_webapk_strings.grd +++ b/chrome/android/webapk/strings/android_webapk_strings.grd
@@ -112,6 +112,10 @@ <message name="IDS_INSTALL_HOST_BROWSER_DIALOG_INSTALL_BUTTON" desc="Text for the install button on the dialog. "> INSTALL </message> + <message name="IDS_NAME" desc="The name of the WebAPK." translateable="false"> + </message> + <message name="IDS_SHORT_NAME" desc="The short name of the WebAPK." translateable="false"> + </message> </messages> </release> </grit>
diff --git a/chrome/android/webapk/test/BUILD.gn b/chrome/android/webapk/test/BUILD.gn index 8a594cd1..a50cfc1 100644 --- a/chrome/android/webapk/test/BUILD.gn +++ b/chrome/android/webapk/test/BUILD.gn
@@ -10,6 +10,7 @@ testonly = true java_files = [ "src/org/chromium/webapk/test/WebApkTestHelper.java" ] deps = [ + "//third_party/mockito:mockito_java", "//third_party/robolectric:robolectric_all_java", ] }
diff --git a/chrome/android/webapk/test/src/org/chromium/webapk/test/WebApkTestHelper.java b/chrome/android/webapk/test/src/org/chromium/webapk/test/WebApkTestHelper.java index d8fe09b..1818995 100644 --- a/chrome/android/webapk/test/src/org/chromium/webapk/test/WebApkTestHelper.java +++ b/chrome/android/webapk/test/src/org/chromium/webapk/test/WebApkTestHelper.java
@@ -6,26 +6,76 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; +import android.content.res.Resources; import android.os.Bundle; +import org.mockito.Mockito; import org.robolectric.RuntimeEnvironment; +import org.robolectric.res.builder.DefaultPackageManager; import org.robolectric.res.builder.RobolectricPackageManager; +import java.util.HashMap; + /** * Helper class for WebAPK JUnit tests. */ public class WebApkTestHelper { + /** FakePackageManager allows setting up Resources for installed packages. */ + private static class FakePackageManager extends DefaultPackageManager { + private final HashMap<String, Resources> mResourceMap; + + public FakePackageManager() { + mResourceMap = new HashMap<>(); + } + + @Override + public Resources getResourcesForApplication(String appPackageName) + throws NameNotFoundException { + Resources result = mResourceMap.get(appPackageName); + if (result == null) throw new NameNotFoundException(appPackageName); + + return result; + } + + public void setResourcesForTest(String packageName, Resources resources) { + mResourceMap.put(packageName, resources); + } + } + /** - * Registers WebAPK. + * Setups a new {@FakePackageManager}. + */ + public static void setUpPackageManager() { + FakePackageManager packageManager = new FakePackageManager(); + RuntimeEnvironment.setRobolectricPackageManager(packageManager); + } + + /** + * Registers WebAPK. This function also creates an empty resource for the WebAPK. * @param packageName The package to register * @param metaData Bundle with meta data from WebAPK's Android Manifest. */ public static void registerWebApkWithMetaData(String packageName, Bundle metaData) { RobolectricPackageManager packageManager = - (RobolectricPackageManager) RuntimeEnvironment.application.getPackageManager(); + RuntimeEnvironment.getRobolectricPackageManager(); + if (!(packageManager instanceof FakePackageManager)) { + setUpPackageManager(); + } + packageManager = RuntimeEnvironment.getRobolectricPackageManager(); + Resources res = Mockito.mock(Resources.class); + ((FakePackageManager) packageManager).setResourcesForTest(packageName, res); packageManager.addPackage(newPackageInfo(packageName, metaData)); } + /** Sets the resource for the given package name. */ + public static void setResource(String packageName, Resources res) { + RobolectricPackageManager packageManager = + RuntimeEnvironment.getRobolectricPackageManager(); + if (packageManager instanceof FakePackageManager) { + ((FakePackageManager) packageManager).setResourcesForTest(packageName, res); + } + } + private static PackageInfo newPackageInfo(String packageName, Bundle metaData) { ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.metaData = metaData;
diff --git a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc index 6ec3b8ed..a4b8cd12 100644 --- a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
@@ -1741,6 +1741,12 @@ // This test verifies that focusing an input inside a <webview> will put the // guest process's render widget into a monitoring mode for composition range // changes. +// Flaky on Mac (crbug.com/736759) +#if defined(OS_MACOSX) +#define MAYBE_CompositionRangeUpdates DISABLED_CompositionRangeUpdates +#else +#define MAYBE_CompositionRangeUpdates CompositionRangeUpdates +#endif IN_PROC_BROWSER_TEST_P(WebViewImeInteractiveTest, CompositionRangeUpdates) { ASSERT_TRUE(StartEmbeddedTestServer()); // For serving guest pages. LoadAndLaunchPlatformApp("web_view/ime", "WebViewImeTest.Launched");
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index 2e9944c6c..37e50251 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -14,11 +14,11 @@ #include "ash/autoclick/autoclick_controller.h" #include "ash/autoclick/mus/public/interfaces/autoclick.mojom.h" #include "ash/high_contrast/high_contrast_controller.h" +#include "ash/metrics/user_metrics_recorder.h" #include "ash/root_window_controller.h" #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_layout_manager.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/sticky_keys/sticky_keys_controller.h" #include "base/callback.h" #include "base/callback_helpers.h" @@ -473,7 +473,7 @@ ash::AccessibilityNotificationVisibility notify) { if (!profile_) return; - ash::ShellPort::Get()->RecordUserMetricsAction( + ash::Shell::Get()->metrics()->RecordUserMetricsAction( enabled ? ash::UMA_STATUS_AREA_ENABLE_SPOKEN_FEEDBACK : ash::UMA_STATUS_AREA_DISABLE_SPOKEN_FEEDBACK);
diff --git a/chrome/browser/chromeos/attestation/attestation_policy_browsertest.cc b/chrome/browser/chromeos/attestation/attestation_policy_browsertest.cc index c04bcc3..89df91a 100644 --- a/chrome/browser/chromeos/attestation/attestation_policy_browsertest.cc +++ b/chrome/browser/chromeos/attestation/attestation_policy_browsertest.cc
@@ -31,7 +31,7 @@ const chromeos::BoolDBusMethodCallback& callback) override { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(callback, chromeos::DBUS_METHOD_CALL_FAILURE, false)); + base::BindOnce(callback, chromeos::DBUS_METHOD_CALL_FAILURE, false)); } };
diff --git a/chrome/browser/chromeos/attestation/attestation_policy_observer.cc b/chrome/browser/chromeos/attestation/attestation_policy_observer.cc index 933996d..5b3b4a78 100644 --- a/chrome/browser/chromeos/attestation/attestation_policy_observer.cc +++ b/chrome/browser/chromeos/attestation/attestation_policy_observer.cc
@@ -311,8 +311,8 @@ if (++num_retries_ < kRetryLimit) { content::BrowserThread::PostDelayedTask( content::BrowserThread::UI, FROM_HERE, - base::Bind(&AttestationPolicyObserver::Start, - weak_factory_.GetWeakPtr()), + base::BindOnce(&AttestationPolicyObserver::Start, + weak_factory_.GetWeakPtr()), base::TimeDelta::FromSeconds(retry_delay_)); } else { LOG(WARNING) << "AttestationPolicyObserver: Retry limit exceeded.";
diff --git a/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc b/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc index 9f09b4d..2ac6fed9 100644 --- a/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc +++ b/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc
@@ -38,28 +38,28 @@ void DBusCallbackFalse(const BoolDBusMethodCallback& callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false)); + FROM_HERE, base::BindOnce(callback, DBUS_METHOD_CALL_SUCCESS, false)); } void DBusCallbackTrue(const BoolDBusMethodCallback& callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true)); + FROM_HERE, base::BindOnce(callback, DBUS_METHOD_CALL_SUCCESS, true)); } void DBusCallbackError(const BoolDBusMethodCallback& callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_FAILURE, false)); + FROM_HERE, base::BindOnce(callback, DBUS_METHOD_CALL_FAILURE, false)); } void CertCallbackSuccess(const AttestationFlow::CertificateCallback& callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, true, "fake_cert")); + FROM_HERE, base::BindOnce(callback, true, "fake_cert")); } void StatusCallbackSuccess( const policy::CloudPolicyClient::StatusCallback& callback) { base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, - base::Bind(callback, true)); + base::BindOnce(callback, true)); } class FakeDBusData { @@ -68,7 +68,8 @@ void operator() (const CryptohomeClient::DataMethodCallback& callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true, data_)); + FROM_HERE, + base::BindOnce(callback, DBUS_METHOD_CALL_SUCCESS, true, data_)); } private:
diff --git a/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc b/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc index f16d9d3..9e888a69 100644 --- a/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc +++ b/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc
@@ -104,13 +104,15 @@ void TpmAttestationIsEnrolled( const BoolDBusMethodCallback& callback) override { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, call_status_, attestation_enrolled_)); + FROM_HERE, + base::BindOnce(callback, call_status_, attestation_enrolled_)); } void TpmAttestationIsPrepared( const BoolDBusMethodCallback& callback) override { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, call_status_, attestation_prepared_)); + FROM_HERE, + base::BindOnce(callback, call_status_, attestation_prepared_)); } void set_call_status(DBusMethodCallStatus call_status) { @@ -186,15 +188,15 @@ (fake_certificate_index_ < fake_certificate_list_.size()) ? fake_certificate_list_[fake_certificate_index_] : kTestCertificate; base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, certificate_success_, certificate)); + FROM_HERE, base::BindOnce(callback, certificate_success_, certificate)); ++fake_certificate_index_; } void FakeSignChallenge( const cryptohome::AsyncMethodCaller::DataCallback& callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, sign_challenge_success_, - CreateFakeResponseProto())); + FROM_HERE, base::BindOnce(callback, sign_challenge_success_, + CreateFakeResponseProto())); } void FakeChallengeCallback(PlatformVerificationFlow::Result result,
diff --git a/chrome/browser/chromeos/policy/active_directory_policy_manager.cc b/chrome/browser/chromeos/policy/active_directory_policy_manager.cc index 23c19e9..195140d 100644 --- a/chrome/browser/chromeos/policy/active_directory_policy_manager.cc +++ b/chrome/browser/chromeos/policy/active_directory_policy_manager.cc
@@ -17,9 +17,9 @@ namespace { -// Refresh policy every 90 minutes which matches the Windows default: +// Fetch policy every 90 minutes which matches the Windows default: // https://technet.microsoft.com/en-us/library/cc940895.aspx -constexpr base::TimeDelta kRefreshInterval = base::TimeDelta::FromMinutes(90); +constexpr base::TimeDelta kFetchInterval = base::TimeDelta::FromMinutes(90); } // namespace @@ -56,11 +56,11 @@ PublishPolicy(); scheduler_ = base::MakeUnique<PolicyScheduler>( - base::BindRepeating(&ActiveDirectoryPolicyManager::DoRefresh, + base::BindRepeating(&ActiveDirectoryPolicyManager::DoFetch, weak_ptr_factory_.GetWeakPtr()), - base::BindRepeating(&ActiveDirectoryPolicyManager::OnPolicyRefreshed, + base::BindRepeating(&ActiveDirectoryPolicyManager::OnPolicyFetched, weak_ptr_factory_.GetWeakPtr()), - kRefreshInterval); + kFetchInterval); } void ActiveDirectoryPolicyManager::Shutdown() { @@ -117,7 +117,7 @@ UpdatePolicy(std::move(bundle)); } -void ActiveDirectoryPolicyManager::DoRefresh( +void ActiveDirectoryPolicyManager::DoFetch( base::OnceCallback<void(bool success)> callback) { chromeos::DBusThreadManager* thread_manager = chromeos::DBusThreadManager::Get(); @@ -132,9 +132,9 @@ } } -void ActiveDirectoryPolicyManager::OnPolicyRefreshed(bool success) { +void ActiveDirectoryPolicyManager::OnPolicyFetched(bool success) { if (!success) { - LOG(ERROR) << "Active Directory policy refresh failed."; + LOG(ERROR) << "Active Directory policy fetch failed."; } // Load independently of success or failure to keep up to date with whatever // has happened on the authpolicyd / session manager side.
diff --git a/chrome/browser/chromeos/policy/active_directory_policy_manager.h b/chrome/browser/chromeos/policy/active_directory_policy_manager.h index 598c545..46cf742 100644 --- a/chrome/browser/chromeos/policy/active_directory_policy_manager.h +++ b/chrome/browser/chromeos/policy/active_directory_policy_manager.h
@@ -58,10 +58,10 @@ // Calls into authpolicyd to fetch policy. Reports success or failure via // |callback|. - void DoRefresh(PolicyScheduler::TaskCallback callback); + void DoFetch(PolicyScheduler::TaskCallback callback); // Called by scheduler with result of policy fetch. - void OnPolicyRefreshed(bool success); + void OnPolicyFetched(bool success); const AccountId account_id_; std::unique_ptr<CloudPolicyStore> store_;
diff --git a/chrome/browser/chromeos/policy/cloud_external_data_manager_base.cc b/chrome/browser/chromeos/policy/cloud_external_data_manager_base.cc index 728adb2..ce71a60 100644 --- a/chrome/browser/chromeos/policy/cloud_external_data_manager_base.cc +++ b/chrome/browser/chromeos/policy/cloud_external_data_manager_base.cc
@@ -319,8 +319,8 @@ void CloudExternalDataManagerBase::Backend::RunCallback( const ExternalDataFetcher::FetchCallback& callback, std::unique_ptr<std::string> data) const { - callback_task_runner_->PostTask(FROM_HERE, - base::Bind(callback, base::Passed(&data))); + callback_task_runner_->PostTask( + FROM_HERE, base::BindOnce(callback, base::Passed(&data))); } void CloudExternalDataManagerBase::Backend::StartDownload( @@ -362,10 +362,10 @@ void CloudExternalDataManagerBase::SetExternalDataStore( std::unique_ptr<CloudExternalDataStore> external_data_store) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - backend_task_runner_->PostTask(FROM_HERE, base::Bind( - &Backend::SetExternalDataStore, - base::Unretained(backend_.get()), - base::Passed(&external_data_store))); + backend_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&Backend::SetExternalDataStore, + base::Unretained(backend_.get()), + base::Passed(&external_data_store))); } void CloudExternalDataManagerBase::SetPolicyStore( @@ -404,10 +404,10 @@ } } - backend_task_runner_->PostTask(FROM_HERE, base::Bind( - &Backend::OnMetadataUpdated, - base::Unretained(backend_.get()), - base::Passed(&metadata))); + backend_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&Backend::OnMetadataUpdated, + base::Unretained(backend_.get()), + base::Passed(&metadata))); } void CloudExternalDataManagerBase::Connect( @@ -417,27 +417,31 @@ external_policy_data_fetcher_backend_.reset( new ExternalPolicyDataFetcherBackend(io_task_runner_, request_context)); - backend_task_runner_->PostTask(FROM_HERE, base::Bind( - &Backend::Connect, - base::Unretained(backend_.get()), - base::Passed(external_policy_data_fetcher_backend_->CreateFrontend( - backend_task_runner_)))); + backend_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &Backend::Connect, base::Unretained(backend_.get()), + base::Passed(external_policy_data_fetcher_backend_->CreateFrontend( + backend_task_runner_)))); } void CloudExternalDataManagerBase::Disconnect() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); io_task_runner_->DeleteSoon(FROM_HERE, external_policy_data_fetcher_backend_.release()); - backend_task_runner_->PostTask(FROM_HERE, base::Bind( - &Backend::Disconnect, base::Unretained(backend_.get()))); + backend_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&Backend::Disconnect, base::Unretained(backend_.get()))); } void CloudExternalDataManagerBase::Fetch( const std::string& policy, const ExternalDataFetcher::FetchCallback& callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - backend_task_runner_->PostTask(FROM_HERE, base::Bind( - &Backend::Fetch, base::Unretained(backend_.get()), policy, callback)); + backend_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&Backend::Fetch, base::Unretained(backend_.get()), policy, + callback)); } // static @@ -448,8 +452,9 @@ void CloudExternalDataManagerBase::FetchAll() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - backend_task_runner_->PostTask(FROM_HERE, base::Bind( - &Backend::FetchAll, base::Unretained(backend_.get()))); + backend_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&Backend::FetchAll, base::Unretained(backend_.get()))); } } // namespace policy
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc index 97308740..bf385518 100644 --- a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc +++ b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
@@ -90,7 +90,7 @@ const chromeos::attestation::AttestationFlow::CertificateCallback& callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, true, "fake_cert")); + FROM_HERE, base::BindOnce(callback, true, "fake_cert")); } class TestingDeviceCloudPolicyManagerChromeOS
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc index 38a541ba..cef7441 100644 --- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -526,7 +526,7 @@ // This shuts down the login UI. base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&chrome::AttemptExit)); + FROM_HERE, base::BindOnce(&chrome::AttemptExit)); base::RunLoop().RunUntilIdle(); }
diff --git a/chrome/browser/chromeos/policy/device_local_account_external_data_service.cc b/chrome/browser/chromeos/policy/device_local_account_external_data_service.cc index 3e38624a..92eb02e 100644 --- a/chrome/browser/chromeos/policy/device_local_account_external_data_service.cc +++ b/chrome/browser/chromeos/policy/device_local_account_external_data_service.cc
@@ -61,10 +61,10 @@ ++it; } } - backend_task_runner_->PostTask(FROM_HERE, base::Bind( - &ResourceCache::PurgeOtherKeys, - base::Unretained(resource_cache_.get()), - account_ids)); + backend_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&ResourceCache::PurgeOtherKeys, + base::Unretained(resource_cache_.get()), account_ids)); } scoped_refptr<DeviceLocalAccountExternalDataManager>
diff --git a/chrome/browser/chromeos/policy/device_local_account_policy_service.cc b/chrome/browser/chromeos/policy/device_local_account_policy_service.cc index 26c8188..a20dbfab 100644 --- a/chrome/browser/chromeos/policy/device_local_account_policy_service.cc +++ b/chrome/browser/chromeos/policy/device_local_account_policy_service.cc
@@ -391,12 +391,10 @@ // be removed. The directory must stay marked as busy while the removal is in // progress. extension_cache_task_runner_->PostTaskAndReply( - FROM_HERE, - base::Bind(&DeleteObsoleteExtensionCache, account_id), - base::Bind(&DeviceLocalAccountPolicyService:: - OnObsoleteExtensionCacheDeleted, - weak_factory_.GetWeakPtr(), - account_id)); + FROM_HERE, base::BindOnce(&DeleteObsoleteExtensionCache, account_id), + base::BindOnce( + &DeviceLocalAccountPolicyService::OnObsoleteExtensionCacheDeleted, + weak_factory_.GetWeakPtr(), account_id)); } void DeviceLocalAccountPolicyService::OnObsoleteExtensionCacheDeleted( @@ -509,9 +507,9 @@ &cache_root_dir)); extension_cache_task_runner_->PostTaskAndReply( FROM_HERE, - base::Bind( - &DeleteOrphanedCaches, cache_root_dir, subdirectories_to_keep), - base::Bind( + base::BindOnce(&DeleteOrphanedCaches, cache_root_dir, + subdirectories_to_keep), + base::BindOnce( &DeviceLocalAccountPolicyService::OnOrphanedExtensionCachesDeleted, weak_factory_.GetWeakPtr())); @@ -536,10 +534,10 @@ // TODO(joaodasilva): for now this must be posted to the FILE thread, // to avoid racing with the ComponentCloudPolicyStore. Use a task runner // once that class supports another background thread too. - content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, - base::Bind(&DeleteOrphanedCaches, - component_policy_cache_root_, - subdirectories_to_keep)); + content::BrowserThread::PostTask( + content::BrowserThread::FILE, FROM_HERE, + base::BindOnce(&DeleteOrphanedCaches, component_policy_cache_root_, + subdirectories_to_keep)); for (auto& observer : observers_) observer.OnDeviceLocalAccountsChanged();
diff --git a/chrome/browser/chromeos/policy/device_status_collector.cc b/chrome/browser/chromeos/policy/device_status_collector.cc index 3c7445e..fab14678 100644 --- a/chrome/browser/chromeos/policy/device_status_collector.cc +++ b/chrome/browser/chromeos/policy/device_status_collector.cc
@@ -393,9 +393,9 @@ // async query, the query holds a reference to us, so the destructor is // not called. ~GetStatusState() { - task_runner_->PostTask(FROM_HERE, - base::Bind(response_, base::Passed(&device_status_), - base::Passed(&session_status_))); + task_runner_->PostTask( + FROM_HERE, base::BindOnce(response_, base::Passed(&device_status_), + base::Passed(&session_status_))); } void OnVolumeInfoReceived(const std::vector<em::VolumeInfo>& volume_info) {
diff --git a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc index 0afa872e..e408233 100644 --- a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
@@ -245,8 +245,8 @@ const policy::DeviceStatusCollector::AndroidStatusReceiver& receiver) { // Post it to the thread because this call is expected to be asynchronous. base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&CallAndroidStatusReceiver, receiver, - status, droid_guard_info)); + FROM_HERE, base::BindOnce(&CallAndroidStatusReceiver, receiver, status, + droid_guard_info)); return true; } @@ -254,7 +254,7 @@ const policy::DeviceStatusCollector::AndroidStatusReceiver& receiver) { // Post it to the thread because this call is expected to be asynchronous. base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&CallAndroidStatusReceiver, receiver, "", "")); + FROM_HERE, base::BindOnce(&CallAndroidStatusReceiver, receiver, "", "")); return true; }
diff --git a/chrome/browser/chromeos/policy/device_system_use_24hour_clock_browsertest.cc b/chrome/browser/chromeos/policy/device_system_use_24hour_clock_browsertest.cc index 233c124..8302e05 100644 --- a/chrome/browser/chromeos/policy/device_system_use_24hour_clock_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_system_use_24hour_clock_browsertest.cc
@@ -52,7 +52,7 @@ // If the login display is still showing, exit gracefully. if (LoginDisplayHost::default_host()) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&chrome::AttemptExit)); + FROM_HERE, base::BindOnce(&chrome::AttemptExit)); content::RunMessageLoop(); } }
diff --git a/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc b/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc index 140fdce9..c2409019 100644 --- a/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc +++ b/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc
@@ -92,7 +92,7 @@ // If the login display is still showing, exit gracefully. if (chromeos::LoginDisplayHost::default_host()) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&chrome::AttemptExit)); + FROM_HERE, base::BindOnce(&chrome::AttemptExit)); content::RunMessageLoop(); } }
diff --git a/chrome/browser/chromeos/policy/dm_token_storage_unittest.cc b/chrome/browser/chromeos/policy/dm_token_storage_unittest.cc index bce508e..9d753b25 100644 --- a/chrome/browser/chromeos/policy/dm_token_storage_unittest.cc +++ b/chrome/browser/chromeos/policy/dm_token_storage_unittest.cc
@@ -67,8 +67,8 @@ base::RunLoop run_loop; dm_token_storage_->StoreDMToken( "test-token", - base::Bind(&DMTokenStorageTest::OnStoreCallback, base::Unretained(this), - run_loop.QuitClosure(), true)); + base::BindOnce(&DMTokenStorageTest::OnStoreCallback, + base::Unretained(this), run_loop.QuitClosure(), true)); run_loop.Run(); } @@ -100,7 +100,7 @@ { base::RunLoop run_loop; - dm_token_storage_->RetrieveDMToken(base::Bind( + dm_token_storage_->RetrieveDMToken(base::BindOnce( &DMTokenStorageTest::OnRetrieveCallback, base::Unretained(this), run_loop.QuitClosure(), "test-token")); run_loop.Run(); @@ -109,7 +109,7 @@ CreateDMStorage(); { base::RunLoop run_loop; - dm_token_storage_->RetrieveDMToken(base::Bind( + dm_token_storage_->RetrieveDMToken(base::BindOnce( &DMTokenStorageTest::OnRetrieveCallback, base::Unretained(this), run_loop.QuitClosure(), "test-token")); run_loop.Run(); @@ -117,7 +117,7 @@ { // Subsequent retrieving DM token should succeed. base::RunLoop run_loop; - dm_token_storage_->RetrieveDMToken(base::Bind( + dm_token_storage_->RetrieveDMToken(base::BindOnce( &DMTokenStorageTest::OnRetrieveCallback, base::Unretained(this), run_loop.QuitClosure(), "test-token")); run_loop.Run(); @@ -133,7 +133,7 @@ { base::RunLoop run_loop; - dm_token_storage_->RetrieveDMToken(base::Bind( + dm_token_storage_->RetrieveDMToken(base::BindOnce( &DMTokenStorageTest::OnRetrieveCallback, base::Unretained(this), run_loop.QuitClosure(), "test-token")); SetSaltAvailable(); @@ -147,8 +147,8 @@ base::RunLoop run_loop; dm_token_storage_->StoreDMToken( "test-token", - base::Bind(&DMTokenStorageTest::OnStoreCallback, base::Unretained(this), - run_loop.QuitClosure(), true)); + base::BindOnce(&DMTokenStorageTest::OnStoreCallback, + base::Unretained(this), run_loop.QuitClosure(), true)); SetSaltAvailable(); run_loop.Run(); } @@ -159,7 +159,7 @@ { base::RunLoop run_loop; for (int i = 0; i < 3; ++i) { - dm_token_storage_->RetrieveDMToken(base::Bind( + dm_token_storage_->RetrieveDMToken(base::BindOnce( &DMTokenStorageTest::OnRetrieveCallback, base::Unretained(this), run_loop.QuitClosure(), "test-token")); } @@ -173,8 +173,8 @@ base::RunLoop run_loop; dm_token_storage_->StoreDMToken( "test-token", - base::Bind(&DMTokenStorageTest::OnStoreCallback, base::Unretained(this), - run_loop.QuitClosure(), false)); + base::BindOnce(&DMTokenStorageTest::OnStoreCallback, + base::Unretained(this), run_loop.QuitClosure(), false)); run_loop.Run(); } @@ -185,8 +185,8 @@ CreateDMStorage(); base::RunLoop run_loop; dm_token_storage_->RetrieveDMToken( - base::Bind(&DMTokenStorageTest::OnRetrieveCallback, - base::Unretained(this), run_loop.QuitClosure(), "")); + base::BindOnce(&DMTokenStorageTest::OnRetrieveCallback, + base::Unretained(this), run_loop.QuitClosure(), "")); SetSaltError(); run_loop.Run(); } @@ -195,8 +195,8 @@ CreateDMStorage(); base::RunLoop run_loop; dm_token_storage_->RetrieveDMToken( - base::Bind(&DMTokenStorageTest::OnRetrieveCallback, - base::Unretained(this), run_loop.QuitClosure(), "")); + base::BindOnce(&DMTokenStorageTest::OnRetrieveCallback, + base::Unretained(this), run_loop.QuitClosure(), "")); run_loop.Run(); } @@ -206,11 +206,11 @@ base::RunLoop run_loop; dm_token_storage_->StoreDMToken( "test-token", - base::Bind(&DMTokenStorageTest::OnStoreCallback, base::Unretained(this), - run_loop.QuitClosure(), true)); + base::BindOnce(&DMTokenStorageTest::OnStoreCallback, + base::Unretained(this), run_loop.QuitClosure(), true)); dm_token_storage_->RetrieveDMToken( - base::Bind(&DMTokenStorageTest::OnRetrieveCallback, - base::Unretained(this), base::Closure(), "")); + base::BindOnce(&DMTokenStorageTest::OnRetrieveCallback, + base::Unretained(this), base::Closure(), "")); SetSaltAvailable(); run_loop.Run(); } @@ -221,11 +221,12 @@ base::RunLoop run_loop; dm_token_storage_->StoreDMToken( "test-token", - base::Bind(&DMTokenStorageTest::OnStoreCallback, base::Unretained(this), - run_loop.QuitClosure(), true)); + base::BindOnce(&DMTokenStorageTest::OnStoreCallback, + base::Unretained(this), run_loop.QuitClosure(), true)); dm_token_storage_->StoreDMToken( - "test-token", base::Bind(&DMTokenStorageTest::OnStoreCallback, - base::Unretained(this), base::Closure(), false)); + "test-token", + base::BindOnce(&DMTokenStorageTest::OnStoreCallback, + base::Unretained(this), base::Closure(), false)); SetSaltAvailable(); run_loop.Run(); }
diff --git a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc index 40fcb27..a7b968e 100644 --- a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc +++ b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc
@@ -539,8 +539,9 @@ LOG(WARNING) << "Install Attributes not ready yet will retry in " << kLockRetryIntervalMs << "ms."; base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, base::Bind(&EnrollmentHandlerChromeOS::StartLockDevice, - weak_ptr_factory_.GetWeakPtr()), + FROM_HERE, + base::BindOnce(&EnrollmentHandlerChromeOS::StartLockDevice, + weak_ptr_factory_.GetWeakPtr()), base::TimeDelta::FromMilliseconds(kLockRetryIntervalMs)); lockbox_init_duration_ += kLockRetryIntervalMs; } else { @@ -567,8 +568,8 @@ g_browser_process->local_state()); dm_token_storage_->StoreDMToken( client_->dm_token(), - base::Bind(&EnrollmentHandlerChromeOS::HandleDMTokenStoreResult, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&EnrollmentHandlerChromeOS::HandleDMTokenStoreResult, + weak_ptr_factory_.GetWeakPtr())); } void EnrollmentHandlerChromeOS::StartStoreRobotAuth() { @@ -605,7 +606,7 @@ install_attributes_->GetMode()); chromeos::DBusThreadManager::Get() ->GetAuthPolicyClient() - ->RefreshDevicePolicy(base::Bind( + ->RefreshDevicePolicy(base::BindOnce( &EnrollmentHandlerChromeOS::HandleActiveDirectoryPolicyRefreshed, weak_ptr_factory_.GetWeakPtr())); } else {
diff --git a/chrome/browser/chromeos/policy/heartbeat_scheduler.cc b/chrome/browser/chromeos/policy/heartbeat_scheduler.cc index bb831ec..4378701 100644 --- a/chrome/browser/chromeos/policy/heartbeat_scheduler.cc +++ b/chrome/browser/chromeos/policy/heartbeat_scheduler.cc
@@ -152,8 +152,8 @@ // Transient error - try again after a delay. task_runner_->PostDelayedTask( FROM_HERE, - base::Bind(&HeartbeatRegistrationHelper::AttemptRegistration, - weak_factory_.GetWeakPtr()), + base::BindOnce(&HeartbeatRegistrationHelper::AttemptRegistration, + weak_factory_.GetWeakPtr()), base::TimeDelta::FromMilliseconds(kRegistrationRetryDelayMs)); break;
diff --git a/chrome/browser/chromeos/policy/login_screen_default_policy_browsertest.cc b/chrome/browser/chromeos/policy/login_screen_default_policy_browsertest.cc index a60e978..2fb50b2 100644 --- a/chrome/browser/chromeos/policy/login_screen_default_policy_browsertest.cc +++ b/chrome/browser/chromeos/policy/login_screen_default_policy_browsertest.cc
@@ -192,7 +192,7 @@ void LoginScreenDefaultPolicyLoginScreenBrowsertest::TearDownOnMainThread() { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&chrome::AttemptExit)); + FROM_HERE, base::BindOnce(&chrome::AttemptExit)); base::RunLoop().RunUntilIdle(); LoginScreenDefaultPolicyBrowsertestBase::TearDownOnMainThread(); }
diff --git a/chrome/browser/chromeos/policy/policy_cert_service.cc b/chrome/browser/chromeos/policy/policy_cert_service.cc index 2d77e53e..85af6d1 100644 --- a/chrome/browser/chromeos/policy/policy_cert_service.cc +++ b/chrome/browser/chromeos/policy/policy_cert_service.cc
@@ -89,11 +89,9 @@ // Note: ProfileIOData, which owns the CertVerifier is deleted by a // DeleteSoon on IO, i.e. after all pending tasks on IO are finished. content::BrowserThread::PostTask( - content::BrowserThread::IO, - FROM_HERE, - base::Bind(&PolicyCertVerifier::SetTrustAnchors, - base::Unretained(cert_verifier_), - trust_anchors)); + content::BrowserThread::IO, FROM_HERE, + base::BindOnce(&PolicyCertVerifier::SetTrustAnchors, + base::Unretained(cert_verifier_), trust_anchors)); } bool PolicyCertService::UsedPolicyCertificates() const {
diff --git a/chrome/browser/chromeos/policy/power_policy_browsertest.cc b/chrome/browser/chromeos/policy/power_policy_browsertest.cc index 5726d26..4dfb14a 100644 --- a/chrome/browser/chromeos/policy/power_policy_browsertest.cc +++ b/chrome/browser/chromeos/policy/power_policy_browsertest.cc
@@ -302,7 +302,7 @@ void PowerPolicyLoginScreenBrowserTest::TearDownOnMainThread() { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&chrome::AttemptExit)); + FROM_HERE, base::BindOnce(&chrome::AttemptExit)); base::RunLoop().RunUntilIdle(); PowerPolicyBrowserTestBase::TearDownOnMainThread(); }
diff --git a/chrome/browser/chromeos/policy/remote_commands/device_command_fetch_status_job.cc b/chrome/browser/chromeos/policy/remote_commands/device_command_fetch_status_job.cc index 909175c..ecf3bcc1 100644 --- a/chrome/browser/chromeos/policy/remote_commands/device_command_fetch_status_job.cc +++ b/chrome/browser/chromeos/policy/remote_commands/device_command_fetch_status_job.cc
@@ -62,12 +62,12 @@ manager->GetStatusUploader()->ScheduleNextStatusUploadImmediately(); manager->GetSystemLogUploader()->ScheduleNextSystemLogUploadImmediately(); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(succeeded_callback, nullptr)); + FROM_HERE, base::BindOnce(succeeded_callback, nullptr)); return; } base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(failed_callback, nullptr)); + FROM_HERE, base::BindOnce(failed_callback, nullptr)); } } // namespace policy
diff --git a/chrome/browser/chromeos/policy/remote_commands/device_command_reboot_job.cc b/chrome/browser/chromeos/policy/remote_commands/device_command_reboot_job.cc index 6e777b0..d195edf 100644 --- a/chrome/browser/chromeos/policy/remote_commands/device_command_reboot_job.cc +++ b/chrome/browser/chromeos/policy/remote_commands/device_command_reboot_job.cc
@@ -63,7 +63,7 @@ SYSLOG(WARNING) << "Ignoring reboot command issued " << delta << " before current boot time"; base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(succeeded_callback, nullptr)); + FROM_HERE, base::BindOnce(succeeded_callback, nullptr)); return; }
diff --git a/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job.cc b/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job.cc index 249f3d9..e2e615a 100644 --- a/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job.cc +++ b/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job.cc
@@ -62,7 +62,7 @@ scoped_refptr<base::TaskRunner> task_runner, scoped_refptr<base::RefCountedMemory> png_data) { task_runner->PostTask(FROM_HERE, - base::Bind(store_screenshot_callback, png_data)); + base::BindOnce(store_screenshot_callback, png_data)); } } // namespace @@ -112,8 +112,9 @@ void DeviceCommandScreenshotJob::OnSuccess() { SYSLOG(INFO) << "Upload successful."; base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(succeeded_callback_, - base::Passed(base::MakeUnique<Payload>(SUCCESS)))); + FROM_HERE, + base::BindOnce(succeeded_callback_, + base::Passed(base::MakeUnique<Payload>(SUCCESS)))); } void DeviceCommandScreenshotJob::OnFailure(UploadJob::ErrorCode error_code) { @@ -130,8 +131,8 @@ } base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(failed_callback_, - base::Passed(base::MakeUnique<Payload>(result_code)))); + base::BindOnce(failed_callback_, + base::Passed(base::MakeUnique<Payload>(result_code)))); } bool DeviceCommandScreenshotJob::IsExpired(base::TimeTicks now) { @@ -199,8 +200,8 @@ SYSLOG(ERROR) << "Screenshots are not allowed."; base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(failed_callback_, base::Passed(base::MakeUnique<Payload>( - FAILURE_USER_INPUT)))); + base::BindOnce(failed_callback_, base::Passed(base::MakeUnique<Payload>( + FAILURE_USER_INPUT)))); } aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows(); @@ -210,8 +211,8 @@ SYSLOG(ERROR) << upload_url_ << " is not a valid URL."; base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(failed_callback_, base::Passed(base::MakeUnique<Payload>( - FAILURE_INVALID_URL)))); + base::BindOnce(failed_callback_, base::Passed(base::MakeUnique<Payload>( + FAILURE_INVALID_URL)))); return; } @@ -220,8 +221,8 @@ SYSLOG(ERROR) << "No attached screens."; base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(failed_callback_, base::Passed(base::MakeUnique<Payload>( - FAILURE_SCREENSHOT_ACQUISITION)))); + base::BindOnce(failed_callback_, base::Passed(base::MakeUnique<Payload>( + FAILURE_SCREENSHOT_ACQUISITION)))); return; }
diff --git a/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job_unittest.cc b/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job_unittest.cc index 72b3b4e5..1fa8b59 100644 --- a/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job_unittest.cc +++ b/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job_unittest.cc
@@ -106,13 +106,13 @@ EXPECT_EQ(kMockUploadUrl, upload_url_.spec()); if (error_code_) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&UploadJob::Delegate::OnFailure, - base::Unretained(delegate_), *error_code_)); + FROM_HERE, base::BindOnce(&UploadJob::Delegate::OnFailure, + base::Unretained(delegate_), *error_code_)); return; } base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(&UploadJob::Delegate::OnSuccess, base::Unretained(delegate_))); + FROM_HERE, base::BindOnce(&UploadJob::Delegate::OnSuccess, + base::Unretained(delegate_))); } scoped_refptr<base::RefCountedBytes> GenerateTestPNG(const int& width, @@ -177,8 +177,8 @@ const int height = source_rect.height(); scoped_refptr<base::RefCountedBytes> test_png = GenerateTestPNG(width, height); - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, - base::Bind(callback, test_png)); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(callback, test_png)); } std::unique_ptr<UploadJob> MockScreenshotDelegate::CreateUploadJob(
diff --git a/chrome/browser/chromeos/policy/remote_commands/device_command_set_volume_job.cc b/chrome/browser/chromeos/policy/remote_commands/device_command_set_volume_job.cc index 993f378..7437130 100644 --- a/chrome/browser/chromeos/policy/remote_commands/device_command_set_volume_job.cc +++ b/chrome/browser/chromeos/policy/remote_commands/device_command_set_volume_job.cc
@@ -71,7 +71,7 @@ audio_handler->SetOutputMute(mute); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(succeeded_callback, nullptr)); + FROM_HERE, base::BindOnce(succeeded_callback, nullptr)); } } // namespace policy
diff --git a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc index db32df02..526dbe8 100644 --- a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc +++ b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc
@@ -97,8 +97,8 @@ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, - base::Bind(&ServerBackedStateKeysBroker::FetchStateKeys, - weak_factory_.GetWeakPtr()), + base::BindOnce(&ServerBackedStateKeysBroker::FetchStateKeys, + weak_factory_.GetWeakPtr()), kPollInterval); }
diff --git a/chrome/browser/chromeos/policy/system_log_uploader.cc b/chrome/browser/chromeos/policy/system_log_uploader.cc index 7a97883..f49a4da1 100644 --- a/chrome/browser/chromeos/policy/system_log_uploader.cc +++ b/chrome/browser/chromeos/policy/system_log_uploader.cc
@@ -341,10 +341,11 @@ // Ensure that we never have more than one pending delayed task // (InvalidateWeakPtrs() will cancel any pending log uploads). weak_factory_.InvalidateWeakPtrs(); - task_runner_->PostDelayedTask(FROM_HERE, - base::Bind(&SystemLogUploader::StartLogUpload, - weak_factory_.GetWeakPtr()), - delay); + task_runner_->PostDelayedTask( + FROM_HERE, + base::BindOnce(&SystemLogUploader::StartLogUpload, + weak_factory_.GetWeakPtr()), + delay); } } // namespace policy
diff --git a/chrome/browser/chromeos/policy/upload_job_impl.cc b/chrome/browser/chromeos/policy/upload_job_impl.cc index c74b147..834294e 100644 --- a/chrome/browser/chromeos/policy/upload_job_impl.cc +++ b/chrome/browser/chromeos/policy/upload_job_impl.cc
@@ -378,8 +378,9 @@ access_token_); access_token_.clear(); task_runner_->PostDelayedTask( - FROM_HERE, base::Bind(&UploadJobImpl::RequestAccessToken, - weak_factory_.GetWeakPtr()), + FROM_HERE, + base::BindOnce(&UploadJobImpl::RequestAccessToken, + weak_factory_.GetWeakPtr()), base::TimeDelta::FromMilliseconds(g_retry_delay_ms)); } else { // Retry without a new token. @@ -387,7 +388,8 @@ SYSLOG(WARNING) << "Retrying upload with the same token."; task_runner_->PostDelayedTask( FROM_HERE, - base::Bind(&UploadJobImpl::StartUpload, weak_factory_.GetWeakPtr()), + base::BindOnce(&UploadJobImpl::StartUpload, + weak_factory_.GetWeakPtr()), base::TimeDelta::FromMilliseconds(g_retry_delay_ms)); } }
diff --git a/chrome/browser/chromeos/policy/upload_job_unittest.cc b/chrome/browser/chromeos/policy/upload_job_unittest.cc index 0e0f9b59..896195ea 100644 --- a/chrome/browser/chromeos/policy/upload_job_unittest.cc +++ b/chrome/browser/chromeos/policy/upload_job_unittest.cc
@@ -118,9 +118,10 @@ token_replies_.pop(); } base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&OAuth2TokenService::RequestImpl::InformConsumer, - request->AsWeakPtr(), response_error, access_token, - response_expiration)); + FROM_HERE, + base::BindOnce(&OAuth2TokenService::RequestImpl::InformConsumer, + request->AsWeakPtr(), response_error, access_token, + response_expiration)); } void MockOAuth2TokenService::AddTokenToQueue(const std::string& token) {
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc index 82d1ffa..b2e6fa9f 100644 --- a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc +++ b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc
@@ -305,10 +305,11 @@ std::string* key = new std::string(); background_task_runner()->PostTaskAndReply( - FROM_HERE, base::Bind(&UserCloudPolicyStoreChromeOS::LoadPolicyKey, - cached_policy_key_path_, key), - base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded, - weak_factory_.GetWeakPtr(), base::Owned(key), callback)); + FROM_HERE, + base::BindOnce(&UserCloudPolicyStoreChromeOS::LoadPolicyKey, + cached_policy_key_path_, key), + base::BindOnce(&UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded, + weak_factory_.GetWeakPtr(), base::Owned(key), callback)); } // static
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc index 7a7d2f5..ca3786cb 100644 --- a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc +++ b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc
@@ -57,7 +57,7 @@ ACTION_P2(SendSanitizedUsername, call_status, sanitized_username) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(arg1, call_status, sanitized_username)); + FROM_HERE, base::BindOnce(arg1, call_status, sanitized_username)); } class UserCloudPolicyStoreChromeOSTest : public testing::Test {
diff --git a/chrome/browser/resources/pdf/elements/viewer-page-indicator/viewer-page-indicator.js b/chrome/browser/resources/pdf/elements/viewer-page-indicator/viewer-page-indicator.js index 70147ab5..96f7f3d 100644 --- a/chrome/browser/resources/pdf/elements/viewer-page-indicator/viewer-page-indicator.js +++ b/chrome/browser/resources/pdf/elements/viewer-page-indicator/viewer-page-indicator.js
@@ -31,14 +31,15 @@ /** @param {number} displayTime */ fadeIn: function(displayTime) { var percent = window.scrollY / - (document.body.scrollHeight - document.documentElement.clientHeight); + (document.scrollingElement.scrollHeight - + document.documentElement.clientHeight); this.style.top = percent * (document.documentElement.clientHeight - this.offsetHeight) + 'px'; // <if expr="is_macosx"> // On the Mac, if overlay scrollbars are enabled, prevent them from // overlapping the triangle. - if (window.innerWidth == document.body.scrollWidth) + if (window.innerWidth == document.scrollingElement.scrollWidth) this.style.right = '16px'; else this.style.right = '0px';
diff --git a/chrome/browser/ui/ash/launcher/launcher_context_menu.cc b/chrome/browser/ui/ash/launcher/launcher_context_menu.cc index 8df12d96..abbb6f40 100644 --- a/chrome/browser/ui/ash/launcher/launcher_context_menu.cc +++ b/chrome/browser/ui/ash/launcher/launcher_context_menu.cc
@@ -6,11 +6,11 @@ #include <string> +#include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/shelf_model.h" #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_widget.h" #include "ash/shell.h" -#include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/wallpaper/wallpaper_delegate.h" #include "ash/wm/maximize_mode/maximize_mode_controller.h" @@ -125,12 +125,12 @@ // TODO(simonhong): Use ShelfItemDelegate::Close(). controller_->Close(item_.id); } - ash::ShellPort::Get()->RecordUserMetricsAction( + ash::Shell::Get()->metrics()->RecordUserMetricsAction( ash::UMA_CLOSE_THROUGH_CONTEXT_MENU); if (ash::Shell::Get() ->maximize_mode_controller() ->IsMaximizeModeWindowManagerEnabled()) { - ash::ShellPort::Get()->RecordUserMetricsAction( + ash::Shell::Get()->metrics()->RecordUserMetricsAction( ash::UMA_TABLET_WINDOW_CLOSE_THROUGH_CONTXT_MENU); } break;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm index 87282df..304687d21 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm
@@ -496,4 +496,18 @@ return title; } +- (id)accessibilityAttributeValue:(NSString*)attribute { + // The buttons on the bookmark bar are like popup buttons, in that they make a + // new menu appear, so they ascribe to that role. All other items in the + // bookmark menus end up being "buttons". This logic detects bookmark bar + // buttons as those which have a corresponding folder but are not actually + // folder buttons, which are used inside the bookmark menus. + // TODO(lgrey): move menus over to using the MenuItem role + if ([attribute isEqual:NSAccessibilityRoleAttribute] && [self bookmarkNode] && + [self bookmarkNode]->is_folder() && ![self isFolderButtonCell]) { + return NSAccessibilityPopUpButtonRole; + } + return [super accessibilityAttributeValue:attribute]; +} + @end
diff --git a/chromecast/browser/test/cast_features_browsertest.cc b/chromecast/browser/test/cast_features_browsertest.cc index 67071f3..dacbc34 100644 --- a/chromecast/browser/test/cast_features_browsertest.cc +++ b/chromecast/browser/test/cast_features_browsertest.cc
@@ -290,8 +290,14 @@ ASSERT_TRUE(GetDCSExperimentIds().empty()); } +#if defined(OS_LINUX) +#define MAYBE_TestExperimentIdsPersisted DISABLED_TestExperimentIdsPersisted +#else +#define MAYBE_TestExperimentIdsPersisted TestExperimentIdsPersisted +#endif // Test that experiment ids are persisted to disk. Part 3 of 3. -IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, TestExperimentIdsPersisted) { +IN_PROC_BROWSER_TEST_F(CastFeaturesBrowserTest, + MAYBE_TestExperimentIdsPersisted) { // The experiments set in the last run should be active now. std::unordered_set<int32_t> ids({1234, 1, 4000}); ASSERT_EQ(ids, GetDCSExperimentIds());
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host.cc b/content/browser/renderer_host/media/audio_input_renderer_host.cc index 439da33..dc96e62 100644 --- a/content/browser/renderer_host/media/audio_input_renderer_host.cc +++ b/content/browser/renderer_host/media/audio_input_renderer_host.cc
@@ -135,12 +135,12 @@ BrowserThread::DeleteOnIOThread::Destruct(this); } -void AudioInputRendererHost::OnCreated( - media::AudioInputController* controller) { +void AudioInputRendererHost::OnCreated(media::AudioInputController* controller, + bool initially_muted) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::BindOnce(&AudioInputRendererHost::DoCompleteCreation, this, - base::RetainedRef(controller))); + base::RetainedRef(controller), initially_muted)); } void AudioInputRendererHost::OnError(media::AudioInputController* controller, @@ -173,7 +173,8 @@ } void AudioInputRendererHost::DoCompleteCreation( - media::AudioInputController* controller) { + media::AudioInputController* controller, + bool initially_muted) { DCHECK_CURRENTLY_ON(BrowserThread::IO); AudioEntry* entry = LookupByController(controller); @@ -205,13 +206,15 @@ } LogMessage(entry->stream_id, - "DoCompleteCreation: IPC channel and stream are now open", + base::StringPrintf("DoCompleteCreation: IPC channel and stream " + "are now open (initially %s", + initially_muted ? "muted" : "not muted"), true); Send(new AudioInputMsg_NotifyStreamCreated( entry->stream_id, foreign_memory_handle, socket_transit_descriptor, writer->shared_memory()->requested_size(), - writer->shared_memory_segment_count())); + writer->shared_memory_segment_count(), initially_muted)); // Free the foreign socket on here since it isn't needed anymore in this // process.
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host.h b/content/browser/renderer_host/media/audio_input_renderer_host.h index 47682e3..281a83a5 100644 --- a/content/browser/renderer_host/media/audio_input_renderer_host.h +++ b/content/browser/renderer_host/media/audio_input_renderer_host.h
@@ -110,7 +110,8 @@ bool OnMessageReceived(const IPC::Message& message) override; // AudioInputController::EventHandler implementation. - void OnCreated(media::AudioInputController* controller) override; + void OnCreated(media::AudioInputController* controller, + bool initially_muted) override; void OnError(media::AudioInputController* controller, media::AudioInputController::ErrorCode error_code) override; void OnLog(media::AudioInputController* controller, @@ -165,7 +166,8 @@ // Complete the process of creating an audio input stream. This will set up // the shared memory or shared socket in low latency mode and send the // NotifyStreamCreated message to the peer. - void DoCompleteCreation(media::AudioInputController* controller); + void DoCompleteCreation(media::AudioInputController* controller, + bool initially_muted); // Send a state change message to the renderer. void DoSendRecordingMessage(media::AudioInputController* controller);
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc b/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc index 24881e1..c441897 100644 --- a/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc +++ b/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc
@@ -77,12 +77,13 @@ class MockRenderer { public: - MOCK_METHOD5(NotifyStreamCreated, + MOCK_METHOD6(NotifyStreamCreated, void(int /*stream_id*/, base::SharedMemoryHandle /*handle*/, base::SyncSocket::TransitDescriptor /*socket_desriptor*/, uint32_t /*length*/, - uint32_t /*total_segments*/)); + uint32_t /*total_segments*/, + bool initially_muted)); MOCK_METHOD1(NotifyStreamError, void(int /*stream_id*/)); MOCK_METHOD0(WasShutDown, void()); }; @@ -138,7 +139,8 @@ base::SharedMemoryHandle handle, base::SyncSocket::TransitDescriptor socket_descriptor, uint32_t length, - uint32_t total_segments) { + uint32_t total_segments, + bool initially_muted) { // It's difficult to check that the sync socket and shared memory is // valid in the gmock macros, so we check them here. EXPECT_NE(base::SyncSocket::UnwrapHandle(socket_descriptor), @@ -146,7 +148,7 @@ base::SharedMemory memory(handle, /*read_only*/ true); EXPECT_TRUE(memory.Map(length)); renderer_->NotifyStreamCreated(stream_id, handle, socket_descriptor, length, - total_segments); + total_segments, initially_muted); EXPECT_TRUE(memory.Unmap()); memory.Close(); } @@ -177,8 +179,8 @@ GetTaskRunnerForTesting()->PostTask( FROM_HERE, base::BindOnce(&AudioInputController::EventHandler::OnCreated, - base::Unretained(event_handler), - base::Unretained(this))); + base::Unretained(event_handler), base::Unretained(this), + false)); ON_CALL(*this, EnableDebugRecording(_)) .WillByDefault(SaveArg<0>(&file_name)); } @@ -334,7 +336,7 @@ Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); EXPECT_CALL(renderer_, - NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount, _)); EXPECT_CALL(controller_factory_, ControllerCreated()); airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( @@ -360,7 +362,7 @@ int session_id = Open("Nondefault device", GetRawNondefaultId()); EXPECT_CALL(renderer_, - NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount, _)); EXPECT_CALL(controller_factory_, ControllerCreated()); airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( @@ -376,7 +378,7 @@ Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); EXPECT_CALL(renderer_, - NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount, _)); EXPECT_CALL(controller_factory_, ControllerCreated()); airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( @@ -399,7 +401,7 @@ Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); EXPECT_CALL(renderer_, - NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount, _)); EXPECT_CALL(controller_factory_, ControllerCreated()); airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( @@ -424,7 +426,7 @@ Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); EXPECT_CALL(renderer_, - NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount, _)); EXPECT_CALL(controller_factory_, ControllerCreated()); airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( @@ -445,7 +447,7 @@ Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); EXPECT_CALL(renderer_, - NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount, _)); EXPECT_CALL(controller_factory_, ControllerCreated()); airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( @@ -466,7 +468,7 @@ Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); EXPECT_CALL(renderer_, - NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount, _)); EXPECT_CALL(renderer_, NotifyStreamError(kStreamId)); EXPECT_CALL(controller_factory_, ControllerCreated()); @@ -487,9 +489,9 @@ Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); EXPECT_CALL(renderer_, - NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); - EXPECT_CALL(renderer_, - NotifyStreamCreated(kStreamId + 1, _, _, _, kSharedMemoryCount)); + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount, _)); + EXPECT_CALL(renderer_, NotifyStreamCreated(kStreamId + 1, _, _, _, + kSharedMemoryCount, _)); EXPECT_CALL(controller_factory_, ControllerCreated()).Times(2); airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( @@ -524,7 +526,7 @@ Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); EXPECT_CALL(renderer_, - NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount, _)); EXPECT_CALL(controller_factory_, ControllerCreated()); airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( @@ -556,7 +558,7 @@ int session_id = Open("Tab capture", controls.audio.device_id); EXPECT_CALL(renderer_, - NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount, _)); EXPECT_CALL(controller_factory_, ControllerCreated()); airh_->OnMessageReceived(AudioInputHostMsg_CreateStream(
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index fda6b6a..9b484b6 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -5849,8 +5849,8 @@ } // namespace anonymous -// Flaky under TSan. https://crbug.com/592320 -#if defined(THREAD_SANITIZER) +// Flaky under Linux and Tsan. https://crbug.com/592320 +#if defined(THREAD_SANITIZER) || defined(OS_LINUX) #define MAYBE_SubframeGestureEventRouting DISABLED_SubframeGestureEventRouting #else #define MAYBE_SubframeGestureEventRouting SubframeGestureEventRouting
diff --git a/content/browser/speech/speech_recognizer_impl.h b/content/browser/speech/speech_recognizer_impl.h index 4c30dad..711b501 100644 --- a/content/browser/speech/speech_recognizer_impl.h +++ b/content/browser/speech/speech_recognizer_impl.h
@@ -143,7 +143,8 @@ void OnAudioClosed(media::AudioInputController*); // AudioInputController::EventHandler methods. - void OnCreated(media::AudioInputController* controller) override {} + void OnCreated(media::AudioInputController* controller, + bool initially_muted) override {} void OnError(media::AudioInputController* controller, media::AudioInputController::ErrorCode error_code) override; void OnLog(media::AudioInputController* controller,
diff --git a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc index b1d00eb..ef7b8bd 100644 --- a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc +++ b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
@@ -106,8 +106,9 @@ class WebRtcGetUserMediaBrowserTest : public WebRtcContentBrowserTestBase { public: WebRtcGetUserMediaBrowserTest() : trace_log_(NULL) { - scoped_feature_list_.InitAndDisableFeature( - features::kMediaStreamOldVideoConstraints); + scoped_feature_list_.InitWithFeatures( + {}, {features::kMediaStreamOldVideoConstraints, + features::kMediaStreamOldAudioConstraints}); // Automatically grant device permission. AppendUseFakeUIForMediaStreamFlag(); } @@ -429,14 +430,12 @@ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html")); // Test with invalid mandatory audio sourceID. - // TODO(guidou): Update error string when spec-compliant constraint resolution - // for audio is implemented. See http://crbug.com/657733. NavigateToURL(shell(), url); - EXPECT_EQ("DevicesNotFoundError", ExecuteJavascriptAndReturnResult( - GenerateGetUserMediaWithMandatorySourceID( - kGetUserMediaAndExpectFailure, - "something invalid", - video_ids[0]))); + EXPECT_EQ("ConstraintNotSatisfiedError", + ExecuteJavascriptAndReturnResult( + GenerateGetUserMediaWithMandatorySourceID( + kGetUserMediaAndExpectFailure, "something invalid", + video_ids[0]))); // Test with invalid mandatory video sourceID. EXPECT_EQ("ConstraintNotSatisfiedError", @@ -446,13 +445,10 @@ "something invalid"))); // Test with empty mandatory audio sourceID. - // TODO(guidou): Update error string when spec-compliant constraint resolution - // for audio is implemented. See http://crbug.com/657733. - EXPECT_EQ("DevicesNotFoundError", ExecuteJavascriptAndReturnResult( - GenerateGetUserMediaWithMandatorySourceID( - kGetUserMediaAndExpectFailure, - "", - video_ids[0]))); + EXPECT_EQ("ConstraintNotSatisfiedError", + ExecuteJavascriptAndReturnResult( + GenerateGetUserMediaWithMandatorySourceID( + kGetUserMediaAndExpectFailure, "", video_ids[0]))); } IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest, @@ -807,8 +803,10 @@ : public WebRtcContentBrowserTestBase { public: WebRtcGetUserMediaOldConstraintsBrowserTest() : trace_log_(NULL) { - scoped_feature_list_.InitAndEnableFeature( - features::kMediaStreamOldVideoConstraints); + scoped_feature_list_.InitWithFeatures( + {features::kMediaStreamOldVideoConstraints, + features::kMediaStreamOldAudioConstraints}, + {}); // Automatically grant device permission. AppendUseFakeUIForMediaStreamFlag(); } @@ -1121,8 +1119,6 @@ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html")); // Test with invalid mandatory audio sourceID. - // TODO(guidou): Update error string when spec-compliant constraint resolution - // for audio is implemented. See http://crbug.com/657733. NavigateToURL(shell(), url); EXPECT_EQ("DevicesNotFoundError", ExecuteJavascriptAndReturnResult( @@ -1138,8 +1134,6 @@ "something invalid"))); // Test with empty mandatory audio sourceID. - // TODO(guidou): Update error string when spec-compliant constraint resolution - // for audio is implemented. See http://crbug.com/657733. EXPECT_EQ("DevicesNotFoundError", ExecuteJavascriptAndReturnResult( GenerateGetUserMediaWithMandatorySourceID(
diff --git a/content/browser/webrtc/webrtc_media_recorder_browsertest.cc b/content/browser/webrtc/webrtc_media_recorder_browsertest.cc index f016341..3d815a27 100644 --- a/content/browser/webrtc/webrtc_media_recorder_browsertest.cc +++ b/content/browser/webrtc/webrtc_media_recorder_browsertest.cc
@@ -122,7 +122,14 @@ kMediaRecorderHtmlFile); } -IN_PROC_BROWSER_TEST_F(WebRtcMediaRecorderTest, IllegalPauseThrowsDOMError) { +// TODO (crbug.com/736268): Flaky on Linux TSan bots. +#if defined(OS_LINUX) +#define MAYBE_IllegalPauseThrowsDOMError DISABLED_IllegalPauseThrowsDOMError +#else +#define MAYBE_IllegalPauseThrowsDOMError IllegalPauseThrowsDOMError +#endif +IN_PROC_BROWSER_TEST_F(WebRtcMediaRecorderTest, + MAYBE_IllegalPauseThrowsDOMError) { MakeTypicalCall("testIllegalPauseThrowsDOMError();", kMediaRecorderHtmlFile); } @@ -153,8 +160,15 @@ kMediaRecorderHtmlFile); } +// Flaky on Linux Tsan (crbug.com/736268) +#if defined(OS_LINUX) +#define MAYBE_IllegalRequestDataThrowsDOMError \ + DISABLED_IllegalRequestDataThrowsDOMError +#else +#define MAYBE_IllegalRequestDataThrowsDOMError IllegalRequestDataThrowsDOMError +#endif IN_PROC_BROWSER_TEST_F(WebRtcMediaRecorderTest, - IllegalRequestDataThrowsDOMError) { + MAYBE_IllegalRequestDataThrowsDOMError) { MakeTypicalCall("testIllegalRequestDataThrowsDOMError();", kMediaRecorderHtmlFile); } @@ -180,8 +194,16 @@ kMediaRecorderHtmlFile); } +// Flaky on Linux Tsan (crbug.com/736268) +#if defined(OS_LINUX) +#define MAYBE_AddingTrackToMediaStreamFiresErrorEvent \ + DISABLED_AddingTrackToMediaStreamFiresErrorEvent +#else +#define MAYBE_AddingTrackToMediaStreamFiresErrorEvent \ + AddingTrackToMediaStreamFiresErrorEvent +#endif IN_PROC_BROWSER_TEST_F(WebRtcMediaRecorderTest, - AddingTrackToMediaStreamFiresErrorEvent) { + MAYBE_AddingTrackToMediaStreamFiresErrorEvent) { MakeTypicalCall("testAddingTrackToMediaStreamFiresErrorEvent();", kMediaRecorderHtmlFile); }
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc index 1e4ab807..1b7c0e6 100644 --- a/content/child/web_url_loader_impl.cc +++ b/content/child/web_url_loader_impl.cc
@@ -1074,7 +1074,7 @@ WebURLResponse* response, bool report_security_info) { response->SetURL(url); - response->SetResponseTime(info.response_time.ToInternalValue()); + response->SetResponseTime(info.response_time); response->SetMIMEType(WebString::FromUTF8(info.mime_type)); response->SetTextEncodingName(WebString::FromUTF8(info.charset)); response->SetExpectedContentLength(info.content_length);
diff --git a/content/common/media/audio_messages.h b/content/common/media/audio_messages.h index 1fed287..f918660 100644 --- a/content/common/media/audio_messages.h +++ b/content/common/media/audio_messages.h
@@ -54,15 +54,16 @@ uint32_t /* length */) // Tell the renderer process that an audio input stream has been created. -// The renderer process would be given a SyncSocket that it should read -// from from then on. It is also given number of segments in shared memory. -IPC_MESSAGE_CONTROL5( - AudioInputMsg_NotifyStreamCreated, - int /* stream id */, - base::SharedMemoryHandle /* handle */, - base::SyncSocket::TransitDescriptor /* socket descriptor */, - uint32_t /* length */, - uint32_t /* segment count */) +// The renderer process would be given a SyncSocket that it should read from +// from then on. It is also given number of segments in shared memory and +// whether the stream initially is muted. +IPC_MESSAGE_CONTROL(AudioInputMsg_NotifyStreamCreated, + int /* stream id */, + base::SharedMemoryHandle /* handle */, + base::SyncSocket::TransitDescriptor /* socket descriptor */, + uint32_t /* length */, + uint32_t /* segment count */, + bool /* initially muted */) // Notification message sent from AudioRendererHost to renderer for state // update on error.
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index db54f942..ba68c9030 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -136,6 +136,10 @@ base::FEATURE_DISABLED_BY_DEFAULT }; +// Enables the old algorithm for processing audio constraints in getUserMedia(). +const base::Feature kMediaStreamOldAudioConstraints{ + "MediaStreamOldAudioConstraints", base::FEATURE_ENABLED_BY_DEFAULT}; + // Enables the old algorithm for processing video constraints in getUserMedia(). const base::Feature kMediaStreamOldVideoConstraints{ "MediaStreamOldVideoConstraints", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 631f2be2..e06b6dc 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -43,6 +43,7 @@ CONTENT_EXPORT extern const base::Feature kLoadingWithMojo; CONTENT_EXPORT extern const base::Feature kLocationHardReload; CONTENT_EXPORT extern const base::Feature kMediaDocumentDownloadButton; +CONTENT_EXPORT extern const base::Feature kMediaStreamOldAudioConstraints; CONTENT_EXPORT extern const base::Feature kMediaStreamOldVideoConstraints; CONTENT_EXPORT extern const base::Feature kMemoryCoordinator; CONTENT_EXPORT extern const base::Feature kNotificationContentImage;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index cc4afef5..3ad0810 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -682,6 +682,8 @@ "media/webrtc/webrtc_audio_sink.h", "media/webrtc/webrtc_media_stream_adapter.cc", "media/webrtc/webrtc_media_stream_adapter.h", + "media/webrtc/webrtc_media_stream_adapter_map.cc", + "media/webrtc/webrtc_media_stream_adapter_map.h", "media/webrtc/webrtc_media_stream_track_adapter.cc", "media/webrtc/webrtc_media_stream_track_adapter.h", "media/webrtc/webrtc_media_stream_track_adapter_map.cc",
diff --git a/content/renderer/cache_storage/cache_storage_dispatcher.cc b/content/renderer/cache_storage/cache_storage_dispatcher.cc index 51b09d23..f1ba2dc8 100644 --- a/content/renderer/cache_storage/cache_storage_dispatcher.cc +++ b/content/renderer/cache_storage/cache_storage_dispatcher.cc
@@ -630,7 +630,7 @@ web_response->SetStatus(response.status_code); web_response->SetStatusText(WebString::FromASCII(response.status_text)); web_response->SetResponseType(response.response_type); - web_response->SetResponseTime(response.response_time.ToInternalValue()); + web_response->SetResponseTime(response.response_time); web_response->SetCacheStorageCacheName( response.is_in_cache_storage ? blink::WebString::FromUTF8(response.cache_storage_cache_name)
diff --git a/content/renderer/media/audio_input_message_filter.cc b/content/renderer/media/audio_input_message_filter.cc index 145215b..9c69e3e 100644 --- a/content/renderer/media/audio_input_message_filter.cc +++ b/content/renderer/media/audio_input_message_filter.cc
@@ -128,7 +128,8 @@ base::SharedMemoryHandle handle, base::SyncSocket::TransitDescriptor socket_descriptor, uint32_t length, - uint32_t total_segments) { + uint32_t total_segments, + bool initially_muted) { DCHECK(io_task_runner_->BelongsToCurrentThread()); LogMessage(stream_id, "OnStreamCreated"); @@ -143,7 +144,8 @@ return; } // Forward message to the stream delegate. - delegate->OnStreamCreated(handle, socket_handle, length, total_segments); + delegate->OnStreamCreated(handle, socket_handle, length, total_segments, + initially_muted); } void AudioInputMessageFilter::OnStreamError(int stream_id) {
diff --git a/content/renderer/media/audio_input_message_filter.h b/content/renderer/media/audio_input_message_filter.h index 60952c9..a015af7b 100644 --- a/content/renderer/media/audio_input_message_filter.h +++ b/content/renderer/media/audio_input_message_filter.h
@@ -73,7 +73,8 @@ base::FileDescriptor socket_descriptor, #endif uint32_t length, - uint32_t total_segments); + uint32_t total_segments, + bool initially_muted); // Received when internal state of browser process' audio input stream has // encountered an error.
diff --git a/content/renderer/media/media_stream_audio_processor.cc b/content/renderer/media/media_stream_audio_processor.cc index d98b594..360b40d1 100644 --- a/content/renderer/media/media_stream_audio_processor.cc +++ b/content/renderer/media/media_stream_audio_processor.cc
@@ -6,7 +6,11 @@ #include <stddef.h> #include <stdint.h> +#include <algorithm> +#include <limits> +#include <string> #include <utility> +#include <vector> #include "base/command_line.h" #include "base/feature_list.h" @@ -20,13 +24,11 @@ #include "build/build_config.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" -#include "content/renderer/media/media_stream_audio_processor_options.h" #include "content/renderer/media/webrtc_audio_device_impl.h" #include "media/base/audio_converter.h" #include "media/base/audio_fifo.h" #include "media/base/audio_parameters.h" #include "media/base/channel_layout.h" -#include "third_party/WebKit/public/platform/WebMediaConstraints.h" #include "third_party/webrtc/api/mediaconstraintsinterface.h" #include "third_party/webrtc/modules/audio_processing/typing_detection.h" @@ -128,6 +130,19 @@ switches::kAecRefinedAdaptiveFilter); } +webrtc::Point WebrtcPointFromMediaPoint(const media::Point& point) { + return webrtc::Point(point.x(), point.y(), point.z()); +} + +std::vector<webrtc::Point> WebrtcPointsFromMediaPoints( + const std::vector<media::Point>& points) { + std::vector<webrtc::Point> webrtc_points; + webrtc_points.reserve(webrtc_points.size()); + for (const auto& point : points) + webrtc_points.push_back(WebrtcPointFromMediaPoint(point)); + return webrtc_points; +} + } // namespace // Wraps AudioBus to provide access to the array of channel pointers, since this @@ -292,8 +307,7 @@ }; MediaStreamAudioProcessor::MediaStreamAudioProcessor( - const blink::WebMediaConstraints& constraints, - const MediaStreamDevice::AudioDeviceParameters& input_params, + const AudioProcessingProperties& properties, WebRtcPlayoutDataSource* playout_data_source) : render_delay_ms_(0), has_echo_cancellation_(false), @@ -305,7 +319,7 @@ DCHECK(main_thread_runner_); capture_thread_checker_.DetachFromThread(); render_thread_checker_.DetachFromThread(); - InitializeAudioProcessingModule(constraints, input_params); + InitializeAudioProcessingModule(properties); aec_dump_message_filter_ = AecDumpMessageFilter::Get(); // In unit tests not creating a message filter, |aec_dump_message_filter_| @@ -491,34 +505,30 @@ // static bool MediaStreamAudioProcessor::WouldModifyAudio( - const blink::WebMediaConstraints& constraints, - int effects_flags) { + const AudioProcessingProperties& properties) { // Note: This method should by kept in-sync with any changes to the logic in // MediaStreamAudioProcessor::InitializeAudioProcessingModule(). - const MediaAudioConstraints audio_constraints(constraints, effects_flags); - - if (audio_constraints.GetGoogAudioMirroring()) + if (properties.goog_audio_mirroring) return true; #if !defined(OS_IOS) - if (audio_constraints.GetEchoCancellationProperty() || - audio_constraints.GetGoogAutoGainControl()) { + if (properties.enable_sw_echo_cancellation || + properties.goog_auto_gain_control) { return true; } #endif #if !defined(OS_IOS) && !defined(OS_ANDROID) - if (audio_constraints.GetGoogExperimentalEchoCancellation() || - audio_constraints.GetGoogTypingNoiseDetection()) { + if (properties.goog_experimental_echo_cancellation || + properties.goog_typing_noise_detection) { return true; } #endif - if (audio_constraints.GetGoogNoiseSuppression() || - audio_constraints.GetGoogExperimentalNoiseSuppression() || - audio_constraints.GetGoogBeamforming() || - audio_constraints.GetGoogHighpassFilter()) { + if (properties.goog_noise_suppression || + properties.goog_experimental_noise_suppression || + properties.goog_beamforming || properties.goog_highpass_filter) { return true; } @@ -578,78 +588,63 @@ } void MediaStreamAudioProcessor::InitializeAudioProcessingModule( - const blink::WebMediaConstraints& constraints, - const MediaStreamDevice::AudioDeviceParameters& input_params) { + const AudioProcessingProperties& properties) { DCHECK(main_thread_runner_->BelongsToCurrentThread()); DCHECK(!audio_processing_); - MediaAudioConstraints audio_constraints(constraints, input_params.effects); - // Note: The audio mirroring constraint (i.e., swap left and right channels) // is handled within this MediaStreamAudioProcessor and does not, by itself, // require webrtc::AudioProcessing. - audio_mirroring_ = audio_constraints.GetGoogAudioMirroring(); - - const bool echo_cancellation = - audio_constraints.GetEchoCancellationProperty(); - has_echo_cancellation_ = echo_cancellation; - const bool goog_agc = audio_constraints.GetGoogAutoGainControl(); + audio_mirroring_ = properties.goog_audio_mirroring; + has_echo_cancellation_ = properties.enable_sw_echo_cancellation; #if defined(OS_ANDROID) const bool goog_experimental_aec = false; const bool goog_typing_detection = false; #else const bool goog_experimental_aec = - audio_constraints.GetGoogExperimentalEchoCancellation(); - const bool goog_typing_detection = - audio_constraints.GetGoogTypingNoiseDetection(); + properties.goog_experimental_echo_cancellation; + const bool goog_typing_detection = properties.goog_typing_noise_detection; #endif - const bool goog_ns = audio_constraints.GetGoogNoiseSuppression(); - const bool goog_experimental_ns = - audio_constraints.GetGoogExperimentalNoiseSuppression(); - const bool goog_beamforming = audio_constraints.GetGoogBeamforming(); - const bool goog_high_pass_filter = audio_constraints.GetGoogHighpassFilter(); - // Return immediately if none of the goog constraints requiring // webrtc::AudioProcessing are enabled. - if (!echo_cancellation && !goog_experimental_aec && !goog_ns && - !goog_high_pass_filter && !goog_typing_detection && - !goog_agc && !goog_experimental_ns && !goog_beamforming) { + if (!properties.enable_sw_echo_cancellation && !goog_experimental_aec && + !properties.goog_noise_suppression && !properties.goog_highpass_filter && + !goog_typing_detection && !properties.goog_auto_gain_control && + !properties.goog_experimental_noise_suppression && + !properties.goog_beamforming) { // Sanity-check: WouldModifyAudio() should return true iff // |audio_mirroring_| is true. - DCHECK_EQ(audio_mirroring_, WouldModifyAudio(constraints, - input_params.effects)); + DCHECK_EQ(audio_mirroring_, WouldModifyAudio(properties)); RecordProcessingState(AUDIO_PROCESSING_DISABLED); return; } // Sanity-check: WouldModifyAudio() should return true because the above logic // has determined webrtc::AudioProcessing will be used. - DCHECK(WouldModifyAudio(constraints, input_params.effects)); + DCHECK(WouldModifyAudio(properties)); // Experimental options provided at creation. webrtc::Config config; config.Set<webrtc::ExtendedFilter>( new webrtc::ExtendedFilter(goog_experimental_aec)); - config.Set<webrtc::ExperimentalNs>( - new webrtc::ExperimentalNs(goog_experimental_ns)); + config.Set<webrtc::ExperimentalNs>(new webrtc::ExperimentalNs( + properties.goog_experimental_noise_suppression)); config.Set<webrtc::DelayAgnostic>(new webrtc::DelayAgnostic(true)); if (UseAecRefinedAdaptiveFilter()) { config.Set<webrtc::RefinedAdaptiveFilter>( new webrtc::RefinedAdaptiveFilter(true)); } - if (goog_beamforming) { - const auto& geometry = - GetArrayGeometryPreferringConstraints(audio_constraints, input_params); - + if (properties.goog_beamforming) { // Only enable beamforming if we have at least two mics. - config.Set<webrtc::Beamforming>( - new webrtc::Beamforming(geometry.size() > 1, geometry)); + config.Set<webrtc::Beamforming>(new webrtc::Beamforming( + properties.goog_array_geometry.size() > 1, + WebrtcPointsFromMediaPoints(properties.goog_array_geometry))); } // If the experimental AGC is enabled, check for overridden config params. - if (audio_constraints.GetGoogExperimentalAutoGainControl()) { + if (properties.goog_experimental_auto_gain_control) { auto startup_min_volume = GetStartupMinVolumeForAgc(); constexpr int kClippingLevelMin = 70; // TODO(hlundin) Make this value default in WebRTC and clean up here. @@ -667,7 +662,7 @@ playout_data_source_->AddPlayoutSink(this); } - if (echo_cancellation) { + if (properties.enable_sw_echo_cancellation) { EnableEchoCancellation(audio_processing_.get()); apm_config.echo_canceller3.enabled = override_aec3_.value_or( @@ -686,7 +681,7 @@ apm_config.echo_canceller3.enabled = false; } - if (goog_ns) { + if (properties.goog_noise_suppression) { // The beamforming postfilter is effective at suppressing stationary noise, // so reduce the single-channel NS aggressiveness when enabled. const NoiseSuppression::Level ns_level = @@ -696,7 +691,7 @@ EnableNoiseSuppression(audio_processing_.get(), ns_level); } - apm_config.high_pass_filter.enabled = goog_high_pass_filter; + apm_config.high_pass_filter.enabled = properties.goog_highpass_filter; if (goog_typing_detection) { // TODO(xians): Remove this |typing_detector_| after the typing suppression @@ -705,7 +700,7 @@ EnableTypingDetection(audio_processing_.get(), typing_detector_.get()); } - if (goog_agc) + if (properties.goog_auto_gain_control) EnableAutomaticGainControl(audio_processing_.get()); audio_processing_->ApplyConfig(apm_config);
diff --git a/content/renderer/media/media_stream_audio_processor.h b/content/renderer/media/media_stream_audio_processor.h index fa4c8ff..d001734 100644 --- a/content/renderer/media/media_stream_audio_processor.h +++ b/content/renderer/media/media_stream_audio_processor.h
@@ -5,6 +5,8 @@ #ifndef CONTENT_RENDERER_MEDIA_MEDIA_STREAM_AUDIO_PROCESSOR_H_ #define CONTENT_RENDERER_MEDIA_MEDIA_STREAM_AUDIO_PROCESSOR_H_ +#include <memory> + #include "base/atomicops.h" #include "base/files/file.h" #include "base/gtest_prod_util.h" @@ -19,6 +21,7 @@ #include "content/public/common/media_stream_request.h" #include "content/renderer/media/aec_dump_message_filter.h" #include "content/renderer/media/audio_repetition_detector.h" +#include "content/renderer/media/media_stream_audio_processor_options.h" #include "content/renderer/media/webrtc_audio_device_impl.h" #include "media/base/audio_converter.h" #include "third_party/webrtc/api/mediastreaminterface.h" @@ -34,10 +37,6 @@ #endif #endif -namespace blink { -class WebMediaConstraints; -} - namespace media { class AudioBus; class AudioParameters; @@ -70,10 +69,8 @@ // // Threading note: The constructor assumes it is being run on the main render // thread. - MediaStreamAudioProcessor( - const blink::WebMediaConstraints& constraints, - const MediaStreamDevice::AudioDeviceParameters& input_params, - WebRtcPlayoutDataSource* playout_data_source); + MediaStreamAudioProcessor(const AudioProcessingProperties& properties, + WebRtcPlayoutDataSource* playout_data_source); // Called when the format of the capture data has changed. // Called on the main render thread. The caller is responsible for stopping @@ -126,15 +123,10 @@ void OnIpcClosing() override; // Returns true if MediaStreamAudioProcessor would modify the audio signal, - // based on the |constraints| and |effects_flags| parsed from a user media - // request. If the audio signal would not be modified, there is no need to - // instantiate a MediaStreamAudioProcessor and feed audio through it. Doing so - // would waste a non-trivial amount of memory and CPU resources. - // - // See media::AudioParameters::PlatformEffectsMask for interpretation of - // |effects_flags|. - static bool WouldModifyAudio(const blink::WebMediaConstraints& constraints, - int effects_flags); + // based on |properties|. If the audio signal would not be modified, there is + // no need to instantiate a MediaStreamAudioProcessor and feed audio through + // it. Doing so would waste a non-trivial amount of memory and CPU resources. + static bool WouldModifyAudio(const AudioProcessingProperties& properties); protected: ~MediaStreamAudioProcessor() override; @@ -158,8 +150,7 @@ // Helper to initialize the WebRtc AudioProcessing. void InitializeAudioProcessingModule( - const blink::WebMediaConstraints& constraints, - const MediaStreamDevice::AudioDeviceParameters& input_params); + const AudioProcessingProperties& properties); // Helper to initialize the capture converter. void InitializeCaptureFifo(const media::AudioParameters& input_format);
diff --git a/content/renderer/media/media_stream_audio_processor_options.cc b/content/renderer/media/media_stream_audio_processor_options.cc index 401350e..2da0996 100644 --- a/content/renderer/media/media_stream_audio_processor_options.cc +++ b/content/renderer/media/media_stream_audio_processor_options.cc
@@ -7,6 +7,7 @@ #include <stddef.h> #include <utility> +#include "base/feature_list.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/logging.h" @@ -18,6 +19,7 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "content/common/media/media_stream_options.h" +#include "content/public/common/content_features.h" #include "content/renderer/media/media_stream_constraints_util.h" #include "content/renderer/media/media_stream_source.h" #include "media/base/audio_parameters.h" @@ -107,19 +109,6 @@ return DELAY_BASED_ECHO_QUALITY_BAD; } -webrtc::Point WebrtcPointFromMediaPoint(const media::Point& point) { - return webrtc::Point(point.x(), point.y(), point.z()); -} - -std::vector<webrtc::Point> WebrtcPointsFromMediaPoints( - const std::vector<media::Point>& points) { - std::vector<webrtc::Point> webrtc_points; - webrtc_points.reserve(webrtc_points.size()); - for (const auto& point : points) - webrtc_points.push_back(WebrtcPointFromMediaPoint(point)); - return webrtc_points; -} - // Scan the basic and advanced constraints until a value is found. // If nothing is found, the default is returned. // Argument 2 is a pointer to class data member. @@ -141,6 +130,7 @@ : constraints_(constraints), effects_(effects), default_audio_processing_constraint_value_(true) { + DCHECK(IsOldAudioConstraints()); // The default audio processing constraints are turned off when // - gUM has a specific kMediaStreamSource, which is used by tab capture // and screen capture. @@ -286,6 +276,50 @@ AudioProcessingProperties&& other) = default; AudioProcessingProperties::~AudioProcessingProperties() = default; +void AudioProcessingProperties::DisableDefaultPropertiesForTesting() { + enable_sw_echo_cancellation = false; + goog_auto_gain_control = false; + goog_experimental_echo_cancellation = false; + goog_typing_noise_detection = false; + goog_noise_suppression = false; + goog_experimental_noise_suppression = false; + goog_beamforming = false; + goog_highpass_filter = false; + goog_experimental_auto_gain_control = false; +} + +// static +AudioProcessingProperties AudioProcessingProperties::FromConstraints( + const blink::WebMediaConstraints& constraints, + const MediaStreamDevice::AudioDeviceParameters& input_params) { + DCHECK(IsOldAudioConstraints()); + MediaAudioConstraints audio_constraints(constraints, input_params.effects); + AudioProcessingProperties properties; + properties.enable_sw_echo_cancellation = + audio_constraints.GetEchoCancellationProperty(); + // |properties.disable_hw_echo_cancellation| is not used when + // IsOldAudioConstraints() is true. + properties.goog_audio_mirroring = audio_constraints.GetGoogAudioMirroring(); + properties.goog_auto_gain_control = + audio_constraints.GetGoogAutoGainControl(); + properties.goog_experimental_echo_cancellation = + audio_constraints.GetGoogExperimentalEchoCancellation(); + properties.goog_typing_noise_detection = + audio_constraints.GetGoogTypingNoiseDetection(); + properties.goog_noise_suppression = + audio_constraints.GetGoogNoiseSuppression(); + properties.goog_experimental_noise_suppression = + audio_constraints.GetGoogExperimentalNoiseSuppression(); + properties.goog_beamforming = audio_constraints.GetGoogBeamforming(); + properties.goog_highpass_filter = audio_constraints.GetGoogHighpassFilter(); + properties.goog_experimental_auto_gain_control = + audio_constraints.GetGoogExperimentalAutoGainControl(); + properties.goog_array_geometry = + GetArrayGeometryPreferringConstraints(audio_constraints, input_params); + + return properties; +} + EchoInformation::EchoInformation() : delay_stats_time_ms_(0), echo_frames_received_(false), @@ -482,7 +516,7 @@ apm_stats.residual_echo_likelihood_recent_max; } -std::vector<webrtc::Point> GetArrayGeometryPreferringConstraints( +std::vector<media::Point> GetArrayGeometryPreferringConstraints( const MediaAudioConstraints& audio_constraints, const MediaStreamDevice::AudioDeviceParameters& input_params) { const std::string constraints_geometry = @@ -490,10 +524,14 @@ // Give preference to the audio constraint over the device-supplied mic // positions. This is mainly for testing purposes. - return WebrtcPointsFromMediaPoints( - constraints_geometry.empty() - ? input_params.mic_positions - : media::ParsePointsFromString(constraints_geometry)); + return constraints_geometry.empty() + ? input_params.mic_positions + : media::ParsePointsFromString(constraints_geometry); +} + +bool IsOldAudioConstraints() { + return base::FeatureList::IsEnabled( + features::kMediaStreamOldAudioConstraints); } } // namespace content
diff --git a/content/renderer/media/media_stream_audio_processor_options.h b/content/renderer/media/media_stream_audio_processor_options.h index c891c8c..153a26c5 100644 --- a/content/renderer/media/media_stream_audio_processor_options.h +++ b/content/renderer/media/media_stream_audio_processor_options.h
@@ -110,6 +110,14 @@ AudioProcessingProperties& operator=(AudioProcessingProperties&& other); ~AudioProcessingProperties(); + // Disables properties that are enabled by default. + void DisableDefaultPropertiesForTesting(); + + // TODO(guidou): Remove this function. http://crbug.com/706408 + static AudioProcessingProperties FromConstraints( + const blink::WebMediaConstraints& constraints, + const MediaStreamDevice::AudioDeviceParameters& input_params); + bool enable_sw_echo_cancellation = true; bool disable_hw_echo_cancellation = false; bool goog_audio_mirroring = false; @@ -197,10 +205,14 @@ // Returns the array geometry from the media constraints if existing and // otherwise that provided by the input device. -CONTENT_EXPORT std::vector<webrtc::Point> GetArrayGeometryPreferringConstraints( +// TODO(guidou): Remove this function. http://crbug.com/706408 +CONTENT_EXPORT std::vector<media::Point> GetArrayGeometryPreferringConstraints( const MediaAudioConstraints& audio_constraints, const MediaStreamDevice::AudioDeviceParameters& input_params); +// TODO(guidou): Remove this function. http://crbug.com/706408 +CONTENT_EXPORT bool IsOldAudioConstraints(); + } // namespace content #endif // CONTENT_RENDERER_MEDIA_MEDIA_STREAM_AUDIO_PROCESSOR_OPTIONS_H_
diff --git a/content/renderer/media/media_stream_audio_processor_unittest.cc b/content/renderer/media/media_stream_audio_processor_unittest.cc index 3404ed5..c5a9f4b 100644 --- a/content/renderer/media/media_stream_audio_processor_unittest.cc +++ b/content/renderer/media/media_stream_audio_processor_unittest.cc
@@ -14,10 +14,12 @@ #include "base/memory/aligned_memory.h" #include "base/message_loop/message_loop.h" #include "base/path_service.h" +#include "base/test/scoped_feature_list.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "build/build_config.h" #include "content/common/media/media_stream_options.h" +#include "content/public/common/content_features.h" #include "content/public/common/media_stream_request.h" #include "content/renderer/media/media_stream_audio_processor.h" #include "content/renderer/media/media_stream_audio_processor_options.h" @@ -81,6 +83,12 @@ MediaStreamAudioProcessorTest() : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_STEREO, 48000, 16, 512) { + // This file includes tests for MediaStreamAudioProcessor, but also for + // the old constraints algorithm. The MediaStreamAudioProcessor tests are + // insensitive to the constraints algorithm, but the constraints tests + // require that the old constraints algorithm be enabled. + scoped_feature_list_.InitAndEnableFeature( + features::kMediaStreamOldAudioConstraints); } protected: @@ -212,6 +220,9 @@ base::MessageLoop main_thread_message_loop_; media::AudioParameters params_; MediaStreamDevice::AudioDeviceParameters input_device_params_; + + // TODO(guidou): Remove this field. http://crbug.com/706408 + base::test::ScopedFeatureList scoped_feature_list_; }; // Test crashing with ASAN on Android. crbug.com/468762 @@ -221,13 +232,12 @@ #define MAYBE_WithAudioProcessing WithAudioProcessing #endif TEST_F(MediaStreamAudioProcessorTest, MAYBE_WithAudioProcessing) { - MockConstraintFactory constraint_factory; scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( new WebRtcAudioDeviceImpl()); + AudioProcessingProperties properties; scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - constraint_factory.CreateWebMediaConstraints(), input_device_params_, - webrtc_audio_device.get())); + properties, webrtc_audio_device.get())); EXPECT_TRUE(audio_processor->has_audio_processing()); audio_processor->OnCaptureFormatChanged(params_); VerifyDefaultComponents(audio_processor.get()); @@ -242,52 +252,15 @@ audio_processor->Stop(); } -TEST_F(MediaStreamAudioProcessorTest, VerifyTabCaptureWithoutAudioProcessing) { - scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( - new WebRtcAudioDeviceImpl()); - // Create MediaStreamAudioProcessor instance for kMediaStreamSourceTab source. - MockConstraintFactory tab_constraint_factory; - const std::string tab_string = kMediaStreamSourceTab; - tab_constraint_factory.basic().media_stream_source.SetExact( - blink::WebString::FromUTF8(tab_string)); - scoped_refptr<MediaStreamAudioProcessor> audio_processor( - new rtc::RefCountedObject<MediaStreamAudioProcessor>( - tab_constraint_factory.CreateWebMediaConstraints(), - input_device_params_, webrtc_audio_device.get())); - EXPECT_FALSE(audio_processor->has_audio_processing()); - audio_processor->OnCaptureFormatChanged(params_); - - ProcessDataAndVerifyFormat(audio_processor.get(), - params_.sample_rate(), - params_.channels(), - params_.sample_rate() / 100); - - // Create MediaStreamAudioProcessor instance for kMediaStreamSourceSystem - // source. - MockConstraintFactory system_constraint_factory; - const std::string system_string = kMediaStreamSourceSystem; - system_constraint_factory.basic().media_stream_source.SetExact( - blink::WebString::FromUTF8(system_string)); - audio_processor = new rtc::RefCountedObject<MediaStreamAudioProcessor>( - system_constraint_factory.CreateWebMediaConstraints(), - input_device_params_, webrtc_audio_device.get()); - EXPECT_FALSE(audio_processor->has_audio_processing()); - - // Stop |audio_processor| so that it removes itself from - // |webrtc_audio_device| and clears its pointer to it. - audio_processor->Stop(); -} - TEST_F(MediaStreamAudioProcessorTest, TurnOffDefaultConstraints) { + AudioProcessingProperties properties; // Turn off the default constraints and pass it to MediaStreamAudioProcessor. - MockConstraintFactory constraint_factory; - constraint_factory.DisableDefaultAudioConstraints(); + properties.DisableDefaultPropertiesForTesting(); scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( new WebRtcAudioDeviceImpl()); scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - constraint_factory.CreateWebMediaConstraints(), input_device_params_, - webrtc_audio_device.get())); + properties, webrtc_audio_device.get())); EXPECT_FALSE(audio_processor->has_audio_processing()); audio_processor->OnCaptureFormatChanged(params_); @@ -301,6 +274,7 @@ audio_processor->Stop(); } +// TODO(guidou): Remove this test. http://crbug.com/706408 TEST_F(MediaStreamAudioProcessorTest, VerifyConstraints) { { // Verify that echo cancellation is off when platform aec effect is on. @@ -340,6 +314,7 @@ } } +// TODO(guidou): Remove this test. http://crbug.com/706408 TEST_F(MediaStreamAudioProcessorTest, ValidateBadConstraints) { MockConstraintFactory constraint_factory; // Add a constraint that is not valid for audio. @@ -349,6 +324,7 @@ EXPECT_FALSE(audio_constraints.IsValid()); } +// TODO(guidou): Remove this test. http://crbug.com/706408 TEST_F(MediaStreamAudioProcessorTest, ValidateGoodConstraints) { MockConstraintFactory constraint_factory; // Check that the renderToAssociatedSink constraint is considered valid. @@ -358,6 +334,7 @@ EXPECT_TRUE(audio_constraints.IsValid()); } +// TODO(guidou): Remove this test. http://crbug.com/706408 TEST_F(MediaStreamAudioProcessorTest, NoEchoTurnsOffProcessing) { { MockConstraintFactory constraint_factory; @@ -387,19 +364,20 @@ } } +// TODO(guidou): Remove this function. http://crbug.com/706408 MediaAudioConstraints MakeMediaAudioConstraints( const MockConstraintFactory& constraint_factory) { return MediaAudioConstraints(constraint_factory.CreateWebMediaConstraints(), AudioParameters::NO_EFFECTS); } +// TODO(guidou): Remove this test. http://crbug.com/706408 TEST_F(MediaStreamAudioProcessorTest, SelectsConstraintsArrayGeometryIfExists) { - std::vector<webrtc::Point> constraints_geometry(1, - webrtc::Point(-0.02f, 0, 0)); - constraints_geometry.push_back(webrtc::Point(0.02f, 0, 0)); + std::vector<media::Point> constraints_geometry(1, media::Point(-0.02f, 0, 0)); + constraints_geometry.push_back(media::Point(0.02f, 0, 0)); - std::vector<webrtc::Point> input_device_geometry(1, webrtc::Point(0, 0, 0)); - input_device_geometry.push_back(webrtc::Point(0, 0.05f, 0)); + std::vector<media::Point> input_device_geometry(1, media::Point(0, 0, 0)); + input_device_geometry.push_back(media::Point(0, 0.05f, 0)); { // Both geometries empty. @@ -408,7 +386,7 @@ const auto& actual_geometry = GetArrayGeometryPreferringConstraints( MakeMediaAudioConstraints(constraint_factory), input_params); - EXPECT_EQ(std::vector<webrtc::Point>(), actual_geometry); + EXPECT_EQ(std::vector<media::Point>(), actual_geometry); } { // Constraints geometry empty. @@ -455,13 +433,12 @@ #define MAYBE_TestAllSampleRates TestAllSampleRates #endif TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestAllSampleRates) { - MockConstraintFactory constraint_factory; scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( new WebRtcAudioDeviceImpl()); + AudioProcessingProperties properties; scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - constraint_factory.CreateWebMediaConstraints(), input_device_params_, - webrtc_audio_device.get())); + properties, webrtc_audio_device.get())); EXPECT_TRUE(audio_processor->has_audio_processing()); static const int kSupportedSampleRates[] = @@ -495,13 +472,12 @@ new AecDumpMessageFilter(base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get())); - MockConstraintFactory constraint_factory; scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( new WebRtcAudioDeviceImpl()); + AudioProcessingProperties properties; scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - constraint_factory.CreateWebMediaConstraints(), input_device_params_, - webrtc_audio_device.get())); + properties, webrtc_audio_device.get())); EXPECT_TRUE(audio_processor->aec_dump_message_filter_.get()); @@ -511,17 +487,15 @@ } TEST_F(MediaStreamAudioProcessorTest, TestStereoAudio) { - // Set up the correct constraints to turn off the audio processing and turn - // on the stereo channels mirroring. - MockConstraintFactory constraint_factory; - constraint_factory.basic().echo_cancellation.SetExact(false); - constraint_factory.basic().goog_audio_mirroring.SetExact(true); scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( new WebRtcAudioDeviceImpl()); + AudioProcessingProperties properties; + // Turn off the audio processing and turn on the stereo channels mirroring. + properties.DisableDefaultPropertiesForTesting(); + properties.goog_audio_mirroring = true; scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - constraint_factory.CreateWebMediaConstraints(), input_device_params_, - webrtc_audio_device.get())); + properties, webrtc_audio_device.get())); EXPECT_FALSE(audio_processor->has_audio_processing()); const media::AudioParameters source_params( media::AudioParameters::AUDIO_PCM_LOW_LATENCY, @@ -577,14 +551,12 @@ #define MAYBE_TestWithKeyboardMicChannel TestWithKeyboardMicChannel #endif TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestWithKeyboardMicChannel) { - MockConstraintFactory constraint_factory; - constraint_factory.basic().goog_experimental_noise_suppression.SetExact(true); scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( new WebRtcAudioDeviceImpl()); + AudioProcessingProperties properties; scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - constraint_factory.CreateWebMediaConstraints(), input_device_params_, - webrtc_audio_device.get())); + properties, webrtc_audio_device.get())); EXPECT_TRUE(audio_processor->has_audio_processing()); media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, @@ -604,13 +576,12 @@ // Test that the OnAec3Enable method has the desired effect on the APM config. TEST_F(MediaStreamAudioProcessorTest, TestAec3Switch) { - MockConstraintFactory constraint_factory; scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( new WebRtcAudioDeviceImpl()); + AudioProcessingProperties properties; scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - constraint_factory.CreateWebMediaConstraints(), input_device_params_, - webrtc_audio_device.get())); + properties, webrtc_audio_device.get())); audio_processor->OnAec3Enable(true); EXPECT_TRUE(GetAec3ConfigState(audio_processor.get())); @@ -626,15 +597,14 @@ // Same test as above, but when AEC is disabled in the constrants. The expected // outcome is that AEC3 should be disabled in all cases. TEST_F(MediaStreamAudioProcessorTest, TestAec3Switch_AecOff) { - MockConstraintFactory constraint_factory; - // Disable the AEC. - constraint_factory.DisableAecAudioConstraints(); scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( new WebRtcAudioDeviceImpl()); + AudioProcessingProperties properties; + // Disable the AEC. + properties.enable_sw_echo_cancellation = false; scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - constraint_factory.CreateWebMediaConstraints(), input_device_params_, - webrtc_audio_device.get())); + properties, webrtc_audio_device.get())); EXPECT_FALSE(GetAec3ConfigState(audio_processor.get()));
diff --git a/content/renderer/media/rtc_peer_connection_handler_unittest.cc b/content/renderer/media/rtc_peer_connection_handler_unittest.cc index ecc1946..66d6be9 100644 --- a/content/renderer/media/rtc_peer_connection_handler_unittest.cc +++ b/content/renderer/media/rtc_peer_connection_handler_unittest.cc
@@ -301,7 +301,7 @@ media::AudioParameters::kAudioCDSampleRate, media::CHANNEL_LAYOUT_STEREO, media::AudioParameters::kAudioCDSampleRate / 100), - MockConstraintFactory().CreateWebMediaConstraints(), + AudioProcessingProperties(), base::Bind(&RTCPeerConnectionHandlerTest::OnAudioSourceStarted), mock_dependency_factory_.get()); audio_source->SetAllowInvalidRenderFrameIdForTesting(true);
diff --git a/content/renderer/media/user_media_client_impl.cc b/content/renderer/media/user_media_client_impl.cc index aa65b67..96ebd7bd 100644 --- a/content/renderer/media/user_media_client_impl.cc +++ b/content/renderer/media/user_media_client_impl.cc
@@ -21,6 +21,7 @@ #include "content/renderer/media/local_media_stream_audio_source.h" #include "content/renderer/media/media_stream.h" #include "content/renderer/media/media_stream_constraints_util.h" +#include "content/renderer/media/media_stream_constraints_util_audio.h" #include "content/renderer/media/media_stream_constraints_util_video_content.h" #include "content/renderer/media/media_stream_constraints_util_video_device.h" #include "content/renderer/media/media_stream_dispatcher.h" @@ -49,6 +50,7 @@ *destination = constraint.Exact()[0].Utf8(); } +// TODO(guidou): Remove this function. http://crbug.com/706408 bool FindDeviceId(const blink::WebVector<blink::WebString> candidates, const MediaDeviceInfoArray& device_infos, std::string* device_id) { @@ -79,8 +81,7 @@ // such device ID is copied to |*device_id| and the function returns true. // If no such device ID is found, |*device_id| is left unmodified and the // function returns true. -// TODO(guidou): Replace with a spec-compliant selection algorithm. See -// http://crbug.com/657733. +// TODO(guidou): Remove this function. http://crbug.com/706408 bool PickDeviceId(const blink::WebMediaConstraints& constraints, const MediaDeviceInfoArray& device_infos, std::string* device_id) { @@ -123,8 +124,7 @@ return source.empty(); } -// TODO(guidou): Remove once audio constraints are processed with spec-compliant -// algorithm. See http://crbug.com/657733. +// TODO(guidou): Remove this function. http://crbug.com/706408 void CopyConstraintsToTrackControls( const blink::WebMediaConstraints& constraints, TrackControls* track_controls, @@ -157,6 +157,7 @@ &track_controls->stream_source); } +// TODO(guidou): Remove this function. http://crbug.com/706408 void CopyHotwordAndLocalEchoToStreamControls( const blink::WebMediaConstraints& audio_constraints, StreamControls* controls) { @@ -219,6 +220,18 @@ } } +bool IsValidAudioContentSource(const std::string& source) { + return source == kMediaStreamSourceTab || + source == kMediaStreamSourceDesktop || + source == kMediaStreamSourceSystem; +} + +bool IsValidVideoContentSource(const std::string& source) { + return source == kMediaStreamSourceTab || + source == kMediaStreamSourceDesktop || + source == kMediaStreamSourceScreen; +} + static int g_next_request_id = 0; } // namespace @@ -265,11 +278,33 @@ State state() const { return state_; } void set_state(State state) { state_ = state; } - bool enable_automatic_output_device_selection() const { - return enable_automatic_output_device_selection_; + // TODO(guidou): Remove this function. http://crbug.com/706408 + bool legacy_enable_automatic_output_device_selection() const { + DCHECK(IsOldAudioConstraints()); + return legacy_enable_automatic_output_device_selection_; } - void set_enable_automatic_output_device_selection(bool value) { - enable_automatic_output_device_selection_ = value; + // TODO(guidou): Remove this function. http://crbug.com/706408 + void set_legacy_enable_automatic_output_device_selection(bool value) { + DCHECK(IsOldAudioConstraints()); + legacy_enable_automatic_output_device_selection_ = value; + } + const AudioCaptureSettings& audio_capture_settings() const { + DCHECK(!IsOldAudioConstraints()); + return audio_capture_settings_; + } + bool is_audio_content_capture() const { + DCHECK(!IsOldAudioConstraints()); + return audio_capture_settings_.HasValue() && is_audio_content_capture_; + } + bool is_audio_device_capture() const { + DCHECK(!IsOldAudioConstraints()); + return audio_capture_settings_.HasValue() && !is_audio_content_capture_; + } + void SetAudioCaptureSettings(const AudioCaptureSettings& settings, + bool is_content_capture) { + DCHECK(settings.HasValue()); + is_audio_content_capture_ = is_content_capture; + audio_capture_settings_ = settings; } const VideoCaptureSettings& video_capture_settings() const { return video_capture_settings_; @@ -305,7 +340,10 @@ const int request_id_; State state_; - bool enable_automatic_output_device_selection_; + // TODO(guidou): Remove this field. http://crbug.com/706408 + bool legacy_enable_automatic_output_device_selection_; + AudioCaptureSettings audio_capture_settings_; + bool is_audio_content_capture_; VideoCaptureSettings video_capture_settings_; bool is_video_content_capture_; blink::WebMediaStream web_stream_; @@ -390,46 +428,63 @@ current_request_info_ = std::move(pending_request_infos_.front()); pending_request_infos_.pop_front(); - // TODO(guidou): Request audio and video capabilities in parallel. + // TODO(guidou): Set up audio and video in parallel. if (current_request_info_->request().Audio()) { - bool request_audio_input_devices = false; - // TODO(guidou): Implement spec-compliant device selection for audio. See - // http://crbug.com/623104. - CopyConstraintsToTrackControls( - current_request_info_->request().AudioConstraints(), - ¤t_request_info_->stream_controls()->audio, - &request_audio_input_devices); - CopyHotwordAndLocalEchoToStreamControls( - current_request_info_->request().AudioConstraints(), - current_request_info_->stream_controls()); - // Check if this input device should be used to select a matching output - // device for audio rendering. - bool enable_automatic_output_device_selection = false; - GetConstraintValueAsBoolean( - current_request_info_->request().AudioConstraints(), - &blink::WebMediaTrackConstraintSet::render_to_associated_sink, - &enable_automatic_output_device_selection); - current_request_info_->set_enable_automatic_output_device_selection( - enable_automatic_output_device_selection); - - if (request_audio_input_devices) { - GetMediaDevicesDispatcher()->EnumerateDevices( - true /* audio_input */, false /* video_input */, - false /* audio_output */, - base::Bind(&UserMediaClientImpl::SelectAudioInputDevice, - weak_factory_.GetWeakPtr(), - current_request_info_->request())); - return; - } + if (IsOldAudioConstraints()) + LegacySetupAudioInput(); + else + SetupAudioInput(); + return; } - - SetupVideoInput(current_request_info_->request()); + SetupVideoInput(); } -void UserMediaClientImpl::SelectAudioInputDevice( +void UserMediaClientImpl::LegacySetupAudioInput() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsOldAudioConstraints()); + DCHECK(current_request_info_); + DCHECK(current_request_info_->request().Audio()); + + bool request_audio_input_devices = false; + CopyConstraintsToTrackControls( + current_request_info_->request().AudioConstraints(), + ¤t_request_info_->stream_controls()->audio, + &request_audio_input_devices); + CopyHotwordAndLocalEchoToStreamControls( + current_request_info_->request().AudioConstraints(), + current_request_info_->stream_controls()); + // Check if this input device should be used to select a matching output + // device for audio rendering. + bool enable_automatic_output_device_selection = false; + GetConstraintValueAsBoolean( + current_request_info_->request().AudioConstraints(), + &blink::WebMediaTrackConstraintSet::render_to_associated_sink, + &enable_automatic_output_device_selection); + current_request_info_->set_legacy_enable_automatic_output_device_selection( + enable_automatic_output_device_selection); + + if (request_audio_input_devices) { + GetMediaDevicesDispatcher()->EnumerateDevices( + true /* audio_input */, false /* video_input */, + false /* audio_output */, + base::Bind(&UserMediaClientImpl::LegacySelectAudioInputDevice, + weak_factory_.GetWeakPtr(), + current_request_info_->request())); + return; + } + + // No further audio setup required. Continue with video. + SetupVideoInput(); +} + +void UserMediaClientImpl::LegacySelectAudioInputDevice( const blink::WebUserMediaRequest& user_media_request, const EnumerationResult& device_enumeration) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsOldAudioConstraints()); + // The frame might reload or |user_media_request| might be cancelled while + // devices are enumerated. Do nothing if a different request is being + // processed at this point. if (!IsCurrentRequestInfo(user_media_request)) return; @@ -440,38 +495,118 @@ if (!PickDeviceId(user_media_request.AudioConstraints(), device_enumeration[MEDIA_DEVICE_TYPE_AUDIO_INPUT], &audio_controls.device_id)) { - GetUserMediaRequestFailed(user_media_request, MEDIA_DEVICE_NO_HARDWARE, ""); + GetUserMediaRequestFailed(MEDIA_DEVICE_NO_HARDWARE, ""); return; } - SetupVideoInput(user_media_request); + // No further audio setup required. Continue with video. + SetupVideoInput(); } -void UserMediaClientImpl::SetupVideoInput( - const blink::WebUserMediaRequest& user_media_request) { +void UserMediaClientImpl::SetupAudioInput() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!IsOldAudioConstraints()); + DCHECK(current_request_info_); + DCHECK(current_request_info_->request().Audio()); + + auto& audio_controls = current_request_info_->stream_controls()->audio; + InitializeTrackControls(current_request_info_->request().AudioConstraints(), + &audio_controls); + if (IsDeviceSource(audio_controls.stream_source)) { + GetMediaDevicesDispatcher()->GetAudioInputCapabilities(base::Bind( + &UserMediaClientImpl::SelectAudioSettings, weak_factory_.GetWeakPtr(), + current_request_info_->request())); + } else { + if (!IsValidAudioContentSource(audio_controls.stream_source)) { + blink::WebString failed_constraint_name = + blink::WebString::FromASCII(current_request_info_->request() + .AudioConstraints() + .Basic() + .media_stream_source.GetName()); + MediaStreamRequestResult result = MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED; + GetUserMediaRequestFailed(result, failed_constraint_name); + return; + } + SelectAudioSettings(current_request_info_->request(), + AudioDeviceCaptureCapabilities()); + } +} + +void UserMediaClientImpl::SelectAudioSettings( + const blink::WebUserMediaRequest& user_media_request, + std::vector<::mojom::AudioInputDeviceCapabilitiesPtr> + audio_input_capabilities) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!IsOldAudioConstraints()); + // The frame might reload or |user_media_request| might be cancelled while + // capabilities are queried. Do nothing if a different request is being + // processed at this point. if (!IsCurrentRequestInfo(user_media_request)) return; - if (!user_media_request.Video()) { + DCHECK(current_request_info_->stream_controls()->audio.requested); + auto settings = + SelectSettingsAudioCapture(std::move(audio_input_capabilities), + user_media_request.AudioConstraints()); + if (!settings.HasValue()) { + blink::WebString failed_constraint_name = + blink::WebString::FromASCII(settings.failed_constraint_name()); + MediaStreamRequestResult result = + failed_constraint_name.IsEmpty() + ? MEDIA_DEVICE_NO_HARDWARE + : MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED; + GetUserMediaRequestFailed(result, failed_constraint_name); + return; + } + current_request_info_->stream_controls()->audio.device_id = + settings.device_id(); + current_request_info_->stream_controls()->disable_local_echo = + settings.disable_local_echo(); + current_request_info_->stream_controls()->hotword_enabled = + settings.hotword_enabled(); + current_request_info_->SetAudioCaptureSettings( + settings, + !IsDeviceSource( + current_request_info_->stream_controls()->audio.stream_source)); + + // No further audio setup required. Continue with video. + SetupVideoInput(); +} + +void UserMediaClientImpl::SetupVideoInput() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(current_request_info_); + + if (!current_request_info_->request().Video()) { GenerateStreamForCurrentRequestInfo(); return; } auto& video_controls = current_request_info_->stream_controls()->video; - InitializeTrackControls(user_media_request.VideoConstraints(), + InitializeTrackControls(current_request_info_->request().VideoConstraints(), &video_controls); if (IsDeviceSource(video_controls.stream_source)) { - GetMediaDevicesDispatcher()->GetVideoInputCapabilities( - base::Bind(&UserMediaClientImpl::SelectVideoDeviceSettings, - weak_factory_.GetWeakPtr(), user_media_request)); + GetMediaDevicesDispatcher()->GetVideoInputCapabilities(base::Bind( + &UserMediaClientImpl::SelectVideoDeviceSettings, + weak_factory_.GetWeakPtr(), current_request_info_->request())); } else { + if (!IsValidVideoContentSource(video_controls.stream_source)) { + blink::WebString failed_constraint_name = + blink::WebString::FromASCII(current_request_info_->request() + .VideoConstraints() + .Basic() + .media_stream_source.GetName()); + MediaStreamRequestResult result = MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED; + GetUserMediaRequestFailed(result, failed_constraint_name); + return; + } base::PostTaskAndReplyWithResult( worker_task_runner_.get(), FROM_HERE, base::Bind(&SelectSettingsVideoContentCapture, - user_media_request.VideoConstraints(), + current_request_info_->request().VideoConstraints(), video_controls.stream_source), base::Bind(&UserMediaClientImpl::FinalizeSelectVideoContentSettings, - weak_factory_.GetWeakPtr(), user_media_request)); + weak_factory_.GetWeakPtr(), + current_request_info_->request())); } } @@ -480,6 +615,9 @@ std::vector<::mojom::VideoInputDeviceCapabilitiesPtr> video_input_capabilities) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // The frame might reload or |user_media_request| might be cancelled while + // capabilities are queried. Do nothing if a different request is being + // processed at this point. if (!IsCurrentRequestInfo(user_media_request)) return; @@ -518,8 +656,7 @@ failed_constraint_name.IsEmpty() ? MEDIA_DEVICE_NO_HARDWARE : MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED; - GetUserMediaRequestFailed(user_media_request, result, - failed_constraint_name); + GetUserMediaRequestFailed(result, failed_constraint_name); return; } current_request_info_->stream_controls()->video.device_id = @@ -540,10 +677,7 @@ blink::WebString failed_constraint_name = blink::WebString::FromASCII(settings.failed_constraint_name()); DCHECK(!failed_constraint_name.IsEmpty()); - blink::WebString device_id_constraint_name = blink::WebString::FromASCII( - user_media_request.VideoConstraints().Basic().device_id.GetName()); - GetUserMediaRequestFailed(user_media_request, - MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED, + GetUserMediaRequestFailed(MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED, failed_constraint_name); return; } @@ -763,7 +897,7 @@ return; } - GetUserMediaRequestFailed(current_request_info_->request(), result, ""); + GetUserMediaRequestFailed(result, ""); DeleteRequestInfo(current_request_info_->request()); } @@ -847,12 +981,18 @@ const blink::WebMediaConstraints& constraints, const MediaStreamSource::ConstraintsCallback& source_ready) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(current_request_info_); // If the audio device is a loopback device (for screen capture), or if the // constraints/effects parameters indicate no audio processing is needed, // create an efficient, direct-path MediaStreamAudioSource instance. + AudioProcessingProperties audio_processing_properties = + IsOldAudioConstraints() ? AudioProcessingProperties::FromConstraints( + constraints, device.device.input) + : current_request_info_->audio_capture_settings() + .audio_processing_properties(); if (IsScreenCaptureMediaType(device.device.type) || !MediaStreamAudioProcessor::WouldModifyAudio( - constraints, device.device.input.effects)) { + audio_processing_properties)) { return new LocalMediaStreamAudioSource(RenderFrameObserver::routing_id(), device, source_ready); } @@ -860,8 +1000,8 @@ // The audio device is not associated with screen capture and also requires // processing. ProcessedLocalAudioSource* source = new ProcessedLocalAudioSource( - RenderFrameObserver::routing_id(), device, constraints, source_ready, - dependency_factory_); + RenderFrameObserver::routing_id(), device, audio_processing_properties, + source_ready, dependency_factory_); return source; } @@ -906,7 +1046,14 @@ DCHECK_EQ(devices.size(), webkit_tracks->size()); StreamDeviceInfoArray overridden_audio_array = devices; - if (!current_request_info_->enable_automatic_output_device_selection()) { + bool render_to_associated_sink = + IsOldAudioConstraints() + ? current_request_info_ + ->legacy_enable_automatic_output_device_selection() + : current_request_info_->audio_capture_settings().HasValue() && + current_request_info_->audio_capture_settings() + .render_to_associated_sink(); + if (!render_to_associated_sink) { // If the GetUserMedia request did not explicitly set the constraint // kMediaStreamRenderToAssociatedSink, the output device parameters must // be removed. @@ -937,7 +1084,7 @@ request_info->request()); media_stream_dispatcher_->OnStreamStarted(label); } else { - GetUserMediaRequestFailed(request_info->request(), result, result_name); + GetUserMediaRequestFailed(result, result_name); blink::WebVector<blink::WebMediaStreamTrack> tracks; request_info->web_stream()->AudioTracks(tracks); @@ -1002,9 +1149,9 @@ } void UserMediaClientImpl::GetUserMediaRequestFailed( - blink::WebUserMediaRequest request, MediaStreamRequestResult result, const blink::WebString& result_name) { + DCHECK(current_request_info_); // Completing the getUserMedia request can lead to that the RenderFrame and // the UserMediaClientImpl is destroyed if the JavaScript code request the // frame to be destroyed within the scope of the callback. Therefore, @@ -1012,7 +1159,8 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(&UserMediaClientImpl::DelayedGetUserMediaRequestFailed, - weak_factory_.GetWeakPtr(), request, result, result_name)); + weak_factory_.GetWeakPtr(), current_request_info_->request(), + result, result_name)); } void UserMediaClientImpl::DelayedGetUserMediaRequestFailed( @@ -1261,13 +1409,25 @@ return media_devices_dispatcher_; } +const AudioCaptureSettings& +UserMediaClientImpl::AudioCaptureSettingsForTesting() const { + DCHECK(current_request_info_); + return current_request_info_->audio_capture_settings(); +} + +const VideoCaptureSettings& +UserMediaClientImpl::VideoCaptureSettingsForTesting() const { + DCHECK(current_request_info_); + return current_request_info_->video_capture_settings(); +} + base::Optional<bool> UserMediaClientImpl::AutomaticOutputDeviceSelectionEnabledForCurrentRequest() { if (!current_request_info_) return base::Optional<bool>(); return base::Optional<bool>( - current_request_info_->enable_automatic_output_device_selection()); + current_request_info_->legacy_enable_automatic_output_device_selection()); } void UserMediaClientImpl::OnDestruct() { @@ -1281,7 +1441,8 @@ const url::Origin& security_origin) : request_id_(request_id), state_(State::NOT_SENT_FOR_GENERATION), - enable_automatic_output_device_selection_(false), + legacy_enable_automatic_output_device_selection_(false), + is_audio_content_capture_(false), is_video_content_capture_(false), request_(request), is_processing_user_gesture_(is_processing_user_gesture), @@ -1293,6 +1454,11 @@ const blink::WebMediaStreamTrack& track, bool is_pending) { DCHECK(track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio); + DCHECK(request_.Audio()); +#if DCHECK_IS_ON() + if (!IsOldAudioConstraints()) + DCHECK(audio_capture_settings_.HasValue()); +#endif MediaStreamAudioSource* native_source = MediaStreamAudioSource::From(track.Source()); // Add the source as pending since OnTrackStarted will expect it to be there.
diff --git a/content/renderer/media/user_media_client_impl.h b/content/renderer/media/user_media_client_impl.h index 0e4f587a..ba4998d 100644 --- a/content/renderer/media/user_media_client_impl.h +++ b/content/renderer/media/user_media_client_impl.h
@@ -37,10 +37,11 @@ } namespace content { -class PeerConnectionDependencyFactory; +class AudioCaptureSettings; class MediaStreamAudioSource; class MediaStreamDispatcher; class MediaStreamVideoSource; +class PeerConnectionDependencyFactory; class VideoCaptureSettings; // UserMediaClientImpl is a delegate for the Media Stream GetUserMedia API. @@ -101,8 +102,7 @@ // |request| have completed. virtual void GetUserMediaRequestSucceeded(const blink::WebMediaStream& stream, blink::WebUserMediaRequest request); - virtual void GetUserMediaRequestFailed(blink::WebUserMediaRequest request, - MediaStreamRequestResult result, + virtual void GetUserMediaRequestFailed(MediaStreamRequestResult result, const blink::WebString& result_name); virtual void EnumerateDevicesSucceded( @@ -121,10 +121,13 @@ // Returns no value if there is no request being processed. Use only for // testing. - // TODO(guidou): Remove this method once spec-compliant constraints algorithm - // for audio is implemented. http://crbug.com/543997 + // TODO(guidou): Remove this function. http://crbug.com/706408 base::Optional<bool> AutomaticOutputDeviceSelectionEnabledForCurrentRequest(); + // Intended to be used only for testing. + const AudioCaptureSettings& AudioCaptureSettingsForTesting() const; + const VideoCaptureSettings& VideoCaptureSettingsForTesting() const; + private: class UserMediaRequestInfo; typedef std::vector<blink::WebMediaStreamSource> LocalStreamSources; @@ -225,21 +228,25 @@ const ::mojom::MediaDevicesDispatcherHostPtr& GetMediaDevicesDispatcher(); - void SelectAudioInputDevice( + // TODO(guidou): Remove these functions. http://crbug.com/706408 + void LegacySetupAudioInput(); + void LegacySelectAudioInputDevice( const blink::WebUserMediaRequest& user_media_request, const EnumerationResult& device_enumeration); - void SetupVideoInput(const blink::WebUserMediaRequest& user_media_request); + void SetupAudioInput(); + void SelectAudioSettings(const blink::WebUserMediaRequest& user_media_request, + std::vector<::mojom::AudioInputDeviceCapabilitiesPtr> + audio_input_capabilities); + void SetupVideoInput(); void SelectVideoDeviceSettings( const blink::WebUserMediaRequest& user_media_request, std::vector<::mojom::VideoInputDeviceCapabilitiesPtr> video_input_capabilities); - void FinalizeSelectVideoDeviceSettings( const blink::WebUserMediaRequest& user_media_request, const VideoCaptureSettings& settings); - void FinalizeSelectVideoContentSettings( const blink::WebUserMediaRequest& user_media_request, const VideoCaptureSettings& settings);
diff --git a/content/renderer/media/user_media_client_impl_unittest.cc b/content/renderer/media/user_media_client_impl_unittest.cc index 8847631..b5505f07 100644 --- a/content/renderer/media/user_media_client_impl_unittest.cc +++ b/content/renderer/media/user_media_client_impl_unittest.cc
@@ -13,15 +13,21 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "content/child/child_process.h" #include "content/common/media/media_devices.h" +#include "content/public/common/content_features.h" #include "content/renderer/media/media_stream.h" +#include "content/renderer/media/media_stream_audio_processor_options.h" #include "content/renderer/media/media_stream_audio_source.h" +#include "content/renderer/media/media_stream_constraints_util.h" +#include "content/renderer/media/media_stream_constraints_util_video_content.h" #include "content/renderer/media/media_stream_track.h" #include "content/renderer/media/mock_constraint_factory.h" #include "content/renderer/media/mock_media_stream_dispatcher.h" #include "content/renderer/media/mock_media_stream_video_source.h" #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h" +#include "media/audio/audio_device_description.h" #include "mojo/public/cpp/bindings/binding.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h" @@ -47,7 +53,6 @@ const char* basic_ideal_value = nullptr, const char* advanced_exact_value = nullptr) { MockConstraintFactory factory; - blink::WebMediaTrackConstraintSet basic; if (basic_exact_value) { factory.basic().device_id.SetExact( blink::WebString::FromUTF8(basic_exact_value)); @@ -161,13 +166,43 @@ void GetAudioInputCapabilities( GetAudioInputCapabilitiesCallback client_callback) override { - NOTREACHED(); + if (IsOldAudioConstraints()) + NOTREACHED(); + + std::vector<::mojom::AudioInputDeviceCapabilitiesPtr> result; + ::mojom::AudioInputDeviceCapabilitiesPtr device = + ::mojom::AudioInputDeviceCapabilities::New(); + device->device_id = media::AudioDeviceDescription::kDefaultDeviceId; + device->parameters = audio_parameters_; + result.push_back(std::move(device)); + + device = ::mojom::AudioInputDeviceCapabilities::New(); + device->device_id = kFakeAudioInputDeviceId1; + device->parameters = audio_parameters_; + result.push_back(std::move(device)); + + device = ::mojom::AudioInputDeviceCapabilities::New(); + device->device_id = kFakeAudioInputDeviceId2; + device->parameters = audio_parameters_; + result.push_back(std::move(device)); + + std::move(client_callback).Run(std::move(result)); + } + + media::AudioParameters& AudioParameters() { return audio_parameters_; } + + void ResetAudioParameters() { + audio_parameters_ = media::AudioParameters::UnavailableDeviceParams(); } MOCK_METHOD2(SubscribeDeviceChangeNotifications, void(MediaDeviceType type, uint32_t subscription_id)); MOCK_METHOD2(UnsubscribeDeviceChangeNotifications, void(MediaDeviceType type, uint32_t subscription_id)); + + private: + media::AudioParameters audio_parameters_ = + media::AudioParameters::UnavailableDeviceParams(); }; class UserMediaClientImplUnderTest : public UserMediaClientImpl { @@ -221,7 +256,6 @@ } void GetUserMediaRequestFailed( - blink::WebUserMediaRequest request_info, content::MediaStreamRequestResult result, const blink::WebString& result_name) override { last_generated_stream_.Reset(); @@ -306,7 +340,15 @@ content::MediaStreamRequestResult error_reason() const { return result_; } blink::WebString error_name() const { return result_name_; } + AudioCaptureSettings AudioSettings() const { + return AudioCaptureSettingsForTesting(); + } + VideoCaptureSettings VideoSettings() const { + return VideoCaptureSettingsForTesting(); + } + // Access to the request queue for testing. + // TODO(guidou): Remove this function. http://crbug.com/704608 bool UserMediaRequestHasAutomaticDeviceSelection() { base::Optional<bool> enabled = AutomaticOutputDeviceSelectionEnabledForCurrentRequest(); @@ -325,11 +367,19 @@ MockMediaStreamVideoCapturerSource* video_source_; }; -class UserMediaClientImplTest : public ::testing::Test { +class UserMediaClientImplTest : public ::testing::TestWithParam<bool> { public: UserMediaClientImplTest() : binding_user_media(&media_devices_dispatcher_), - binding_event_dispatcher_(&media_devices_dispatcher_) {} + binding_event_dispatcher_(&media_devices_dispatcher_) { + if (GetParam()) { + scoped_feature_list_.InitAndEnableFeature( + features::kMediaStreamOldAudioConstraints); + } else { + scoped_feature_list_.InitAndDisableFeature( + features::kMediaStreamOldAudioConstraints); + } + } void SetUp() override { // Create our test object. @@ -463,16 +513,18 @@ std::unique_ptr<UserMediaClientImplUnderTest> user_media_client_impl_; std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_; + // TODO(guidou): Remove this field. http://crbug.com/706408 + base::test::ScopedFeatureList scoped_feature_list_; }; -TEST_F(UserMediaClientImplTest, GenerateMediaStream) { +TEST_P(UserMediaClientImplTest, GenerateMediaStream) { // Generate a stream with both audio and video. blink::WebMediaStream mixed_desc = RequestLocalMediaStream(); } // Test that the same source object is used if two MediaStreams are generated // using the same source. -TEST_F(UserMediaClientImplTest, GenerateTwoMediaStreamsWithSameSource) { +TEST_P(UserMediaClientImplTest, GenerateTwoMediaStreamsWithSameSource) { blink::WebMediaStream desc1 = RequestLocalMediaStream(); blink::WebMediaStream desc2 = RequestLocalMediaStream(); @@ -499,7 +551,7 @@ // Test that the same source object is not used if two MediaStreams are // generated using different sources. -TEST_F(UserMediaClientImplTest, GenerateTwoMediaStreamsWithDifferentSources) { +TEST_P(UserMediaClientImplTest, GenerateTwoMediaStreamsWithDifferentSources) { blink::WebMediaStream desc1 = RequestLocalMediaStream(); // Make sure another device is selected (another |session_id|) in the next // gUM request. @@ -527,7 +579,7 @@ MediaStreamAudioSource::From(desc2_audio_tracks[0].Source())); } -TEST_F(UserMediaClientImplTest, StopLocalTracks) { +TEST_P(UserMediaClientImplTest, StopLocalTracks) { // Generate a stream with both audio and video. blink::WebMediaStream mixed_desc = RequestLocalMediaStream(); @@ -548,7 +600,7 @@ // MediaStream is stopped if there are two MediaStreams with tracks using the // same device. The source is stopped // if there are no more MediaStream tracks using the device. -TEST_F(UserMediaClientImplTest, StopLocalTracksWhenTwoStreamUseSameDevices) { +TEST_P(UserMediaClientImplTest, StopLocalTracksWhenTwoStreamUseSameDevices) { // Generate a stream with both audio and video. blink::WebMediaStream desc1 = RequestLocalMediaStream(); blink::WebMediaStream desc2 = RequestLocalMediaStream(); @@ -578,7 +630,7 @@ EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter()); } -TEST_F(UserMediaClientImplTest, StopSourceWhenMediaStreamGoesOutOfScope) { +TEST_P(UserMediaClientImplTest, StopSourceWhenMediaStreamGoesOutOfScope) { // Generate a stream with both audio and video. RequestLocalMediaStream(); // Makes sure the test itself don't hold a reference to the created @@ -593,7 +645,7 @@ // Test that the MediaStreams are deleted if a new document is loaded in the // frame. -TEST_F(UserMediaClientImplTest, LoadNewDocumentInFrame) { +TEST_P(UserMediaClientImplTest, LoadNewDocumentInFrame) { // Test a stream with both audio and video. blink::WebMediaStream mixed_desc = RequestLocalMediaStream(); blink::WebMediaStream desc2 = RequestLocalMediaStream(); @@ -604,7 +656,7 @@ } // This test what happens if a video source to a MediaSteam fails to start. -TEST_F(UserMediaClientImplTest, MediaVideoSourceFailToStart) { +TEST_P(UserMediaClientImplTest, MediaVideoSourceFailToStart) { user_media_client_impl_->RequestUserMediaForTest(); FakeMediaStreamDispatcherRequestUserMediaComplete(); FailToStartMockedVideoSource(); @@ -619,7 +671,7 @@ } // This test what happens if an audio source fail to initialize. -TEST_F(UserMediaClientImplTest, MediaAudioSourceFailToInitialize) { +TEST_P(UserMediaClientImplTest, MediaAudioSourceFailToInitialize) { user_media_client_impl_->SetCreateSourceThatFails(true); user_media_client_impl_->RequestUserMediaForTest(); FakeMediaStreamDispatcherRequestUserMediaComplete(); @@ -636,7 +688,7 @@ // This test what happens if UserMediaClientImpl is deleted before a source has // started. -TEST_F(UserMediaClientImplTest, MediaStreamImplShutDown) { +TEST_P(UserMediaClientImplTest, MediaStreamImplShutDown) { user_media_client_impl_->RequestUserMediaForTest(); FakeMediaStreamDispatcherRequestUserMediaComplete(); EXPECT_EQ(1, ms_dispatcher_->request_stream_counter()); @@ -647,7 +699,7 @@ // This test what happens if a new document is loaded in the frame while the // MediaStream is being generated by the MediaStreamDispatcher. -TEST_F(UserMediaClientImplTest, ReloadFrameWhileGeneratingStream) { +TEST_P(UserMediaClientImplTest, ReloadFrameWhileGeneratingStream) { user_media_client_impl_->RequestUserMediaForTest(); LoadNewDocumentInFrame(); EXPECT_EQ(1, ms_dispatcher_->request_stream_counter()); @@ -659,7 +711,7 @@ // This test what happens if a newdocument is loaded in the frame while the // sources are being started. -TEST_F(UserMediaClientImplTest, ReloadFrameWhileGeneratingSources) { +TEST_P(UserMediaClientImplTest, ReloadFrameWhileGeneratingSources) { user_media_client_impl_->RequestUserMediaForTest(); FakeMediaStreamDispatcherRequestUserMediaComplete(); EXPECT_EQ(1, ms_dispatcher_->request_stream_counter()); @@ -672,7 +724,7 @@ // This test what happens if stop is called on a track after the frame has // been reloaded. -TEST_F(UserMediaClientImplTest, StopTrackAfterReload) { +TEST_P(UserMediaClientImplTest, StopTrackAfterReload) { blink::WebMediaStream mixed_desc = RequestLocalMediaStream(); EXPECT_EQ(1, ms_dispatcher_->request_stream_counter()); LoadNewDocumentInFrame(); @@ -693,7 +745,7 @@ EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter()); } -TEST_F(UserMediaClientImplTest, EnumerateMediaDevices) { +TEST_P(UserMediaClientImplTest, EnumerateMediaDevices) { user_media_client_impl_->RequestMediaDevicesForTest(); base::RunLoop().RunUntilIdle(); @@ -749,7 +801,11 @@ user_media_client_impl_->last_devices()[4].GroupId())); } -TEST_F(UserMediaClientImplTest, RenderToAssociatedSinkConstraint) { +// TODO(guidou): Remove this test. http://crbug.com/706408 +TEST_P(UserMediaClientImplTest, RenderToAssociatedSinkConstraint) { + if (!IsOldAudioConstraints()) + return; + // For a UserMediaRequest without audio, we expect false. blink::WebUserMediaRequest request = blink::WebUserMediaRequest::CreateForTesting(blink::WebMediaConstraints(), @@ -786,7 +842,256 @@ factory.CreateWebMediaConstraints())); } -TEST_F(UserMediaClientImplTest, ObserveMediaDeviceChanges) { +TEST_P(UserMediaClientImplTest, DefaultConstraintsPropagate) { + if (IsOldAudioConstraints()) + return; + + blink::WebUserMediaRequest request = + blink::WebUserMediaRequest::CreateForTesting(CreateDefaultConstraints(), + CreateDefaultConstraints()); + user_media_client_impl_->RequestUserMediaForTest(request); + AudioCaptureSettings audio_capture_settings = + user_media_client_impl_->AudioSettings(); + VideoCaptureSettings video_capture_settings = + user_media_client_impl_->VideoSettings(); + user_media_client_impl_->CancelUserMediaRequest(request); + + // Check default values selected by the constraints algorithm. + EXPECT_TRUE(audio_capture_settings.HasValue()); + EXPECT_EQ(media::AudioDeviceDescription::kDefaultDeviceId, + audio_capture_settings.device_id()); + EXPECT_FALSE(audio_capture_settings.hotword_enabled()); + EXPECT_TRUE(audio_capture_settings.disable_local_echo()); + EXPECT_FALSE(audio_capture_settings.render_to_associated_sink()); + + const AudioProcessingProperties& properties = + audio_capture_settings.audio_processing_properties(); + EXPECT_TRUE(properties.enable_sw_echo_cancellation); + EXPECT_FALSE(properties.disable_hw_echo_cancellation); + EXPECT_FALSE(properties.goog_audio_mirroring); + EXPECT_TRUE(properties.goog_auto_gain_control); + // The default value for goog_experimental_echo_cancellation is platform + // dependent. + EXPECT_EQ(AudioProcessingProperties().goog_experimental_echo_cancellation, + properties.goog_experimental_echo_cancellation); + EXPECT_TRUE(properties.goog_typing_noise_detection); + EXPECT_TRUE(properties.goog_noise_suppression); + EXPECT_TRUE(properties.goog_experimental_noise_suppression); + EXPECT_TRUE(properties.goog_beamforming); + EXPECT_TRUE(properties.goog_highpass_filter); + EXPECT_TRUE(properties.goog_experimental_auto_gain_control); + EXPECT_TRUE(properties.goog_array_geometry.empty()); + + EXPECT_TRUE(video_capture_settings.HasValue()); + EXPECT_EQ(video_capture_settings.Width(), + MediaStreamVideoSource::kDefaultWidth); + EXPECT_EQ(video_capture_settings.Height(), + MediaStreamVideoSource::kDefaultHeight); + EXPECT_EQ(video_capture_settings.FrameRate(), + MediaStreamVideoSource::kDefaultFrameRate); + EXPECT_EQ(video_capture_settings.ResolutionChangePolicy(), + media::RESOLUTION_POLICY_FIXED_RESOLUTION); + EXPECT_EQ(video_capture_settings.PowerLineFrequency(), + media::PowerLineFrequency::FREQUENCY_DEFAULT); + EXPECT_FALSE(video_capture_settings.noise_reduction()); + EXPECT_EQ(video_capture_settings.min_frame_rate(), 1.0); + + const VideoTrackAdapterSettings& track_settings = + video_capture_settings.track_adapter_settings(); + EXPECT_EQ(track_settings.max_width, MediaStreamVideoSource::kDefaultWidth); + EXPECT_EQ(track_settings.max_height, MediaStreamVideoSource::kDefaultHeight); + EXPECT_EQ(track_settings.min_aspect_ratio, + 1.0 / MediaStreamVideoSource::kDefaultHeight); + EXPECT_EQ(track_settings.max_aspect_ratio, + MediaStreamVideoSource::kDefaultWidth); + // 0.0 is the default max_frame_rate and it indicates no frame-rate adjustment + EXPECT_EQ(track_settings.max_frame_rate, 0.0); +} + +TEST_P(UserMediaClientImplTest, DefaultTabCapturePropagate) { + if (IsOldAudioConstraints()) + return; + + MockConstraintFactory factory; + factory.basic().media_stream_source.SetExact( + blink::WebString::FromASCII(kMediaStreamSourceTab)); + blink::WebMediaConstraints audio_constraints = + factory.CreateWebMediaConstraints(); + blink::WebMediaConstraints video_constraints = + factory.CreateWebMediaConstraints(); + blink::WebUserMediaRequest request = + blink::WebUserMediaRequest::CreateForTesting(audio_constraints, + video_constraints); + user_media_client_impl_->RequestUserMediaForTest(request); + AudioCaptureSettings audio_capture_settings = + user_media_client_impl_->AudioSettings(); + VideoCaptureSettings video_capture_settings = + user_media_client_impl_->VideoSettings(); + user_media_client_impl_->CancelUserMediaRequest(request); + + // Check default values selected by the constraints algorithm. + EXPECT_TRUE(audio_capture_settings.HasValue()); + EXPECT_EQ(std::string(), audio_capture_settings.device_id()); + EXPECT_FALSE(audio_capture_settings.hotword_enabled()); + EXPECT_TRUE(audio_capture_settings.disable_local_echo()); + EXPECT_FALSE(audio_capture_settings.render_to_associated_sink()); + + const AudioProcessingProperties& properties = + audio_capture_settings.audio_processing_properties(); + EXPECT_FALSE(properties.enable_sw_echo_cancellation); + EXPECT_FALSE(properties.disable_hw_echo_cancellation); + EXPECT_FALSE(properties.goog_audio_mirroring); + EXPECT_FALSE(properties.goog_auto_gain_control); + EXPECT_FALSE(properties.goog_experimental_echo_cancellation); + EXPECT_FALSE(properties.goog_typing_noise_detection); + EXPECT_FALSE(properties.goog_noise_suppression); + EXPECT_FALSE(properties.goog_experimental_noise_suppression); + EXPECT_FALSE(properties.goog_beamforming); + EXPECT_FALSE(properties.goog_highpass_filter); + EXPECT_FALSE(properties.goog_experimental_auto_gain_control); + EXPECT_TRUE(properties.goog_array_geometry.empty()); + + EXPECT_TRUE(video_capture_settings.HasValue()); + EXPECT_EQ(video_capture_settings.Width(), kDefaultScreenCastWidth); + EXPECT_EQ(video_capture_settings.Height(), kDefaultScreenCastHeight); + EXPECT_EQ(video_capture_settings.FrameRate(), kDefaultScreenCastFrameRate); + EXPECT_EQ(video_capture_settings.ResolutionChangePolicy(), + media::RESOLUTION_POLICY_FIXED_RESOLUTION); + EXPECT_EQ(video_capture_settings.PowerLineFrequency(), + media::PowerLineFrequency::FREQUENCY_DEFAULT); + EXPECT_FALSE(video_capture_settings.noise_reduction()); + EXPECT_FALSE(video_capture_settings.min_frame_rate().has_value()); + EXPECT_FALSE(video_capture_settings.max_frame_rate().has_value()); + + const VideoTrackAdapterSettings& track_settings = + video_capture_settings.track_adapter_settings(); + EXPECT_EQ(track_settings.max_width, kDefaultScreenCastWidth); + EXPECT_EQ(track_settings.max_height, kDefaultScreenCastHeight); + EXPECT_EQ(track_settings.min_aspect_ratio, 1.0 / kMaxScreenCastDimension); + EXPECT_EQ(track_settings.max_aspect_ratio, kMaxScreenCastDimension); + // 0.0 is the default max_frame_rate and it indicates no frame-rate adjustment + EXPECT_EQ(track_settings.max_frame_rate, 0.0); +} + +TEST_P(UserMediaClientImplTest, DefaultDesktopCapturePropagate) { + if (IsOldAudioConstraints()) + return; + + MockConstraintFactory factory; + factory.basic().media_stream_source.SetExact( + blink::WebString::FromASCII(kMediaStreamSourceDesktop)); + blink::WebMediaConstraints audio_constraints = + factory.CreateWebMediaConstraints(); + blink::WebMediaConstraints video_constraints = + factory.CreateWebMediaConstraints(); + blink::WebUserMediaRequest request = + blink::WebUserMediaRequest::CreateForTesting(audio_constraints, + video_constraints); + user_media_client_impl_->RequestUserMediaForTest(request); + AudioCaptureSettings audio_capture_settings = + user_media_client_impl_->AudioSettings(); + VideoCaptureSettings video_capture_settings = + user_media_client_impl_->VideoSettings(); + user_media_client_impl_->CancelUserMediaRequest(request); + + // Check default values selected by the constraints algorithm. + EXPECT_TRUE(audio_capture_settings.HasValue()); + EXPECT_EQ(std::string(), audio_capture_settings.device_id()); + EXPECT_FALSE(audio_capture_settings.hotword_enabled()); + EXPECT_FALSE(audio_capture_settings.disable_local_echo()); + EXPECT_FALSE(audio_capture_settings.render_to_associated_sink()); + + const AudioProcessingProperties& properties = + audio_capture_settings.audio_processing_properties(); + EXPECT_FALSE(properties.enable_sw_echo_cancellation); + EXPECT_FALSE(properties.disable_hw_echo_cancellation); + EXPECT_FALSE(properties.goog_audio_mirroring); + EXPECT_FALSE(properties.goog_auto_gain_control); + EXPECT_FALSE(properties.goog_experimental_echo_cancellation); + EXPECT_FALSE(properties.goog_typing_noise_detection); + EXPECT_FALSE(properties.goog_noise_suppression); + EXPECT_FALSE(properties.goog_experimental_noise_suppression); + EXPECT_FALSE(properties.goog_beamforming); + EXPECT_FALSE(properties.goog_highpass_filter); + EXPECT_FALSE(properties.goog_experimental_auto_gain_control); + EXPECT_TRUE(properties.goog_array_geometry.empty()); + + EXPECT_TRUE(video_capture_settings.HasValue()); + EXPECT_EQ(video_capture_settings.Width(), kDefaultScreenCastWidth); + EXPECT_EQ(video_capture_settings.Height(), kDefaultScreenCastHeight); + EXPECT_EQ(video_capture_settings.FrameRate(), kDefaultScreenCastFrameRate); + EXPECT_EQ(video_capture_settings.ResolutionChangePolicy(), + media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT); + EXPECT_EQ(video_capture_settings.PowerLineFrequency(), + media::PowerLineFrequency::FREQUENCY_DEFAULT); + EXPECT_FALSE(video_capture_settings.noise_reduction()); + EXPECT_FALSE(video_capture_settings.min_frame_rate().has_value()); + EXPECT_FALSE(video_capture_settings.max_frame_rate().has_value()); + + const VideoTrackAdapterSettings& track_settings = + video_capture_settings.track_adapter_settings(); + EXPECT_EQ(track_settings.max_width, kDefaultScreenCastWidth); + EXPECT_EQ(track_settings.max_height, kDefaultScreenCastHeight); + EXPECT_EQ(track_settings.min_aspect_ratio, 1.0 / kMaxScreenCastDimension); + EXPECT_EQ(track_settings.max_aspect_ratio, kMaxScreenCastDimension); + // 0.0 is the default max_frame_rate and it indicates no frame-rate adjustment + EXPECT_EQ(track_settings.max_frame_rate, 0.0); +} + +TEST_P(UserMediaClientImplTest, NonDefaultAudioConstraintsPropagate) { + if (IsOldAudioConstraints()) + return; + + MockConstraintFactory factory; + factory.basic().device_id.SetExact( + blink::WebString::FromASCII(kFakeAudioInputDeviceId1)); + factory.basic().hotword_enabled.SetExact(true); + factory.basic().disable_local_echo.SetExact(true); + factory.basic().render_to_associated_sink.SetExact(true); + factory.basic().echo_cancellation.SetExact(false); + factory.basic().goog_audio_mirroring.SetExact(true); + factory.basic().goog_typing_noise_detection.SetExact(true); + factory.basic().goog_array_geometry.SetExact( + blink::WebString::FromASCII("1 1 1")); + blink::WebMediaConstraints audio_constraints = + factory.CreateWebMediaConstraints(); + // Request contains only audio + blink::WebUserMediaRequest request = + blink::WebUserMediaRequest::CreateForTesting( + audio_constraints, blink::WebMediaConstraints()); + user_media_client_impl_->RequestUserMediaForTest(request); + AudioCaptureSettings audio_capture_settings = + user_media_client_impl_->AudioSettings(); + VideoCaptureSettings video_capture_settings = + user_media_client_impl_->VideoSettings(); + user_media_client_impl_->CancelUserMediaRequest(request); + + EXPECT_FALSE(video_capture_settings.HasValue()); + + EXPECT_TRUE(audio_capture_settings.HasValue()); + EXPECT_EQ(kFakeAudioInputDeviceId1, audio_capture_settings.device_id()); + EXPECT_TRUE(audio_capture_settings.hotword_enabled()); + EXPECT_TRUE(audio_capture_settings.disable_local_echo()); + EXPECT_TRUE(audio_capture_settings.render_to_associated_sink()); + + const AudioProcessingProperties& properties = + audio_capture_settings.audio_processing_properties(); + EXPECT_FALSE(properties.enable_sw_echo_cancellation); + EXPECT_TRUE(properties.disable_hw_echo_cancellation); + EXPECT_TRUE(properties.goog_audio_mirroring); + EXPECT_FALSE(properties.goog_auto_gain_control); + EXPECT_FALSE(properties.goog_experimental_echo_cancellation); + EXPECT_TRUE(properties.goog_typing_noise_detection); + EXPECT_FALSE(properties.goog_noise_suppression); + EXPECT_FALSE(properties.goog_experimental_noise_suppression); + EXPECT_FALSE(properties.goog_beamforming); + EXPECT_FALSE(properties.goog_highpass_filter); + EXPECT_FALSE(properties.goog_experimental_auto_gain_control); + const std::vector<media::Point> kGeometry = {{1.0, 1.0, 1.0}}; + EXPECT_EQ(kGeometry, properties.goog_array_geometry); +} + +TEST_P(UserMediaClientImplTest, ObserveMediaDeviceChanges) { EXPECT_CALL(media_devices_dispatcher_, SubscribeDeviceChangeNotifications( MEDIA_DEVICE_TYPE_AUDIO_INPUT, _)); EXPECT_CALL(media_devices_dispatcher_, SubscribeDeviceChangeNotifications( @@ -822,7 +1127,7 @@ } // This test what happens if the audio stream has same id with video stream. -TEST_F(UserMediaClientImplTest, AudioVideoWithSameId) { +TEST_P(UserMediaClientImplTest, AudioVideoWithSameId) { ms_dispatcher_->TestSameId(); // Generate a stream with both audio and video. @@ -847,7 +1152,7 @@ EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter()); } -TEST_F(UserMediaClientImplTest, CreateWithMandatoryInvalidAudioDeviceId) { +TEST_P(UserMediaClientImplTest, CreateWithMandatoryInvalidAudioDeviceId) { blink::WebMediaConstraints audio_constraints = CreateDeviceConstraints(kInvalidDeviceId); blink::WebUserMediaRequest request = @@ -858,7 +1163,7 @@ user_media_client_impl_->request_state()); } -TEST_F(UserMediaClientImplTest, CreateWithMandatoryInvalidVideoDeviceId) { +TEST_P(UserMediaClientImplTest, CreateWithMandatoryInvalidVideoDeviceId) { blink::WebMediaConstraints video_constraints = CreateDeviceConstraints(kInvalidDeviceId); blink::WebUserMediaRequest request = @@ -869,7 +1174,7 @@ user_media_client_impl_->request_state()); } -TEST_F(UserMediaClientImplTest, CreateWithMandatoryValidDeviceIds) { +TEST_P(UserMediaClientImplTest, CreateWithMandatoryValidDeviceIds) { blink::WebMediaConstraints audio_constraints = CreateDeviceConstraints(kFakeAudioInputDeviceId1); blink::WebMediaConstraints video_constraints = @@ -879,7 +1184,7 @@ kFakeVideoInputDeviceId1); } -TEST_F(UserMediaClientImplTest, CreateWithBasicIdealValidDeviceId) { +TEST_P(UserMediaClientImplTest, CreateWithBasicIdealValidDeviceId) { blink::WebMediaConstraints audio_constraints = CreateDeviceConstraints(nullptr, kFakeAudioInputDeviceId1); blink::WebMediaConstraints video_constraints = @@ -889,7 +1194,7 @@ kFakeVideoInputDeviceId1); } -TEST_F(UserMediaClientImplTest, CreateWithAdvancedExactValidDeviceId) { +TEST_P(UserMediaClientImplTest, CreateWithAdvancedExactValidDeviceId) { blink::WebMediaConstraints audio_constraints = CreateDeviceConstraints(nullptr, nullptr, kFakeAudioInputDeviceId1); blink::WebMediaConstraints video_constraints = CreateDeviceConstraints( @@ -899,19 +1204,23 @@ kFakeVideoInputDeviceId1); } -TEST_F(UserMediaClientImplTest, CreateWithAllOptionalInvalidDeviceId) { +TEST_P(UserMediaClientImplTest, CreateWithAllOptionalInvalidDeviceId) { blink::WebMediaConstraints audio_constraints = CreateDeviceConstraints(nullptr, kInvalidDeviceId, kInvalidDeviceId); blink::WebMediaConstraints video_constraints = CreateDeviceConstraints(nullptr, kInvalidDeviceId, kInvalidDeviceId); // MockMediaStreamDispatcher uses empty string as default audio device ID. // MockMediaDevicesDispatcher uses the first device in the enumeration as - // default video device ID. + // default audio or video device ID. + std::string expected_audio_device_id = + IsOldAudioConstraints() ? std::string() + : media::AudioDeviceDescription::kDefaultDeviceId; TestValidRequestWithConstraints(audio_constraints, video_constraints, - std::string(), kFakeVideoInputDeviceId1); + expected_audio_device_id, + kFakeVideoInputDeviceId1); } -TEST_F(UserMediaClientImplTest, CreateWithFacingModeUser) { +TEST_P(UserMediaClientImplTest, CreateWithFacingModeUser) { blink::WebMediaConstraints audio_constraints = CreateDeviceConstraints(kFakeAudioInputDeviceId1); blink::WebMediaConstraints video_constraints = @@ -922,7 +1231,7 @@ kFakeVideoInputDeviceId1); } -TEST_F(UserMediaClientImplTest, CreateWithFacingModeEnvironment) { +TEST_P(UserMediaClientImplTest, CreateWithFacingModeEnvironment) { blink::WebMediaConstraints audio_constraints = CreateDeviceConstraints(kFakeAudioInputDeviceId1); blink::WebMediaConstraints video_constraints = @@ -933,4 +1242,8 @@ kFakeVideoInputDeviceId2); } +INSTANTIATE_TEST_CASE_P(, + UserMediaClientImplTest, + testing::Values(true, false)); + } // namespace content
diff --git a/content/renderer/media/video_track_adapter.h b/content/renderer/media/video_track_adapter.h index 01237e5..c37fe6e 100644 --- a/content/renderer/media/video_track_adapter.h +++ b/content/renderer/media/video_track_adapter.h
@@ -34,6 +34,9 @@ int max_height; double min_aspect_ratio; double max_aspect_ratio; + // A |max_frame_rate| of zero is used to signal that no frame-rate adjustment + // is necessary. + // TODO(guidou): Change this to base::Optional. http://crbug.com/734528 double max_frame_rate; // If supplied, this can be used to detect frames from a rotated device. base::Optional<gfx::Size> expected_native_size;
diff --git a/content/renderer/media/webrtc/processed_local_audio_source.cc b/content/renderer/media/webrtc/processed_local_audio_source.cc index a4fb2da..6fea798 100644 --- a/content/renderer/media/webrtc/processed_local_audio_source.cc +++ b/content/renderer/media/webrtc/processed_local_audio_source.cc
@@ -4,6 +4,9 @@ #include "content/renderer/media/webrtc/processed_local_audio_source.h" +#include <algorithm> +#include <utility> + #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" @@ -29,13 +32,13 @@ ProcessedLocalAudioSource::ProcessedLocalAudioSource( int consumer_render_frame_id, const StreamDeviceInfo& device_info, - const blink::WebMediaConstraints& constraints, + const AudioProcessingProperties& audio_processing_properties, const ConstraintsCallback& started_callback, PeerConnectionDependencyFactory* factory) : MediaStreamAudioSource(true /* is_local_source */), consumer_render_frame_id_(consumer_render_frame_id), pc_factory_(factory), - constraints_(constraints), + audio_processing_properties_(audio_processing_properties), started_callback_(started_callback), volume_(0), allow_invalid_render_frame_id_for_testing_(false) { @@ -91,28 +94,15 @@ device_info().device.matched_output.frames_per_buffer, device_info().device.input.effects)); - // Sanity-check that the constraints, plus the additional input effects are - // valid when combined. - const MediaAudioConstraints audio_constraints( - constraints_, device_info().device.input.effects); - if (!audio_constraints.IsValid()) { - WebRtcLogMessage("ProcessedLocalAudioSource::EnsureSourceIsStarted() fails " - " because MediaAudioConstraints are not valid."); - return false; - } - - if (device_info().device.input.effects & - media::AudioParameters::ECHO_CANCELLER) { - // TODO(hta): Figure out if we should be looking at echoCancellation. - // Previous code had googEchoCancellation only. - const blink::BooleanConstraint& echoCancellation = - constraints_.Basic().goog_echo_cancellation; - if (echoCancellation.HasExact() && !echoCancellation.Exact()) { - StreamDeviceInfo modified_device_info(device_info()); - modified_device_info.device.input.effects &= - ~media::AudioParameters::ECHO_CANCELLER; - SetDeviceInfo(modified_device_info); - } + // Disable HW echo cancellation if constraints explicitly specified no + // echo cancellation. + if (audio_processing_properties_.disable_hw_echo_cancellation && + (device_info().device.input.effects & + media::AudioParameters::ECHO_CANCELLER)) { + StreamDeviceInfo modified_device_info(device_info()); + modified_device_info.device.input.effects &= + ~media::AudioParameters::ECHO_CANCELLER; + SetDeviceInfo(modified_device_info); } // Create the MediaStreamAudioProcessor, bound to the WebRTC audio device @@ -125,7 +115,7 @@ return false; } audio_processor_ = new rtc::RefCountedObject<MediaStreamAudioProcessor>( - constraints_, device_info().device.input, rtc_audio_device); + audio_processing_properties_, rtc_audio_device); // If KEYBOARD_MIC effect is set, change the layout to the corresponding // layout that includes the keyboard mic. @@ -133,7 +123,7 @@ device_info().device.input.channel_layout); if ((device_info().device.input.effects & media::AudioParameters::KEYBOARD_MIC) && - audio_constraints.GetGoogExperimentalNoiseSuppression()) { + audio_processing_properties_.goog_experimental_noise_suppression) { if (channel_layout == media::CHANNEL_LAYOUT_STEREO) { channel_layout = media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC; DVLOG(1) << "Changed stereo layout to stereo + keyboard mic layout due "
diff --git a/content/renderer/media/webrtc/processed_local_audio_source.h b/content/renderer/media/webrtc/processed_local_audio_source.h index c712472..ad54656 100644 --- a/content/renderer/media/webrtc/processed_local_audio_source.h +++ b/content/renderer/media/webrtc/processed_local_audio_source.h
@@ -5,6 +5,8 @@ #ifndef CONTENT_RENDERER_MEDIA_WEBRTC_PROCESSED_LOCAL_AUDIO_SOURCE_H_ #define CONTENT_RENDERER_MEDIA_WEBRTC_PROCESSED_LOCAL_AUDIO_SOURCE_H_ +#include <string> + #include "base/atomicops.h" #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -36,11 +38,12 @@ // |consumer_render_frame_id| references the RenderFrame that will consume the // audio data. Audio parameters and (optionally) a pre-existing audio session // ID are derived from |device_info|. |factory| must outlive this instance. - ProcessedLocalAudioSource(int consumer_render_frame_id, - const StreamDeviceInfo& device_info, - const blink::WebMediaConstraints& constraints, - const ConstraintsCallback& started_callback, - PeerConnectionDependencyFactory* factory); + ProcessedLocalAudioSource( + int consumer_render_frame_id, + const StreamDeviceInfo& device_info, + const AudioProcessingProperties& audio_processing_properties, + const ConstraintsCallback& started_callback, + PeerConnectionDependencyFactory* factory); ~ProcessedLocalAudioSource() final; @@ -55,10 +58,8 @@ allow_invalid_render_frame_id_for_testing_ = allowed; } - // Gets/Sets source constraints. Using this is optional, but must be done - // before the first call to ConnectToTrack(). - const blink::WebMediaConstraints& source_constraints() const { - return constraints_; + const AudioProcessingProperties& audio_processing_properties() const { + return audio_processing_properties_; } // The following accessors are not valid until after the source is started @@ -112,8 +113,7 @@ // or data flow changes are being called on the main thread. base::ThreadChecker thread_checker_; - // Cached audio constraints for the capturer. - const blink::WebMediaConstraints constraints_; + AudioProcessingProperties audio_processing_properties_; // Callback that's called when the audio source has been initialized. ConstraintsCallback started_callback_;
diff --git a/content/renderer/media/webrtc/processed_local_audio_source_unittest.cc b/content/renderer/media/webrtc/processed_local_audio_source_unittest.cc index 95bf66d..e0bd3aa8 100644 --- a/content/renderer/media/webrtc/processed_local_audio_source_unittest.cc +++ b/content/renderer/media/webrtc/processed_local_audio_source_unittest.cc
@@ -9,9 +9,9 @@ #include "base/message_loop/message_loop.h" #include "build/build_config.h" #include "content/public/renderer/media_stream_audio_sink.h" +#include "content/renderer/media/media_stream_audio_processor_options.h" #include "content/renderer/media/media_stream_audio_track.h" #include "content/renderer/media/mock_audio_device_factory.h" -#include "content/renderer/media/mock_constraint_factory.h" #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h" #include "content/renderer/media/webrtc/processed_local_audio_source.h" #include "media/base/audio_bus.h" @@ -96,13 +96,13 @@ } void CreateProcessedLocalAudioSource( - const blink::WebMediaConstraints& constraints) { + const AudioProcessingProperties& properties) { ProcessedLocalAudioSource* const source = new ProcessedLocalAudioSource( -1 /* consumer_render_frame_id is N/A for non-browser tests */, StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE, "Mock audio device", "mock_audio_device_id", kSampleRate, kChannelLayout, kRequestedBufferSize), - constraints, + properties, base::Bind(&ProcessedLocalAudioSourceTest::OnAudioSourceStarted, base::Unretained(this)), &mock_dependency_factory_); @@ -161,11 +161,9 @@ // Turn off the default constraints so the sink will get audio in chunks of // the native buffer size. - MockConstraintFactory constraint_factory; - constraint_factory.DisableDefaultAudioConstraints(); - - CreateProcessedLocalAudioSource( - constraint_factory.CreateWebMediaConstraints()); + AudioProcessingProperties properties; + properties.DisableDefaultPropertiesForTesting(); + CreateProcessedLocalAudioSource(properties); // Connect the track, and expect the MockCapturerSource to be initialized and // started by ProcessedLocalAudioSource. @@ -206,35 +204,5 @@ MediaStreamAudioTrack::From(blink_audio_track())->Stop(); } -// Tests that the source is not started when invalid audio constraints are -// present. -TEST_F(ProcessedLocalAudioSourceTest, FailToStartWithWrongConstraints) { - MockConstraintFactory constraint_factory; - const std::string dummy_constraint = "dummy"; - // Set a non-audio constraint. - constraint_factory.basic().width.SetExact(240); - - CreateProcessedLocalAudioSource( - constraint_factory.CreateWebMediaConstraints()); - - // Expect the MockCapturerSource is never initialized/started and the - // ConnectToTrack() operation fails due to the invalid constraint. - EXPECT_CALL(*mock_audio_device_factory()->mock_capturer_source(), - Initialize(_, capture_source_callback(), -1)) - .Times(0); - EXPECT_CALL(*mock_audio_device_factory()->mock_capturer_source(), - SetAutomaticGainControl(true)).Times(0); - EXPECT_CALL(*mock_audio_device_factory()->mock_capturer_source(), Start()) - .Times(0); - EXPECT_FALSE(audio_source()->ConnectToTrack(blink_audio_track())); - - // Even though ConnectToTrack() failed, there should still have been a new - // MediaStreamAudioTrack instance created, owned by the - // blink::WebMediaStreamTrack. - EXPECT_TRUE(MediaStreamAudioTrack::From(blink_audio_track())); -} - -// TODO(miu): There's a lot of logic in ProcessedLocalAudioSource around -// constraints processing and validation that should have unit testing. } // namespace content
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc b/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc index 6419adf..e20521ed 100644 --- a/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc +++ b/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc
@@ -36,6 +36,7 @@ TrackAdded(video_track); MediaStream* const native_stream = MediaStream::GetMediaStream(web_stream_); + DCHECK(native_stream); native_stream->AddObserver(this); }
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc b/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc new file mode 100644 index 0000000..e309151 --- /dev/null +++ b/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc
@@ -0,0 +1,88 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h" + +namespace content { + +WebRtcMediaStreamAdapterMap::AdapterEntry::AdapterEntry( + std::unique_ptr<WebRtcMediaStreamAdapter> adapter) + : adapter(std::move(adapter)), ref_count(0) { + DCHECK(this->adapter); +} + +WebRtcMediaStreamAdapterMap::AdapterEntry::AdapterEntry(AdapterEntry&& other) + : adapter(other.adapter.release()), ref_count(other.ref_count) {} + +WebRtcMediaStreamAdapterMap::AdapterEntry::~AdapterEntry() { + // |ref_count| is allowed to be non-zero only if this entry has been moved + // which is the case if the |adapter| has already been released. + DCHECK(!ref_count || !adapter); +} + +WebRtcMediaStreamAdapterMap::AdapterRef::AdapterRef( + scoped_refptr<WebRtcMediaStreamAdapterMap> map, + const MapEntryIterator& it) + : map_(std::move(map)), it_(it) { + DCHECK(map_); + DCHECK(map_->main_thread_->BelongsToCurrentThread()); + DCHECK(it_ != map_->local_stream_adapters_.end()); + DCHECK(entry()->adapter); + ++entry()->ref_count; +} + +WebRtcMediaStreamAdapterMap::AdapterRef::~AdapterRef() { + DCHECK(map_->main_thread_->BelongsToCurrentThread()); + if (--entry()->ref_count == 0) { + map_->local_stream_adapters_.erase(it_); + } +} + +WebRtcMediaStreamAdapterMap::WebRtcMediaStreamAdapterMap( + PeerConnectionDependencyFactory* const factory, + scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map) + : factory_(factory), + main_thread_(base::ThreadTaskRunnerHandle::Get()), + track_adapter_map_(std::move(track_adapter_map)) { + DCHECK(factory_); + DCHECK(main_thread_); + DCHECK(track_adapter_map_); +} + +WebRtcMediaStreamAdapterMap::~WebRtcMediaStreamAdapterMap() { + DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(local_stream_adapters_.empty()); +} + +std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> +WebRtcMediaStreamAdapterMap::GetLocalStreamAdapter(const std::string& id) { + DCHECK(main_thread_->BelongsToCurrentThread()); + auto it = local_stream_adapters_.find(id); + if (it == local_stream_adapters_.end()) + return nullptr; + return base::WrapUnique(new AdapterRef(this, it)); +} + +std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> +WebRtcMediaStreamAdapterMap::GetOrCreateLocalStreamAdapter( + const blink::WebMediaStream& web_stream) { + DCHECK(main_thread_->BelongsToCurrentThread()); + std::string id = web_stream.Id().Utf8(); + auto it = local_stream_adapters_.find(id); + if (it == local_stream_adapters_.end()) { + it = local_stream_adapters_ + .insert(std::make_pair( + id, AdapterEntry(base::MakeUnique<WebRtcMediaStreamAdapter>( + factory_, track_adapter_map_, web_stream)))) + .first; + } + return base::WrapUnique(new AdapterRef(this, it)); +} + +size_t WebRtcMediaStreamAdapterMap::GetLocalStreamCount() const { + DCHECK(main_thread_->BelongsToCurrentThread()); + return local_stream_adapters_.size(); +} + +} // namespace content
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h b/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h new file mode 100644 index 0000000..112c314 --- /dev/null +++ b/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h
@@ -0,0 +1,109 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_MAP_H_ +#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_MAP_H_ + +#include "base/memory/ref_counted.h" +#include "base/single_thread_task_runner.h" +#include "content/common/content_export.h" +#include "content/renderer/media/webrtc/webrtc_media_stream_adapter.h" +#include "third_party/WebKit/public/platform/WebMediaStream.h" +#include "third_party/webrtc/api/mediastreaminterface.h" + +namespace content { + +// A map and owner of |WebRtcMediaStreamAdapter|s. Adapters are the glue between +// blink and webrtc layer versions of streams. As long as a stream is in use by +// a peer connection there has to exist an adapter for it. The map takes care of +// creating and disposing stream adapters. Adapters are accessed via +// |AdapterRef|s, when all references to an adapter are destroyed it is +// destroyed and removed from the map. +class CONTENT_EXPORT WebRtcMediaStreamAdapterMap + : public base::RefCountedThreadSafe<WebRtcMediaStreamAdapterMap> { + private: + // The map's entries are reference counted in order to remove the adapter when + // all |AdapterRef|s referencing an entry are destroyed. + // Private section needed here due to |AdapterRef|'s usage of |AdapterEntry|. + struct AdapterEntry { + AdapterEntry(std::unique_ptr<WebRtcMediaStreamAdapter> adapter); + AdapterEntry(AdapterEntry&& other); + ~AdapterEntry(); + + AdapterEntry(const AdapterEntry&) = delete; + AdapterEntry& operator=(const AdapterEntry&) = delete; + + std::unique_ptr<WebRtcMediaStreamAdapter> adapter; + size_t ref_count; + }; + + public: + // Accessor to an adapter to take care of reference counting. When the last + // |AdapterRef| is destroyed, the corresponding adapter is destroyed and + // removed from the map. + class CONTENT_EXPORT AdapterRef { + public: + // Must be invoked on the main thread. If this was the last reference to the + // adapter it will be disposed and removed from the map. + ~AdapterRef(); + + const WebRtcMediaStreamAdapter& adapter() const { + return *it_->second.adapter; + } + + private: + friend class WebRtcMediaStreamAdapterMap; + using MapEntryIterator = std::map<std::string, AdapterEntry>::iterator; + + // Increments the |AdapterEntry::ref_count|. + AdapterRef(scoped_refptr<WebRtcMediaStreamAdapterMap> map, + const MapEntryIterator& it); + + AdapterEntry* entry() { return &it_->second; } + + scoped_refptr<WebRtcMediaStreamAdapterMap> map_; + MapEntryIterator it_; + }; + + // Must be invoked on the main thread. + WebRtcMediaStreamAdapterMap( + PeerConnectionDependencyFactory* const factory, + scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map); + + // Invoke on the main thread. Gets a new reference to the local stream adapter + // by ID, or null if no such adapter was found. When all references are + // destroyed the adapter is destroyed and removed from the map. References + // must be destroyed on the main thread. + std::unique_ptr<AdapterRef> GetLocalStreamAdapter(const std::string& id); + // Invoke on the main thread. Gets a new reference to the local stream adapter + // for the web stream. If no adapter exists for the stream one is created. + // When all references are destroyed the adapter is destroyed and removed from + // the map. References must be destroyed on the main thread. + std::unique_ptr<AdapterRef> GetOrCreateLocalStreamAdapter( + const blink::WebMediaStream& web_stream); + // Invoke on the main thread. + size_t GetLocalStreamCount() const; + + protected: + friend class base::RefCountedThreadSafe<WebRtcMediaStreamAdapterMap>; + + // Invoke on the main thread. + virtual ~WebRtcMediaStreamAdapterMap(); + + private: + // Pointer to a |PeerConnectionDependencyFactory| owned by the |RenderThread|. + // It's valid for the lifetime of |RenderThread|. + PeerConnectionDependencyFactory* const factory_; + scoped_refptr<base::SingleThreadTaskRunner> main_thread_; + // Takes care of creating and owning track adapters, used by stream adapters. + scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_; + + std::map<std::string, AdapterEntry> local_stream_adapters_; + // TODO(hbos): Take care of remote stream adapters as well. This will require + // usage of the signaling thread. crbug.com/705901 +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_MAP_H_
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc b/content/renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc new file mode 100644 index 0000000..db43fcdd --- /dev/null +++ b/content/renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc
@@ -0,0 +1,102 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h" + +#include <memory> + +#include "base/memory/ref_counted.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/strings/string_number_conversions.h" +#include "content/child/child_process.h" +#include "content/renderer/media/media_stream.h" +#include "content/renderer/media/media_stream_video_source.h" +#include "content/renderer/media/media_stream_video_track.h" +#include "content/renderer/media/mock_audio_device_factory.h" +#include "content/renderer/media/mock_media_stream_video_source.h" +#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h" +#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/platform/WebMediaStream.h" +#include "third_party/WebKit/public/platform/WebMediaStreamSource.h" +#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" +#include "third_party/WebKit/public/platform/WebString.h" +#include "third_party/WebKit/public/platform/WebVector.h" +#include "third_party/WebKit/public/web/WebHeap.h" + +using ::testing::_; + +namespace content { + +class WebRtcMediaStreamAdapterMapTest : public ::testing::Test { + public: + void SetUp() override { + dependency_factory_.reset(new MockPeerConnectionDependencyFactory()); + main_thread_ = base::ThreadTaskRunnerHandle::Get(); + map_ = new WebRtcMediaStreamAdapterMap( + dependency_factory_.get(), + new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get())); + } + + void TearDown() override { blink::WebHeap::CollectAllGarbageForTesting(); } + + blink::WebMediaStream CreateLocalStream(const std::string& id) { + blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks( + static_cast<size_t>(1)); + blink::WebMediaStreamSource video_source; + video_source.Initialize("video_source", + blink::WebMediaStreamSource::kTypeVideo, + "video_source", false /* remote */); + MediaStreamVideoSource* native_source = + new MockMediaStreamVideoSource(false); + video_source.SetExtraData(native_source); + web_video_tracks[0] = MediaStreamVideoTrack::CreateVideoTrack( + native_source, MediaStreamVideoSource::ConstraintsCallback(), true); + + blink::WebMediaStream web_stream; + web_stream.Initialize(blink::WebString::FromUTF8(id), + blink::WebVector<blink::WebMediaStreamTrack>(), + web_video_tracks); + web_stream.SetExtraData(new MediaStream()); + return web_stream; + } + + protected: + // Message loop and child processes is needed for task queues and threading to + // work, as is necessary to create tracks and adapters. + base::MessageLoop message_loop_; + ChildProcess child_process_; + + std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_; + scoped_refptr<base::SingleThreadTaskRunner> main_thread_; + scoped_refptr<WebRtcMediaStreamAdapterMap> map_; +}; + +TEST_F(WebRtcMediaStreamAdapterMapTest, AddAndRemoveLocalStreamAdapter) { + blink::WebMediaStream local_stream = CreateLocalStream("local_stream"); + std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref = + map_->GetOrCreateLocalStreamAdapter(local_stream); + EXPECT_TRUE(adapter_ref); + EXPECT_TRUE(adapter_ref->adapter().IsEqual(local_stream)); + EXPECT_EQ(1u, map_->GetLocalStreamCount()); + + std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref2 = + map_->GetLocalStreamAdapter("local_stream"); + EXPECT_TRUE(adapter_ref2); + EXPECT_EQ(&adapter_ref2->adapter(), &adapter_ref->adapter()); + EXPECT_EQ(1u, map_->GetLocalStreamCount()); + + adapter_ref.reset(); + EXPECT_EQ(1u, map_->GetLocalStreamCount()); + adapter_ref2.reset(); + EXPECT_EQ(0u, map_->GetLocalStreamCount()); +} + +TEST_F(WebRtcMediaStreamAdapterMapTest, GetLocalStreamAdapterInvalidID) { + EXPECT_FALSE(map_->GetLocalStreamAdapter("invalid")); +} + +} // namespace content
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc b/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc index 17f809f2..1d4204eb 100644 --- a/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc +++ b/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc
@@ -61,7 +61,7 @@ media::AudioParameters::kAudioCDSampleRate, media::CHANNEL_LAYOUT_STEREO, media::AudioParameters::kAudioCDSampleRate / 50), - MockConstraintFactory().CreateWebMediaConstraints(), + AudioProcessingProperties(), base::Bind(&WebRtcMediaStreamAdapterTest::OnAudioSourceStarted), dependency_factory_.get()); source->SetAllowInvalidRenderFrameIdForTesting(true);
diff --git a/content/renderer/pepper/pepper_platform_audio_input.cc b/content/renderer/pepper/pepper_platform_audio_input.cc index 80580711..b40b0e0 100644 --- a/content/renderer/pepper/pepper_platform_audio_input.cc +++ b/content/renderer/pepper/pepper_platform_audio_input.cc
@@ -79,7 +79,8 @@ base::SharedMemoryHandle handle, base::SyncSocket::Handle socket_handle, int length, - int total_segments) { + int total_segments, + bool initially_muted) { #if defined(OS_WIN) DCHECK(handle.IsValid()); DCHECK(socket_handle); @@ -95,8 +96,9 @@ // If shutdown has occurred, |client_| will be NULL and the handles will be // cleaned up on the main thread. main_task_runner_->PostTask( - FROM_HERE, base::Bind(&PepperPlatformAudioInput::OnStreamCreated, this, - handle, socket_handle, length, total_segments)); + FROM_HERE, + base::Bind(&PepperPlatformAudioInput::OnStreamCreated, this, handle, + socket_handle, length, total_segments, initially_muted)); } else { // Must dereference the client only on the main thread. Shutdown may have // occurred while the request was in-flight, so we need to NULL check.
diff --git a/content/renderer/pepper/pepper_platform_audio_input.h b/content/renderer/pepper/pepper_platform_audio_input.h index 54f21acd..9060d2f 100644 --- a/content/renderer/pepper/pepper_platform_audio_input.h +++ b/content/renderer/pepper/pepper_platform_audio_input.h
@@ -58,7 +58,8 @@ void OnStreamCreated(base::SharedMemoryHandle handle, base::SyncSocket::Handle socket_handle, int length, - int total_segments) override; + int total_segments, + bool initially_muted) override; void OnError() override; void OnMuted(bool is_muted) override; void OnIPCClosed() override;
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index 06e60c54..168c460d 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -22,6 +22,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" #include "build/build_config.h" #include "components/url_formatter/url_formatter.h" #include "content/child/blob_storage/webblobregistry_impl.h" @@ -411,7 +412,7 @@ } void RendererBlinkPlatformImpl::CacheMetadata(const blink::WebURL& url, - int64_t response_time, + base::Time response_time, const char* data, size_t size) { // Let the browser know we generated cacheable metadata for this resource. The @@ -419,13 +420,13 @@ // the processing of this resource. std::vector<char> copy(data, data + size); RenderThread::Get()->Send( - new RenderProcessHostMsg_DidGenerateCacheableMetadata( - url, base::Time::FromInternalValue(response_time), copy)); + new RenderProcessHostMsg_DidGenerateCacheableMetadata(url, response_time, + copy)); } void RendererBlinkPlatformImpl::CacheMetadataInCacheStorage( const blink::WebURL& url, - int64_t response_time, + base::Time response_time, const char* data, size_t size, const blink::WebSecurityOrigin& cacheStorageOrigin, @@ -436,8 +437,8 @@ std::vector<char> copy(data, data + size); RenderThread::Get()->Send( new RenderProcessHostMsg_DidGenerateCacheableMetadataInCacheStorage( - url, base::Time::FromInternalValue(response_time), copy, - cacheStorageOrigin, cacheStorageCacheName.Utf8())); + url, response_time, copy, cacheStorageOrigin, + cacheStorageCacheName.Utf8())); } WebString RendererBlinkPlatformImpl::DefaultLocale() {
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h index 7884354..05ff5408 100644 --- a/content/renderer/renderer_blink_platform_impl.h +++ b/content/renderer/renderer_blink_platform_impl.h
@@ -13,6 +13,7 @@ #include "base/compiler_specific.h" #include "base/id_map.h" #include "base/macros.h" +#include "base/time/time.h" #include "build/build_config.h" #include "cc/blink/web_compositor_support_impl.h" #include "content/child/blink_platform_impl.h" @@ -93,12 +94,12 @@ std::unique_ptr<blink::WebMessagePortChannel>* channel2) override; blink::WebPrescientNetworking* PrescientNetworking() override; void CacheMetadata(const blink::WebURL&, - int64_t, + base::Time, const char*, size_t) override; void CacheMetadataInCacheStorage( const blink::WebURL&, - int64_t, + base::Time, const char*, size_t, const blink::WebSecurityOrigin& cacheStorageOrigin,
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index 8dfe95e..20489a66 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -245,7 +245,7 @@ response.blob_size); } web_response->SetError(response.error); - web_response->SetResponseTime(response.response_time.ToInternalValue()); + web_response->SetResponseTime(response.response_time); if (response.is_in_cache_storage) { web_response->SetCacheStorageCacheName( blink::WebString::FromUTF8(response.cache_storage_cache_name));
diff --git a/content/renderer/service_worker/service_worker_type_util.cc b/content/renderer/service_worker/service_worker_type_util.cc index 9baae86..c6024b0 100644 --- a/content/renderer/service_worker/service_worker_type_util.cc +++ b/content/renderer/service_worker/service_worker_type_util.cc
@@ -87,7 +87,7 @@ web_response.StatusText().Utf8(), web_response.ResponseType(), GetHeaderMap(web_response), web_response.BlobUUID().Utf8(), web_response.BlobSize(), web_response.GetError(), - base::Time::FromInternalValue(web_response.ResponseTime()), + web_response.ResponseTime(), !web_response.CacheStorageCacheName().IsNull(), web_response.CacheStorageCacheName().Utf8(), GetHeaderList(web_response.CorsExposedHeaderNames()));
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 88a50c97..fe4acf6 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1671,6 +1671,7 @@ "../renderer/media/webrtc/processed_local_audio_source_unittest.cc", "../renderer/media/webrtc/rtc_stats_unittest.cc", "../renderer/media/webrtc/stun_field_trial_unittest.cc", + "../renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc", "../renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc", "../renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc", "../renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc",
diff --git a/extensions/browser/guest_view/web_view/DEPS b/extensions/browser/guest_view/web_view/DEPS new file mode 100644 index 0000000..c2974b7b --- /dev/null +++ b/extensions/browser/guest_view/web_view/DEPS
@@ -0,0 +1,5 @@ +specific_include_rules = { + ".*(test)\.(cc|h)$": [ + "+media", # Tests need to be able to tweak media devices. + ] +}
diff --git a/extensions/browser/guest_view/web_view/web_view_media_access_apitest.cc b/extensions/browser/guest_view/web_view/web_view_media_access_apitest.cc index c013665..1fab6b4 100644 --- a/extensions/browser/guest_view/web_view/web_view_media_access_apitest.cc +++ b/extensions/browser/guest_view/web_view/web_view_media_access_apitest.cc
@@ -2,12 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/command_line.h" #include "base/macros.h" #include "base/strings/stringprintf.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/test/browser_test_utils.h" #include "extensions/browser/guest_view/web_view/web_view_apitest.h" #include "extensions/test/extension_test_message_listener.h" +#include "media/base/media_switches.h" namespace { @@ -80,6 +82,14 @@ base::StringPrintf("runTest('%s');", test_name.c_str()))); ASSERT_TRUE(test_run_listener.WaitUntilSatisfied()); } + + void SetUpCommandLine(base::CommandLine* command_line) override { + // Enable fake devices to make sure there is at least one device in the + // system. Otherwise, this test would fail on machines without physical + // media devices since getUserMedia fails early in those cases. + WebViewAPITest::SetUpCommandLine(command_line); + command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream); + } }; IN_PROC_BROWSER_TEST_F(WebViewMediaAccessAPITest, TestAllow) {
diff --git a/ios/chrome/browser/content_suggestions/BUILD.gn b/ios/chrome/browser/content_suggestions/BUILD.gn index 40964dd..d4c92662 100644 --- a/ios/chrome/browser/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/content_suggestions/BUILD.gn
@@ -46,12 +46,14 @@ "//ios/chrome/browser/ui/content_suggestions/cells:cells_ui", "//ios/chrome/browser/ui/content_suggestions/identifier", "//ios/chrome/browser/ui/favicon", + "//ios/chrome/browser/ui/ntp", "//ios/chrome/browser/ui/ntp:ntp_header", "//ios/chrome/browser/ui/ntp:ntp_internal", "//ios/chrome/browser/ui/reading_list", "//ios/chrome/browser/ui/toolbar", "//ios/public/provider/chrome/browser", "//ios/public/provider/chrome/browser/images", + "//ios/public/provider/chrome/browser/voice", "//ios/web", "//ui/base", "//ui/strings",
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.h b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.h index 572e226..8d5f1d3 100644 --- a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.h +++ b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.h
@@ -6,17 +6,20 @@ #define IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_COORDINATOR_H_ #import "ios/chrome/browser/chrome_coordinator.h" +#import "ios/chrome/browser/ui/ntp/new_tab_page_panel_protocol.h" namespace ios { class ChromeBrowserState; } +@class ContentSuggestionsHeaderController; @protocol UrlLoader; class WebStateList; // Coordinator to manage the Suggestions UI via a // ContentSuggestionsViewController. -@interface ContentSuggestionsCoordinator : ChromeCoordinator +@interface ContentSuggestionsCoordinator + : ChromeCoordinator<NewTabPagePanelProtocol> // BrowserState used to create the ContentSuggestionFactory. @property(nonatomic, assign) ios::ChromeBrowserState* browserState; @@ -27,6 +30,11 @@ // Whether the Suggestions UI is displayed. If this is true, start is a no-op. @property(nonatomic, readonly) BOOL visible; +@property(nonatomic, strong, readonly) + ContentSuggestionsHeaderController* headerController; + +- (UIViewController*)viewController; + @end #endif // IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_COORDINATOR_H_
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm index 172cf0f..8d87baa4 100644 --- a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm +++ b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
@@ -29,10 +29,12 @@ #include "ios/chrome/browser/ui/commands/ios_command_ids.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h" +#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h" #import "ios/chrome/browser/ui/content_suggestions/identifier/content_suggestion_identifier.h" #import "ios/chrome/browser/ui/ntp/google_landing_mediator.h" +#import "ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h" #import "ios/chrome/browser/ui/ntp/notification_promo_whats_new.h" #import "ios/chrome/browser/ui/uikit_ui_util.h" #import "ios/chrome/browser/ui/url_loader.h" @@ -54,10 +56,15 @@ ContentSuggestionsViewController* suggestionsViewController; @property(nonatomic, strong) ContentSuggestionsMediator* contentSuggestionsMediator; -@property(nonatomic, strong) - ContentSuggestionsHeaderController* headerController; @property(nonatomic, strong) GoogleLandingMediator* googleLandingMediator; +// Redefined as readwrite. +@property(nonatomic, strong, readwrite) + ContentSuggestionsHeaderController* headerController; + +// |YES| if the fakebox header should be animated on scroll. +@property(nonatomic, assign) BOOL animateHeader; + // Opens the |URL| in a new tab |incognito| or not. - (void)openNewTabWithURL:(const GURL&)URL incognito:(BOOL)incognito; // Dismisses the |article|, removing it from the content service, and dismisses @@ -80,6 +87,8 @@ @synthesize googleLandingMediator = _googleLandingMediator; @synthesize webStateList = _webStateList; @synthesize dispatcher = _dispatcher; +@synthesize delegate = _delegate; +@synthesize animateHeader = _animateHeader; - (void)start { if (self.visible || !self.browserState) { @@ -89,6 +98,7 @@ } _visible = YES; + self.animateHeader = YES; ntp_snippets::ContentSuggestionsService* contentSuggestionsService = IOSChromeContentSuggestionsServiceFactory::GetForBrowserState( @@ -147,6 +157,10 @@ _visible = NO; } +- (UIViewController*)viewController { + return self.suggestionsViewController; +} + #pragma mark - ContentSuggestionsCommands - (void)openReadingList { @@ -360,6 +374,39 @@ NOTREACHED(); } +#pragma mark - NewTabPagePanelProtocol + +- (CGFloat)alphaForBottomShadow { + // TODO(crbug.com/700375): implement this. + return 0; +} + +- (UIView*)view { + return self.suggestionsViewController.view; +} + +- (void)reload { + // TODO(crbug.com/700375): implement this. +} + +- (void)wasShown { + // TODO(crbug.com/700375): implement this. +} + +- (void)wasHidden { + // TODO(crbug.com/700375): implement this. +} + +- (void)dismissModals { + // TODO(crbug.com/700375): implement this. +} + +- (void)dismissKeyboard { +} + +- (void)setScrollsToTop:(BOOL)enable { +} + #pragma mark - Private - (void)openNewTabWithURL:(const GURL&)URL incognito:(BOOL)incognito {
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_header_controller.h b/ios/chrome/browser/content_suggestions/content_suggestions_header_controller.h index 3d3e743a..86e4e33 100644 --- a/ios/chrome/browser/content_suggestions/content_suggestions_header_controller.h +++ b/ios/chrome/browser/content_suggestions/content_suggestions_header_controller.h
@@ -9,6 +9,8 @@ #import "ios/chrome/browser/content_suggestions/content_suggestions_header_provider.h" #import "ios/chrome/browser/ui/ntp/google_landing_consumer.h" +#import "ios/chrome/browser/ui/toolbar/toolbar_owner.h" +#import "ios/public/provider/chrome/browser/voice/logo_animation_controller.h" @protocol ContentSuggestionsHeaderControllerDelegate; @protocol ContentSuggestionsHeaderControllerCommandHandler; @@ -20,7 +22,10 @@ // the interactions between the header and the collection, and the rest of the // application. @interface ContentSuggestionsHeaderController - : NSObject<ContentSuggestionsHeaderProvider, GoogleLandingConsumer> + : NSObject<ContentSuggestionsHeaderProvider, + GoogleLandingConsumer, + ToolbarOwner, + LogoAnimationControllerOwnerOwner> @property(nonatomic, weak) id<UrlLoader, OmniboxFocuser> dispatcher; @property(nonatomic, weak) id<ContentSuggestionsHeaderControllerDelegate> @@ -29,6 +34,15 @@ commandHandler; @property(nonatomic, assign) ReadingListModel* readingListModel; +// |YES| when notifications indicate the omnibox is focused. +@property(nonatomic, assign) BOOL omniboxFocused; + +// Whether the Google logo or doodle is being shown. +@property(nonatomic, assign) BOOL logoIsShowing; + +// Update the iPhone fakebox's frame based on the current scroll view |offset|. +- (void)updateSearchFieldForOffset:(CGFloat)offset; + @end #endif // IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_HEADER_CONTROLLER_H_
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_header_controller.mm b/ios/chrome/browser/content_suggestions/content_suggestions_header_controller.mm index 34c5dcb..77f5336 100644 --- a/ios/chrome/browser/content_suggestions/content_suggestions_header_controller.mm +++ b/ios/chrome/browser/content_suggestions/content_suggestions_header_controller.mm
@@ -31,9 +31,6 @@ @interface ContentSuggestionsHeaderController () -// Whether the Google logo or doodle is being shown. -@property(nonatomic, assign) BOOL logoIsShowing; - // |YES| if this consumer is has voice search enabled. @property(nonatomic, assign) BOOL voiceSearchIsEnabled; @@ -62,9 +59,6 @@ // ignored. @property(nonatomic, assign) BOOL isShowing; -// |YES| when notifications indicate the omnibox is focused. -@property(nonatomic, assign) BOOL omniboxFocused; - // The number of tabs to show in the google landing fake toolbar. @property(nonatomic, assign) int tabCount; @@ -111,6 +105,20 @@ @synthesize logoIsShowing = _logoIsShowing; @synthesize logoFetched = _logoFetched; +#pragma mark - Public + +- (void)updateSearchFieldForOffset:(CGFloat)offset { + NSArray* constraints = + @[ self.hintLabelLeadingConstraint, self.voiceTapTrailingConstraint ]; + + [self.headerView updateSearchFieldWidth:self.fakeOmniboxWidthConstraint + height:self.fakeOmniboxHeightConstraint + topMargin:self.fakeOmniboxTopMarginConstraint + subviewConstraints:constraints + logoIsShowing:self.logoIsShowing + forOffset:offset]; +} + #pragma mark - ContentSuggestionsHeaderProvider - (UIView*)headerForWidth:(CGFloat)width { @@ -258,6 +266,22 @@ ]]; } +#pragma mark - ToolbarOwner + +- (ToolbarController*)relinquishedToolbarController { + return [self.headerView relinquishedToolbarController]; +} + +- (void)reparentToolbarController { + [self.headerView reparentToolbarController]; +} + +#pragma mark - LogoAnimationControllerOwnerOwner + +- (id<LogoAnimationControllerOwner>)logoAnimationControllerOwner { + return [self.logoVendor logoAnimationControllerOwner]; +} + #pragma mark - GoogleLandingConsumer - (void)setLogoIsShowing:(BOOL)logoIsShowing {
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm index 9adf2d5..c89d739 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm
@@ -364,7 +364,7 @@ NSInteger orderedSectionIdentifier = SectionIdentifierForInfo(orderedSectionInfo); if (orderedSectionIdentifier == sectionIdentifier) { - continue; + break; } if ([model hasSectionForSectionIdentifier:orderedSectionIdentifier]) { sectionIndex++;
diff --git a/ios/chrome/browser/ui/ntp/BUILD.gn b/ios/chrome/browser/ui/ntp/BUILD.gn index f045030..6629b0b 100644 --- a/ios/chrome/browser/ui/ntp/BUILD.gn +++ b/ios/chrome/browser/ui/ntp/BUILD.gn
@@ -154,6 +154,7 @@ "//ios/chrome/app/strings", "//ios/chrome/browser", "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/content_suggestions", "//ios/chrome/browser/search_engines", "//ios/chrome/browser/sync", "//ios/chrome/browser/tabs",
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_controller.mm index a84eeed..09804fa 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_controller.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_controller.mm
@@ -15,6 +15,9 @@ #include "components/strings/grit/components_strings.h" #include "components/sync_sessions/synced_session.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#import "ios/chrome/browser/content_suggestions/content_suggestions_coordinator.h" +#import "ios/chrome/browser/content_suggestions/content_suggestions_header_controller.h" +#include "ios/chrome/browser/experimental_flags.h" #include "ios/chrome/browser/pref_names.h" #include "ios/chrome/browser/search_engines/template_url_service_factory.h" #include "ios/chrome/browser/sync/sync_setup_service.h" @@ -111,31 +114,31 @@ } // anonymous namespace @interface NewTabPageController () { - ios::ChromeBrowserState* browserState_; // weak. - __weak id<UrlLoader> loader_; - __weak id<NewTabPageControllerObserver> newTabPageObserver_; - BookmarkHomeTabletNTPController* bookmarkController_; - GoogleLandingViewController* googleLandingController_; - id<NewTabPagePanelProtocol> incognitoController_; + ios::ChromeBrowserState* _browserState; // weak. + __weak id<UrlLoader> _loader; + __weak id<NewTabPageControllerObserver> _newTabPageObserver; + BookmarkHomeTabletNTPController* _bookmarkController; + GoogleLandingViewController* _googleLandingController; + id<NewTabPagePanelProtocol> _incognitoController; // The currently visible controller, one of the above. - __weak id<NewTabPagePanelProtocol> currentController_; + __weak id<NewTabPagePanelProtocol> _currentController; - GoogleLandingMediator* googleLandingMediator_; + GoogleLandingMediator* _googleLandingMediator; - RecentTabsPanelController* openTabsController_; + RecentTabsPanelController* _openTabsController; // Has the scrollView been initialized. - BOOL scrollInitialized_; + BOOL _scrollInitialized; // Dominant color cache. Key: (NSString*)url, val: (UIColor*)dominantColor. - __weak NSMutableDictionary* dominantColorCache_; // Owned by bvc. + __weak NSMutableDictionary* _dominantColorCache; // Owned by bvc. // Delegate to focus and blur the omnibox. - __weak id<OmniboxFocuser> focuser_; + __weak id<OmniboxFocuser> _focuser; // Delegate to fetch the ToolbarModel and current web state from. - __weak id<WebToolbarDelegate> webToolbarDelegate_; + __weak id<WebToolbarDelegate> _webToolbarDelegate; - TabModel* tabModel_; + TabModel* _tabModel; } // Load and bring panel into view. @@ -179,14 +182,28 @@ // to be used by the reuabled NTP panels. @property(nonatomic, weak) id dispatcher; +// Panel displaying the "Home" view, with the logo and the fake omnibox. +@property(nonatomic, strong) id<NewTabPagePanelProtocol> homePanel; + +// Coordinator for the ContentSuggestions. +@property(nonatomic, strong) + ContentSuggestionsCoordinator* contentSuggestionsCoordinator; + +// Controller for the header of the Home panel. +@property(nonatomic, strong) id<LogoAnimationControllerOwnerOwner, ToolbarOwner> + headerController; + @end @implementation NewTabPageController -@synthesize ntpView = ntpView_; -@synthesize swipeRecognizerProvider = swipeRecognizerProvider_; -@synthesize parentViewController = parentViewController_; -@synthesize dispatcher = dispatcher_; +@synthesize ntpView = _ntpView; +@synthesize swipeRecognizerProvider = _swipeRecognizerProvider; +@synthesize parentViewController = _parentViewController; +@synthesize dispatcher = _dispatcher; +@synthesize homePanel = _homePanel; +@synthesize contentSuggestionsCoordinator = _contentSuggestionsCoordinator; +@synthesize headerController = _headerController; - (id)initWithUrl:(const GURL&)url loader:(id<UrlLoader>)loader @@ -201,17 +218,17 @@ self = [super initWithNibName:nil url:url]; if (self) { DCHECK(browserState); - browserState_ = browserState; - loader_ = loader; - newTabPageObserver_ = ntpObserver; - parentViewController_ = parentViewController; - dispatcher_ = dispatcher; - focuser_ = focuser; - webToolbarDelegate_ = webToolbarDelegate; - tabModel_ = tabModel; - dominantColorCache_ = colorCache; + _browserState = browserState; + _loader = loader; + _newTabPageObserver = ntpObserver; + _parentViewController = parentViewController; + _dispatcher = dispatcher; + _focuser = focuser; + _webToolbarDelegate = webToolbarDelegate; + _tabModel = tabModel; + _dominantColorCache = colorCache; self.title = l10n_util::GetNSString(IDS_NEW_TAB_TITLE); - scrollInitialized_ = NO; + _scrollInitialized = NO; UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 412)]; @@ -219,14 +236,14 @@ UIViewAutoresizingFlexibleHeight)]; NewTabPageBar* tabBar = [[NewTabPageBar alloc] initWithFrame:CGRectMake(0, 412, 320, 48)]; - ntpView_ = [[NewTabPageView alloc] initWithFrame:CGRectMake(0, 0, 320, 460) + _ntpView = [[NewTabPageView alloc] initWithFrame:CGRectMake(0, 0, 320, 460) andScrollView:scrollView andTabBar:tabBar]; // TODO(crbug.com/607113): Merge view and ntpView. - self.view = ntpView_; + self.view = _ntpView; [tabBar setDelegate:self]; - bool isIncognito = browserState_->IsOffTheRecord(); + bool isIncognito = _browserState->IsOffTheRecord(); NSString* incognito = l10n_util::GetNSString(IDS_IOS_NEW_TAB_INCOGNITO); NSString* mostVisited = @@ -277,7 +294,7 @@ if (!IsIPadIdiom()) { itemToDisplay = mostVisitedItem; } else { - PrefService* prefs = browserState_->GetPrefs(); + PrefService* prefs = _browserState->GetPrefs(); int shownPage = prefs->GetInteger(prefs::kNtpShownPage); shownPage = shownPage & ~INDEX_MASK; @@ -303,19 +320,23 @@ // delegate. self.ntpView.scrollView.delegate = nil; - [googleLandingMediator_ shutdown]; + [_googleLandingMediator shutdown]; // This is not an ideal place to put view controller contaimnent, rather a // //web -wasDismissed method on CRWNativeContent would be more accurate. If // CRWNativeContent leaks, this will not be called. // TODO(crbug.com/708319): Also call -removeFromParentViewController for // open tabs and incognito here. - [googleLandingController_ removeFromParentViewController]; - [bookmarkController_ removeFromParentViewController]; + [_googleLandingController removeFromParentViewController]; + [_bookmarkController removeFromParentViewController]; + [[self.contentSuggestionsCoordinator viewController] + removeFromParentViewController]; - [googleLandingController_ setDelegate:nil]; - [bookmarkController_ setDelegate:nil]; - [openTabsController_ setDelegate:nil]; + [self.contentSuggestionsCoordinator stop]; + + [self.homePanel setDelegate:nil]; + [_bookmarkController setDelegate:nil]; + [_openTabsController setDelegate:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self]; } @@ -327,26 +348,28 @@ // containment methods. // TODO(crbug.com/708319): Also call -willMoveToParentViewController:nil for // open tabs and incognito here. - [googleLandingController_ willMoveToParentViewController:nil]; - [bookmarkController_ willMoveToParentViewController:nil]; + [_googleLandingController willMoveToParentViewController:nil]; + [_bookmarkController willMoveToParentViewController:nil]; + [[self.contentSuggestionsCoordinator viewController] + willMoveToParentViewController:nil]; } - (void)reload { - [currentController_ reload]; + [_currentController reload]; [super reload]; } - (void)wasShown { - [currentController_ wasShown]; + [_currentController wasShown]; // Ensure that the NTP has the latest data when it is shown. [self reload]; [self.ntpView.tabBar updateColorsForScrollView:self.ntpView.scrollView]; [self.ntpView.tabBar - setShadowAlpha:[currentController_ alphaForBottomShadow]]; + setShadowAlpha:[_currentController alphaForBottomShadow]]; } - (void)wasHidden { - [currentController_ wasHidden]; + [_currentController wasHidden]; } - (BOOL)wantsKeyboardShield { @@ -359,7 +382,7 @@ return YES; // Always show the location bar hint text if the search engine is not Google. TemplateURLService* service = - ios::TemplateURLServiceFactory::GetForBrowserState(browserState_); + ios::TemplateURLServiceFactory::GetForBrowserState(_browserState); if (service) { const TemplateURL* defaultURL = service->GetDefaultSearchProvider(); if (defaultURL && @@ -370,31 +393,31 @@ } // Always return true when incognito. - if (browserState_->IsOffTheRecord()) + if (_browserState->IsOffTheRecord()) return YES; return [self selectedPanelID] != NewTabPage::kMostVisitedPanel; } - (void)dismissKeyboard { - [currentController_ dismissKeyboard]; + [_currentController dismissKeyboard]; } - (void)dismissModals { - [currentController_ dismissModals]; + [_currentController dismissModals]; } - (void)willUpdateSnapshot { - if ([currentController_ respondsToSelector:@selector(willUpdateSnapshot)]) { - [currentController_ willUpdateSnapshot]; + if ([_currentController respondsToSelector:@selector(willUpdateSnapshot)]) { + [_currentController willUpdateSnapshot]; } } #pragma mark - - (void)setSwipeRecognizerProvider:(id<CRWSwipeRecognizerProvider>)provider { - swipeRecognizerProvider_ = provider; - NSSet* recognizers = [swipeRecognizerProvider_ swipeRecognizers]; + _swipeRecognizerProvider = provider; + NSSet* recognizers = [_swipeRecognizerProvider swipeRecognizers]; for (UISwipeGestureRecognizer* swipeRecognizer in recognizers) { [self.ntpView.scrollView.panGestureRecognizer requireGestureRecognizerToFail:swipeRecognizer]; @@ -424,7 +447,7 @@ [self.ntpView updateScrollViewContentSize]; [self.ntpView.tabBar updateColorsForScrollView:scrollView]; - scrollInitialized_ = YES; + _scrollInitialized = YES; } - (void)disableScroll { @@ -437,7 +460,7 @@ // Update selectedIndex and scroll position as the scroll view moves. - (void)scrollViewDidScroll:(UIScrollView*)scrollView { - if (!scrollInitialized_) + if (!_scrollInitialized) return; // Position is used to track the exact X position of the scroll view, whereas @@ -491,7 +514,7 @@ [self scrollToPanel:selectedItem animate:YES]; } - [newTabPageObserver_ selectedPanelDidChange]; + [_newTabPageObserver selectedPanelDidChange]; } - (void)selectPanel:(NewTabPage::PanelIdentifier)panelType { @@ -531,47 +554,67 @@ BOOL created = NO; // Only load the controllers once. if (item.identifier == NewTabPage::kBookmarksPanel) { - if (!bookmarkController_) { + if (!_bookmarkController) { BookmarkControllerFactory* factory = [[BookmarkControllerFactory alloc] init]; - bookmarkController_ = - [factory bookmarkPanelControllerForBrowserState:browserState_ - loader:loader_ - colorCache:dominantColorCache_]; + _bookmarkController = + [factory bookmarkPanelControllerForBrowserState:_browserState + loader:_loader + colorCache:_dominantColorCache]; } - panelController = bookmarkController_; - view = [bookmarkController_ view]; - [bookmarkController_ setDelegate:self]; + panelController = _bookmarkController; + view = [_bookmarkController view]; + [_bookmarkController setDelegate:self]; } else if (item.identifier == NewTabPage::kMostVisitedPanel) { - if (!googleLandingController_) { - googleLandingController_ = [[GoogleLandingViewController alloc] init]; - [googleLandingController_ setDispatcher:self.dispatcher]; - googleLandingMediator_ = [[GoogleLandingMediator alloc] - initWithConsumer:googleLandingController_ - browserState:browserState_ - dispatcher:self.dispatcher - webStateList:[tabModel_ webStateList]]; - [googleLandingController_ setDataSource:googleLandingMediator_]; + if (experimental_flags::IsSuggestionsUIEnabled()) { + if (!self.contentSuggestionsCoordinator) { + self.contentSuggestionsCoordinator = + [[ContentSuggestionsCoordinator alloc] + initWithBaseViewController:nil]; + self.contentSuggestionsCoordinator.URLLoader = _loader; + self.contentSuggestionsCoordinator.browserState = _browserState; + self.contentSuggestionsCoordinator.dispatcher = self.dispatcher; + self.contentSuggestionsCoordinator.webStateList = + [_tabModel webStateList]; + [self.contentSuggestionsCoordinator start]; + self.headerController = + self.contentSuggestionsCoordinator.headerController; + } + panelController = [self.contentSuggestionsCoordinator viewController]; + self.homePanel = self.contentSuggestionsCoordinator; + } else { + if (!_googleLandingController) { + _googleLandingController = [[GoogleLandingViewController alloc] init]; + [_googleLandingController setDispatcher:self.dispatcher]; + _googleLandingMediator = [[GoogleLandingMediator alloc] + initWithConsumer:_googleLandingController + browserState:_browserState + dispatcher:self.dispatcher + webStateList:[_tabModel webStateList]]; + [_googleLandingController setDataSource:_googleLandingMediator]; + self.headerController = _googleLandingController; + } + panelController = _googleLandingController; + self.homePanel = _googleLandingController; } - panelController = googleLandingController_; - view = [googleLandingController_ view]; - [googleLandingController_ setDelegate:self]; + view = panelController.view; + [self.homePanel setDelegate:self]; } else if (item.identifier == NewTabPage::kOpenTabsPanel) { - if (!openTabsController_) - openTabsController_ = - [[RecentTabsPanelController alloc] initWithLoader:loader_ - browserState:browserState_]; + if (!_openTabsController) + _openTabsController = + [[RecentTabsPanelController alloc] initWithLoader:_loader + browserState:_browserState]; // TODO(crbug.com/708319): Also set panelController for opentabs here. - view = [openTabsController_ view]; - [openTabsController_ setDelegate:self]; + view = [_openTabsController view]; + [_openTabsController setDelegate:self]; } else if (item.identifier == NewTabPage::kIncognitoPanel) { - if (!incognitoController_) - incognitoController_ = - [[IncognitoPanelController alloc] initWithLoader:loader_ - browserState:browserState_ - webToolbarDelegate:webToolbarDelegate_]; + if (!_incognitoController) + _incognitoController = + [[IncognitoPanelController alloc] initWithLoader:_loader + browserState:_browserState + webToolbarDelegate:_webToolbarDelegate]; // TODO(crbug.com/708319): Also set panelController for incognito here. - view = [incognitoController_ view]; + view = [_incognitoController view]; } else { NOTREACHED(); return NO; @@ -620,7 +663,7 @@ } } - if (currentController_ == nil) { + if (_currentController == nil) { [self updateCurrentController:item index:index]; } } @@ -652,44 +695,43 @@ index:(NSUInteger)index { if (!IsIPadIdiom() && (item.identifier == NewTabPage::kBookmarksPanel || item.identifier == NewTabPage::kOpenTabsPanel)) { - // Don't update |currentController_| for iPhone since Bookmarks and Recent + // Don't update |_currentController| for iPhone since Bookmarks and Recent // Tabs are presented in a modal view controller. return; } - id<NewTabPagePanelProtocol> oldController = currentController_; + id<NewTabPagePanelProtocol> oldController = _currentController; self.ntpView.tabBar.selectedIndex = index; if (item.identifier == NewTabPage::kBookmarksPanel) - currentController_ = bookmarkController_; + _currentController = _bookmarkController; else if (item.identifier == NewTabPage::kMostVisitedPanel) - currentController_ = googleLandingController_; + _currentController = self.homePanel; else if (item.identifier == NewTabPage::kOpenTabsPanel) - currentController_ = openTabsController_; + _currentController = _openTabsController; else if (item.identifier == NewTabPage::kIncognitoPanel) - currentController_ = incognitoController_; + _currentController = _incognitoController; - [bookmarkController_ - setScrollsToTop:(currentController_ == bookmarkController_)]; - [googleLandingController_ - setScrollsToTop:(currentController_ == googleLandingController_)]; - [openTabsController_ - setScrollsToTop:(currentController_ == openTabsController_)]; + [_bookmarkController + setScrollsToTop:(_currentController == _bookmarkController)]; + [self.homePanel setScrollsToTop:(_currentController == self.homePanel)]; + [_openTabsController + setScrollsToTop:(_currentController == _openTabsController)]; [self.ntpView.tabBar - setShadowAlpha:[currentController_ alphaForBottomShadow]]; + setShadowAlpha:[_currentController alphaForBottomShadow]]; - if (oldController != currentController_) { - [currentController_ wasShown]; + if (oldController != _currentController) { + [_currentController wasShown]; [oldController wasHidden]; } } - (void)panelChanged:(NewTabPageBarItem*)item { - if (browserState_->IsOffTheRecord()) + if (_browserState->IsOffTheRecord()) return; // Save state and update metrics. Intentionally omitting a metric for the // Incognito panel. - PrefService* prefs = browserState_->GetPrefs(); + PrefService* prefs = _browserState->GetPrefs(); if (item.identifier == NewTabPage::kBookmarksPanel) { base::RecordAction(UserMetricsAction("MobileNTPSwitchToBookmarks")); prefs->SetInteger(prefs::kNtpShownPage, BOOKMARKS_PAGE_ID); @@ -714,31 +756,31 @@ #pragma mark - LogoAnimationControllerOwnerOwner - (id<LogoAnimationControllerOwner>)logoAnimationControllerOwner { - return [googleLandingController_ logoAnimationControllerOwner]; + return [self.headerController logoAnimationControllerOwner]; } #pragma mark - #pragma mark ToolbarOwner - (ToolbarController*)relinquishedToolbarController { - return [googleLandingController_ relinquishedToolbarController]; + return [self.headerController relinquishedToolbarController]; } - (void)reparentToolbarController { - [googleLandingController_ reparentToolbarController]; + [self.headerController reparentToolbarController]; } - (CGFloat)toolbarHeight { // If the google landing controller is nil, there is no toolbar visible in the // native content view, finally there is no toolbar on iPad. - return googleLandingController_ && !IsIPadIdiom() ? kToolbarHeight : 0.0; + return self.headerController && !IsIPadIdiom() ? kToolbarHeight : 0.0; } #pragma mark - NewTabPagePanelControllerDelegate - (void)updateNtpBarShadowForPanelController: (id<NewTabPagePanelProtocol>)ntpPanelController { - if (currentController_ != ntpPanelController) + if (_currentController != ntpPanelController) return; [self.ntpView.tabBar setShadowAlpha:[ntpPanelController alphaForBottomShadow]]; @@ -749,19 +791,19 @@ @implementation NewTabPageController (TestSupport) - (id<NewTabPagePanelProtocol>)currentController { - return currentController_; + return _currentController; } - (BookmarkHomeTabletNTPController*)bookmarkController { - return bookmarkController_; + return _bookmarkController; } - (GoogleLandingViewController*)googleLandingController { - return googleLandingController_; + return _googleLandingController; } - (id<NewTabPagePanelProtocol>)incognitoController { - return incognitoController_; + return _incognitoController; } @end
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn index 7635b63..8381db4 100644 --- a/ios/chrome/browser/ui/settings/BUILD.gn +++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -179,6 +179,7 @@ "//ios/public/provider/chrome/browser/signin", "//ios/public/provider/chrome/browser/user_feedback", "//ios/public/provider/chrome/browser/voice", + "//ios/shared/chrome/browser/ui/settings", "//ios/third_party/material_components_ios", "//ios/third_party/material_roboto_font_loader_ios", "//ios/web",
diff --git a/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm b/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm index ecfbcfb..4eeab2b8 100644 --- a/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm
@@ -155,21 +155,21 @@ toSectionWithIdentifier:SectionIdentifierFields]; // Card number (PAN). - AutofillEditItem* cardNumberitem = + AutofillEditItem* cardNumberItem = [[AutofillEditItem alloc] initWithType:ItemTypeCardNumber]; - cardNumberitem.textFieldName = + cardNumberItem.textFieldName = l10n_util::GetNSString(IDS_IOS_AUTOFILL_CARD_NUMBER); // Never show full card number for Wallet cards, even if copied locally. - cardNumberitem.textFieldValue = + cardNumberItem.textFieldValue = autofill::IsCreditCardLocal(_creditCard) ? base::SysUTF16ToNSString(_creditCard.number()) - : base::SysUTF16ToNSString(_creditCard.LastFourDigits()); - cardNumberitem.textFieldEnabled = isEditing; - cardNumberitem.autofillUIType = AutofillUITypeCreditCardNumber; - cardNumberitem.keyboardType = UIKeyboardTypeNumberPad; - cardNumberitem.identifyingIcon = - [self cardTypeIconFromCardNumber:cardNumberitem.textFieldValue]; - [model addItem:cardNumberitem + : base::SysUTF16ToNSString(_creditCard.NetworkAndLastFourDigits()); + cardNumberItem.textFieldEnabled = isEditing; + cardNumberItem.autofillUIType = AutofillUITypeCreditCardNumber; + cardNumberItem.keyboardType = UIKeyboardTypeNumberPad; + cardNumberItem.identifyingIcon = + [self cardTypeIconFromNetwork:_creditCard.network().c_str()]; + [model addItem:cardNumberItem toSectionWithIdentifier:SectionIdentifierFields]; // Expiration month. @@ -232,7 +232,9 @@ NSString* updatedText = [textField.text stringByReplacingCharactersInRange:range withString:newText]; - item.identifyingIcon = [self cardTypeIconFromCardNumber:updatedText]; + const char* network = autofill::CreditCard::GetCardNetwork( + base::SysNSStringToUTF16(updatedText)); + item.identifyingIcon = [self cardTypeIconFromNetwork:network]; // Update the cell. [self reconfigureCellsForItems:@[ item ]]; } @@ -300,9 +302,7 @@ #pragma mark - Helper Methods -- (UIImage*)cardTypeIconFromCardNumber:(NSString*)cardNumber { - const char* network = autofill::CreditCard::GetCardNetwork( - base::SysNSStringToUTF16(cardNumber)); +- (UIImage*)cardTypeIconFromNetwork:(const char*)network { if (network != autofill::kGenericCard) { int resourceID = autofill::data_util::GetPaymentRequestData(network).icon_resource_id;
diff --git a/ios/chrome/browser/ui/settings/settings_collection_view_controller.h b/ios/chrome/browser/ui/settings/settings_collection_view_controller.h index 0088828..1b43cab 100644 --- a/ios/chrome/browser/ui/settings/settings_collection_view_controller.h +++ b/ios/chrome/browser/ui/settings/settings_collection_view_controller.h
@@ -8,6 +8,7 @@ #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/chrome/browser/ui/settings/settings_root_collection_view_controller.h" +@protocol SettingsMainPageCommands; @class SigninInteractionController; namespace ios { class ChromeBrowserState; @@ -37,6 +38,9 @@ @property(weak, nonatomic, readonly) SigninInteractionController* signinInteractionController; +// This controller's dispatcher. By default it is the controller itself. +@property(weak, nonatomic) id<SettingsMainPageCommands> dispatcher; + // Initializes a new SettingsCollectionViewController. |browserState| must not // be nil and must not be an off-the-record browser state. - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState
diff --git a/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm b/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm index a6988c9..1d248518 100644 --- a/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm
@@ -73,6 +73,7 @@ #import "ios/public/provider/chrome/browser/signin/chrome_identity.h" #import "ios/public/provider/chrome/browser/signin/signin_resources_provider.h" #include "ios/public/provider/chrome/browser/voice/voice_search_prefs.h" +#import "ios/shared/chrome/browser/ui/settings/settings_main_page_commands.h" #import "ios/third_party/material_components_ios/src/components/Buttons/src/MaterialButtons.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -176,13 +177,14 @@ #pragma mark - SettingsCollectionViewController -@interface SettingsCollectionViewController ()<SettingsControllerProtocol, - SyncObserverModelBridge, +@interface SettingsCollectionViewController ()<BooleanObserver, ChromeIdentityServiceObserver, - BooleanObserver, PrefObserverDelegate, + SettingsControllerProtocol, + SettingsMainPageCommands, SigninPromoViewConsumer, - SigninPromoViewDelegate> { + SigninPromoViewDelegate, + SyncObserverModelBridge> { // The current browser state that hold the settings. Never off the record. ios::ChromeBrowserState* _browserState; // weak @@ -231,6 +233,7 @@ @end @implementation SettingsCollectionViewController +@synthesize dispatcher = _dispatcher; #pragma mark Initialization @@ -275,6 +278,8 @@ _prefObserverBridge->ObserveChangesForPreference( autofill::prefs::kAutofillEnabled, &_prefChangeRegistrar); + _dispatcher = self; + [self loadModel]; } return self; @@ -761,7 +766,7 @@ // and only the switch is tappable. break; case ItemTypeCellCatalog: - controller = [[MaterialCellCatalogViewController alloc] init]; + [self.dispatcher showMaterialCellCatalog]; break; default: break; @@ -982,6 +987,14 @@ [self reloadData]; } +#pragma mark Material Cell Catalog + +- (void)showMaterialCellCatalog { + [self.navigationController + pushViewController:[[MaterialCellCatalogViewController alloc] init] + animated:YES]; +} + #pragma mark NotificationBridgeDelegate - (void)onSignInStateChanged {
diff --git a/ios/chrome/browser/ui/settings/settings_navigation_controller.h b/ios/chrome/browser/ui/settings/settings_navigation_controller.h index de84b6b..c7c99cf 100644 --- a/ios/chrome/browser/ui/settings/settings_navigation_controller.h +++ b/ios/chrome/browser/ui/settings/settings_navigation_controller.h
@@ -124,6 +124,16 @@ newAutofillController:(ios::ChromeBrowserState*)browserState delegate:(id<SettingsNavigationControllerDelegate>)delegate; +// Initializes the UINavigationController with |rootViewController|. +- (instancetype) +initWithRootViewController:(UIViewController*)rootViewController + browserState:(ios::ChromeBrowserState*)browserState + delegate:(id<SettingsNavigationControllerDelegate>)delegate + NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithRootViewController:(UIViewController*)rootViewController + NS_UNAVAILABLE; + // Returns a new Done button for a UINavigationItem which will call // closeSettings when it is pressed. Should only be called by view controllers // owned by SettingsNavigationController. @@ -146,15 +156,4 @@ @end -@interface SettingsNavigationController (ExposedForTesting) - -// Initializes the UINavigationController with |rootViewController|. -// User of this class should not call the normal |initWithRootViewController|. -- (instancetype) -initWithRootViewController:(UIViewController*)rootViewController - browserState:(ios::ChromeBrowserState*)browserState - delegate:(id<SettingsNavigationControllerDelegate>)delegate; - -@end - #endif // IOS_CHROME_BROWSER_UI_SETTINGS_SETTINGS_NAVIGATION_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm index 797b617..8eb7c10 100644 --- a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
@@ -288,7 +288,9 @@ delegate:(id<SettingsNavigationControllerDelegate>)delegate { DCHECK(browserState); DCHECK(!browserState->IsOffTheRecord()); - self = [super initWithRootViewController:rootViewController]; + self = rootViewController + ? [super initWithRootViewController:rootViewController] + : [super init]; if (self) { mainBrowserState_ = browserState; delegate_ = delegate;
diff --git a/ios/clean/README.md b/ios/clean/README.md index 80dffe1c..8c41156 100644 --- a/ios/clean/README.md +++ b/ios/clean/README.md
@@ -1,6 +1,214 @@ -# Application Steps +# iOS Chrome Architecture ------ -**The files in this directory are only used in the new architecture for iOS -Chrome** ------ +`/ios/clean/` houses a revised and updated architecture for iOS Chrome's UI. iOS +is in the process of migrating into this new architecture. During this process, +code in `/ios/clean` should not depend on code in `ios/chrome/browser/ui`, or +vice-versa; instead code that is shared between the two will be moved into +`ios/shared`. + +This document is a general overview of the fundamental concepts of the new +architecture. More specific documentation is located alongside the +implementations. + +[TOC] + +## Goals and core principles. + +The goals of the new architecture, briefly, are to: + +* Allow for radical user interface experimentation and changes. +* Make development and maintenance of features easier. +* Cut the Gordian knots of the existing architecture, removing the need for + [unmaintainable monster classes](/ios/chrome/browser/ui/BrowserViewController.mm) + that accrete functionality. +* Keep up with the evolution if iOS by providing a structure in which the + affordances provided by Cocoa Touch can be used without radical changes. + +In order to meet these goals, the new architecture is designed according to +these three core principles: + +* **Strong Decoupling.** Components of the browser, especially UI components, + should not depend on other components explicitly. Where components interact, + they should do so through protocols or other abstractions that prevent + tight coupling. +* **Strong Encapsulation.** A complement to decoupling is encapsulation. + Components of the browser should expose little specifics about their + implementation or state. Public APIs should be as small as possible. + Architectural commonalities (for example, the use of a common superclass for + coordinators) will mean that the essential interfaces for complex components + can be both small and common across many implementations. Overall the + combination of decoupling and encapsulation means that components of + Chrome can be rearranged or removed without impacting the rest of the + application. +* **Separation of layers.** Objects should operate at a specific layer, and + their interactions with objects in other layers should be well-defined. We + distinguish model, coordinator, and UI layers. + +## Structure. + +### View controllers. + +Since this is an iOS application, view controllers remain a fundamental building +block of the user interface. However, the scope of a view controller’s +responsibilities are strongly constrained. View controllers are responsible for +the display and user interactions of a specific piece of user interface. They +may contain, or be contained in, other view controllers in order to compose the +complete UI that a user interacts with. + +For example, when viewing a web page in a Chrome tab, the web page contents, the +toolbar above the page, and the location bar in the toolbar are each separate +view controllers, and a fourth view controller is responsible for composing them +together. View controllers do not directly interact with each other or with any +model-layer services. + +### Coordinators. + +Since view controllers are heavily encapsulated, another object is responsible +for creating them and connecting them to other objects. This object is a +coordinator, and in this architecture all coordinators are subclasses of +[BrowserCoordinator](/ios/shared/chrome/browser/ui/coordinators/). Coordinators +exist in a hierarchy, roughly parallel to the view controller hierarchy; each +coordinator can have multiple child coordinators, and there is a single root +coordinator that is created when the application launches. + +The primary role of coordinators is to create and configure their view +controller, connect it to a mediator and/or a dispatcher (see below), and to +handle the creation and lifecycle of any child view controllers. Coordinators +shouldn’t directly interact with model-layer services, and should contain +little if any “business logic”. + +### Mediators. + +Mediators encapsulate the interactions between the model layer and the user +interface. They are created by coordinators and are handed connections to any +model-layer services they need, as well as to a “consumer” which they will +push user interface configuration and updates into. + +The consumer is typically a view controller, and there is a consumer protocol +defined as part of the UI layer that the view controller adopts for this +purpose. A view controller that integrates UI updates from multiple model +services may be consuming from multiple mediators and may thus implement +multiple consumer protocols. + +Mediators can be either Objective-C or C++ objects, and there isn't a universal +superclass for them. + +### Service Objects. + +Coordinators are created with access to a number of “service objects” that they +may connect to mediators and view controllers. By default a coordinator passes +pointers to all of these objects into their children. + +The inventory of service objects includes: + +* **[WebStateList:](/ios/chrome/browser/web_state_list/)** An observable, + mutable, ordered collection of [WebState](/ios/public/web_state/)s. A WebState + is the model-layer representation of a browser tab. + +* **BrowserState:** The [ChromeBrowserState](/ios/chrome/browser/chrome_browser/state/) + object as used in the old architecture. + +* **[Dispatcher:](/ios/shared/chrome/browser/ui/commands/)** A decoupled + interface over which application-level method calls may be made; see below. + +* **[Broadcaster:](/ios/shared/chrome/browser/ui/broadcaster)** A decoupled + interface over which some properties of the user interface may be observed. + +Some of these service objects are contained inside a [Browser](/ios/shared/chrome/browser/ui/browser_list) +object, which represents a collection of user tabs, equivalent to a window on +desktop platforms. + +The Dispatcher merits special discussion. The role of the dispatcher is to +opaquely route Objective-C method calls. The dispatcher can register objects to +handle specific method calls, or an entire protocol. These protocols are +conventionally called [‘commands’](/ios/clean/chrome/browser/ui/commands/). + +Coordinators typically register themselves or the mediators they own to handle +commands related to the area of their responsibility. The dispatcher is handed +into the view controller that a coordinator creates in the guise of a generic +Objective-C object that conforms to the command protocols that the view +controller needs. This allows the view controller to call methods on objects +that its coordinator doesn’t directly know about. + +## Strictures. + +Within this basic structure, and given the overall principles of decoupling, +encapsulation, and separation of layers, there are a number of restrictions that +all of these classes of objects should adhere to. + +### View Controllers + +* Cannot directly create or interact with any other specific classes of view + controllers. View controllers that contain other view controllers should have + public properties or methods for these embedded view controllers to be + provided; internally they are limited to adding, removing, positioning, and + resizing any such view controllers. + +* Cannot depend on any model-layer objects or types. + +* Should only operate on the main thread. + +* Should not be their own transitioning delegates; an object from the + coordinator layer (usually the coordinator) should handle that. + +* Should handle action methods for their own UI, or, if appropriate, have the + command-handling object they are given (a pointer to the dispatcher) be the + target for control actions. + +* Should only take input from other parts of the application by having them + pushed over the consumer interface (or interfaces). + +* Should only send messages to the rest of the application directly via the + dispatcher. + +### The UI layer + +View controllers, the consumer protocols they adopt, and associated classes and +assets constitute the “UI layer” of the application, and it is a separate source +set in the gn configurations. The UI layer should have no dependencies on +coordinators, mediators, or model objects. + +### Coordinators + +* Should only pass a minimal set of service objects into mediators or other + objects that require them. Rather than passing a `Browser` or `BrowserState`, + they should pass specific services or sub-objects. Rather than passing the + Dispatcher, they should cast it into an `i`d object that conforms to the + protocol(s) the object requires. + +* Should only handle command method whose execution is mostly a matter of + creating, starting, or stopping other coordinators. Interactions with + model-layer objects should be handled by mediators. Coordinators can have + methods dispatch to their mediator. + +* Should only operate on the main thread. + +* If custom view controller presentation or animation is required, the + coordinator can be the presented view controller’s transitioning delegate, or + it can create a helper object for that. + +### Mediators + +* Should have any services they need passed into them by the coordinator. They + shouldn’t depend on singletons, or on aggregate service objects such as + `BrowserState`. + +* Can communicate with their consumer _only_ over the consumer interface and + _only_ on the main thread. It is the mediator’s responsibility to manage any + model updates that occur on other threads and consolidate them into updates + sent to the consumer on the main thread. + +* Can only send Foundation value types, collections, or data classes containing + them to their consumer. + +* Cannot expose any kind of delegate interface for the consumer to call. + Mediators push updates to consumers, and view controllers call command methods + to induce model changes. + +### Dispatchers + +* Should only be used for "command-ish" methods. The dispatcher shouldn’t be + used to implement what are functionally delegation, observation, or + notification relationships. Other tools (such as the Broadcaster, and + model-layer observers) exist for those purposes. +
diff --git a/ios/clean/chrome/browser/ui/settings/BUILD.gn b/ios/clean/chrome/browser/ui/settings/BUILD.gn index e5b4bf6..da44106 100644 --- a/ios/clean/chrome/browser/ui/settings/BUILD.gn +++ b/ios/clean/chrome/browser/ui/settings/BUILD.gn
@@ -4,18 +4,43 @@ source_set("settings") { sources = [ + "material_cell_catalog_coordinator.h", + "material_cell_catalog_coordinator.mm", "settings_coordinator.h", "settings_coordinator.mm", + "settings_main_page_coordinator.h", + "settings_main_page_coordinator.mm", ] configs += [ "//build/config/compiler:enable_arc" ] deps = [ + "//base:base", + "//ios/chrome/browser/browser_state", "//ios/chrome/browser/ui/settings", "//ios/clean/chrome/browser/ui/actions", "//ios/clean/chrome/browser/ui/commands", "//ios/shared/chrome/browser/ui/browser_list", "//ios/shared/chrome/browser/ui/commands", "//ios/shared/chrome/browser/ui/coordinators", + "//ios/shared/chrome/browser/ui/settings", + ] +} + +source_set("unit_tests") { + testonly = true + sources = [ + "material_cell_catalog_coordinator_unittest.mm", + ] + + configs += [ "//build/config/compiler:enable_arc" ] + + deps = [ + ":settings", + "//ios/chrome/browser/browser_state:test_support", + "//ios/chrome/browser/ui/settings", + "//ios/shared/chrome/browser/ui/browser_list", + "//ios/shared/chrome/browser/ui/coordinators:test_support", + "//testing/gtest", ] }
diff --git a/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator.h b/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator.h new file mode 100644 index 0000000..2f1db71 --- /dev/null +++ b/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator.h
@@ -0,0 +1,15 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CLEAN_CHROME_BROWSER_UI_SETTINGS_MATERIAL_CELL_CATALOG_COORDINATOR_H_ +#define IOS_CLEAN_CHROME_BROWSER_UI_SETTINGS_MATERIAL_CELL_CATALOG_COORDINATOR_H_ + +#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" + +// A coordinator for the Material Cell Catalog in Settings. That screen is +// usually pushed onto a navigation controller. +@interface MaterialCellCatalogCoordinator : BrowserCoordinator +@end + +#endif // IOS_CLEAN_CHROME_BROWSER_UI_SETTINGS_MATERIAL_CELL_CATALOG_COORDINATOR_H_
diff --git a/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator.mm b/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator.mm new file mode 100644 index 0000000..f23ed65 --- /dev/null +++ b/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator.mm
@@ -0,0 +1,25 @@ +// 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 "ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator.h" + +#import "ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface MaterialCellCatalogCoordinator () +@property(nonatomic, strong) UIViewController* viewController; +@end + +@implementation MaterialCellCatalogCoordinator +@synthesize viewController = _viewController; + +- (void)start { + self.viewController = [[MaterialCellCatalogViewController alloc] init]; + [super start]; +} + +@end
diff --git a/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator_unittest.mm b/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator_unittest.mm new file mode 100644 index 0000000..f860231 --- /dev/null +++ b/ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator_unittest.mm
@@ -0,0 +1,20 @@ +// 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 "ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator.h" + +#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator_test.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +typedef BrowserCoordinatorTest MaterialCellCatalogCoordinatorTest; + +TEST_F(MaterialCellCatalogCoordinatorTest, Start) { + MaterialCellCatalogCoordinator* coordinator = + [[MaterialCellCatalogCoordinator alloc] init]; + [coordinator start]; +}
diff --git a/ios/clean/chrome/browser/ui/settings/settings_coordinator.h b/ios/clean/chrome/browser/ui/settings/settings_coordinator.h index e1fbadc..502733e 100644 --- a/ios/clean/chrome/browser/ui/settings/settings_coordinator.h +++ b/ios/clean/chrome/browser/ui/settings/settings_coordinator.h
@@ -11,6 +11,7 @@ // A coordinator for the Settings UI, which is usually presented modally // on top of whatever other UI is currently active. +// The Browser of this coordinator must be non-incognito. @interface SettingsCoordinator : BrowserCoordinator @end
diff --git a/ios/clean/chrome/browser/ui/settings/settings_coordinator.mm b/ios/clean/chrome/browser/ui/settings/settings_coordinator.mm index 9712317..751023cf 100644 --- a/ios/clean/chrome/browser/ui/settings/settings_coordinator.mm +++ b/ios/clean/chrome/browser/ui/settings/settings_coordinator.mm
@@ -4,8 +4,11 @@ #import "ios/clean/chrome/browser/ui/settings/settings_coordinator.h" +#include "base/logging.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/clean/chrome/browser/ui/commands/settings_commands.h" +#import "ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.h" #import "ios/shared/chrome/browser/ui/browser_list/browser.h" #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h" #import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" @@ -14,7 +17,20 @@ #error "This file requires ARC support." #endif -@interface SettingsCoordinator ()<SettingsNavigationControllerDelegate> +namespace { +// Traverses the coordinator hierarchy in a pre-order depth-first traversal. +// |block| is called on all children of |coordinator|. +void TraverseCoordinatorHierarchy(BrowserCoordinator* coordinator, + void (^block)(BrowserCoordinator*)) { + for (BrowserCoordinator* child in coordinator.children) { + block(child); + TraverseCoordinatorHierarchy(child, block); + } +} +} // namespace + +@interface SettingsCoordinator ()<SettingsNavigationControllerDelegate, + UINavigationControllerDelegate> @property(nonatomic, strong) SettingsNavigationController* viewController; @end @@ -24,9 +40,18 @@ #pragma mark - BrowserCoordinator - (void)start { - self.viewController = [SettingsNavigationController - newSettingsMainControllerWithBrowserState:self.browser->browser_state() - delegate:self]; + DCHECK(!self.browser->browser_state()->IsOffTheRecord()); + SettingsMainPageCoordinator* mainPageCoordinator = + [[SettingsMainPageCoordinator alloc] init]; + [self addChildCoordinator:mainPageCoordinator]; + [mainPageCoordinator start]; + self.viewController = [[SettingsNavigationController alloc] + initWithRootViewController:mainPageCoordinator.viewController + browserState:self.browser->browser_state() + delegate:self]; + self.viewController.delegate = self; + mainPageCoordinator.viewController.navigationItem.rightBarButtonItem = + [self.viewController doneButton]; [super start]; } @@ -48,4 +73,25 @@ [static_cast<id>(self.browser->dispatcher()) closeSettings]; } +#pragma mark - UINavigationControllerDelegate + +- (void)navigationController:(UINavigationController*)navigationController + didShowViewController:(UIViewController*)viewController + animated:(BOOL)animated { + UIViewController* fromViewController = + [navigationController.transitionCoordinator + viewControllerForKey:UITransitionContextFromViewControllerKey]; + if ([navigationController.viewControllers + containsObject:fromViewController]) { + return; + } + // Clean the coordinator hierarchy from coordinators whose view controller was + // popped via the UI (system back button or swipe to go back.) + TraverseCoordinatorHierarchy(self, ^(BrowserCoordinator* child) { + if ([child.viewController isEqual:fromViewController]) { + [child stop]; + } + }); +} + @end
diff --git a/ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.h b/ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.h new file mode 100644 index 0000000..bdb8d445 --- /dev/null +++ b/ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.h
@@ -0,0 +1,15 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CLEAN_CHROME_BROWSER_UI_SETTINGS_SETTINGS_MAIN_PAGE_COORDINATOR_H_ +#define IOS_CLEAN_CHROME_BROWSER_UI_SETTINGS_SETTINGS_MAIN_PAGE_COORDINATOR_H_ + +#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" + +// A coordinator for the Settings main screen. That screen is usually pushed +// onto a navigation controller. +@interface SettingsMainPageCoordinator : BrowserCoordinator +@end + +#endif // IOS_CLEAN_CHROME_BROWSER_UI_SETTINGS_SETTINGS_MAIN_PAGE_COORDINATOR_H_
diff --git a/ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.mm b/ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.mm new file mode 100644 index 0000000..89ef68f9 --- /dev/null +++ b/ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.mm
@@ -0,0 +1,61 @@ +// 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 "ios/clean/chrome/browser/ui/settings/settings_main_page_coordinator.h" + +#include "base/logging.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#import "ios/chrome/browser/ui/settings/settings_collection_view_controller.h" +#import "ios/clean/chrome/browser/ui/settings/material_cell_catalog_coordinator.h" +#import "ios/shared/chrome/browser/ui/browser_list/browser.h" +#import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h" +#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" +#import "ios/shared/chrome/browser/ui/settings/settings_main_page_commands.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface SettingsMainPageCoordinator ()<SettingsMainPageCommands> +@property(nonatomic, strong) SettingsCollectionViewController* viewController; +@end + +@implementation SettingsMainPageCoordinator +@synthesize viewController = _viewController; + +- (void)start { + DCHECK(!self.browser->browser_state()->IsOffTheRecord()); + self.viewController = [[SettingsCollectionViewController alloc] + initWithBrowserState:self.browser->browser_state()]; + [self.browser->dispatcher() + startDispatchingToTarget:self + forProtocol:@protocol(SettingsMainPageCommands)]; + self.viewController.dispatcher = static_cast<id>(self.browser->dispatcher()); + [super start]; +} + +#pragma mark - SettingsMainPageViewControllerDelegate + +- (void)showMaterialCellCatalog { + MaterialCellCatalogCoordinator* coordinator = + [[MaterialCellCatalogCoordinator alloc] init]; + [self addChildCoordinator:coordinator]; + [coordinator start]; +} + +#pragma mark - BrowserCoordinator + +- (void)childCoordinatorDidStart:(BrowserCoordinator*)coordinator { + [self.viewController.navigationController + pushViewController:coordinator.viewController + animated:YES]; +} + +- (void)childCoordinatorWillStop:(BrowserCoordinator*)childCoordinator { + [self.viewController.navigationController + popToViewController:self.viewController + animated:YES]; +} + +@end
diff --git a/ios/clean/chrome/test/BUILD.gn b/ios/clean/chrome/test/BUILD.gn index b68f0ac..f4a6f6aa 100644 --- a/ios/clean/chrome/test/BUILD.gn +++ b/ios/clean/chrome/test/BUILD.gn
@@ -27,6 +27,7 @@ "//ios/clean/chrome/browser/ui/omnibox:unit_tests", "//ios/clean/chrome/browser/ui/recent_tabs:unit_tests", "//ios/clean/chrome/browser/ui/root:unit_tests", + "//ios/clean/chrome/browser/ui/settings:unit_tests", "//ios/clean/chrome/browser/ui/tab:unit_tests", "//ios/clean/chrome/browser/ui/tab_collection:unit_tests", "//ios/clean/chrome/browser/ui/tab_grid:unit_tests",
diff --git a/ios/shared/chrome/browser/ui/settings/BUILD.gn b/ios/shared/chrome/browser/ui/settings/BUILD.gn new file mode 100644 index 0000000..ac535bc --- /dev/null +++ b/ios/shared/chrome/browser/ui/settings/BUILD.gn
@@ -0,0 +1,20 @@ +# 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. + +source_set("settings") { + sources = [ + "settings_main_page_commands.h", + ] + + configs += [ "//build/config/compiler:enable_arc" ] + + deps = [ + # "//base", + # "//ios/chrome/app:tests_fake_hook", + # "//ios/chrome/browser", + # "//ios/chrome/browser/browser_state", + # "//ios/chrome/browser/tabs:tabs_internal", + # "//ios/shared/chrome/browser/ui/browser_list", + ] +}
diff --git a/ios/shared/chrome/browser/ui/settings/settings_main_page_commands.h b/ios/shared/chrome/browser/ui/settings/settings_main_page_commands.h new file mode 100644 index 0000000..145944d --- /dev/null +++ b/ios/shared/chrome/browser/ui/settings/settings_main_page_commands.h
@@ -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. + +#ifndef IOS_SHARED_CHROME_BROWSER_UI_SETTINGS_SETTINGS_MAIN_PAGE_COMMANDS_H_ +#define IOS_SHARED_CHROME_BROWSER_UI_SETTINGS_SETTINGS_MAIN_PAGE_COMMANDS_H_ + +// Command protocol for commands related to the Settings Main Page. +@protocol SettingsMainPageCommands +// Called when the Material Cell Catalog cell is tapped. +- (void)showMaterialCellCatalog; +@end + +#endif // IOS_SHARED_CHROME_BROWSER_UI_SETTINGS_SETTINGS_MAIN_PAGE_COMMANDS_H_
diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc index e3d994f..c048bf3 100644 --- a/media/audio/audio_input_controller.cc +++ b/media/audio/audio_input_controller.cc
@@ -359,11 +359,11 @@ // Finally, keep the stream pointer around, update the state and notify. stream_ = stream_to_control; - handler_->OnCreated(this); - // Check the current muted state and start the repeating timer to keep that - // updated. - CheckMutedState(); + // Send initial muted state along with OnCreated, to avoid races. + is_muted_ = stream_->IsMuted(); + handler_->OnCreated(this, is_muted_); + check_muted_state_timer_.Start( FROM_HERE, base::TimeDelta::FromSeconds(kCheckMutedStateIntervalSeconds), this, &AudioInputController::CheckMutedState);
diff --git a/media/audio/audio_input_controller.h b/media/audio/audio_input_controller.h index b037996..2b8669c2 100644 --- a/media/audio/audio_input_controller.h +++ b/media/audio/audio_input_controller.h
@@ -104,15 +104,16 @@ // following methods are all called on the audio thread. class MEDIA_EXPORT EventHandler { public: - virtual void OnCreated(AudioInputController* controller) = 0; + // The initial "muted" state of the underlying stream is sent along with the + // OnCreated callback, to avoid the stream being treated as unmuted until an + // OnMuted callback has had time to be processed. + virtual void OnCreated(AudioInputController* controller, + bool initially_muted) = 0; virtual void OnError(AudioInputController* controller, ErrorCode error_code) = 0; virtual void OnLog(AudioInputController* controller, const std::string& message) = 0; - // Initially, an AudioInputController is considered not muted. If the - // underlying stream is actually muted, an OnMuted callback will follow - // shortly after OnCreated. It is also called whenever the muted state of - // the underlying stream changes. + // Called whenever the muted state of the underlying stream changes. virtual void OnMuted(AudioInputController* controller, bool is_muted) = 0; protected:
diff --git a/media/audio/audio_input_controller_unittest.cc b/media/audio/audio_input_controller_unittest.cc index fc290e6..0b8ef921 100644 --- a/media/audio/audio_input_controller_unittest.cc +++ b/media/audio/audio_input_controller_unittest.cc
@@ -61,7 +61,8 @@ public: MockAudioInputControllerEventHandler() {} - MOCK_METHOD1(OnCreated, void(AudioInputController* controller)); + MOCK_METHOD2(OnCreated, + void(AudioInputController* controller, bool initially_muted)); MOCK_METHOD2(OnError, void(AudioInputController* controller, AudioInputController::ErrorCode error_code)); MOCK_METHOD2(OnLog, @@ -136,7 +137,7 @@ audio_manager_.get(), &event_handler, &sync_writer, nullptr, params, AudioDeviceDescription::kDefaultDeviceId, false); ASSERT_TRUE(controller.get()); - EXPECT_CALL(event_handler, OnCreated(controller.get())).Times(Exactly(1)); + EXPECT_CALL(event_handler, OnCreated(controller.get(), _)).Times(Exactly(1)); EXPECT_CALL(event_handler, OnLog(controller.get(), _)).Times(Exactly(3)); EXPECT_CALL(sync_writer, Close()).Times(Exactly(1)); ResumeAudioThread(); @@ -151,7 +152,7 @@ int count = 0; // OnCreated() will be called once. - EXPECT_CALL(event_handler, OnCreated(NotNull())) + EXPECT_CALL(event_handler, OnCreated(NotNull(), _)) .Times(Exactly(1)); // Write() should be called ten times. @@ -186,7 +187,7 @@ MockSyncWriter sync_writer; // OnCreated() shall not be called in this test. - EXPECT_CALL(event_handler, OnCreated(NotNull())).Times(Exactly(0)); + EXPECT_CALL(event_handler, OnCreated(NotNull(), _)).Times(Exactly(0)); AudioParameters params(AudioParameters::AUDIO_FAKE, kChannelLayout, @@ -205,7 +206,7 @@ MockSyncWriter sync_writer; // OnCreated() will be called only once. - EXPECT_CALL(event_handler, OnCreated(NotNull())).Times(Exactly(1)); + EXPECT_CALL(event_handler, OnCreated(NotNull(), _)).Times(Exactly(1)); EXPECT_CALL(event_handler, OnLog(_, _)).Times(AnyNumber()); // This callback should still only be called once. EXPECT_CALL(sync_writer, Close()).Times(Exactly(1)); @@ -252,7 +253,8 @@ base::RunLoop unmute_run_loop; base::RunLoop mute_run_loop; base::RunLoop setup_run_loop; - EXPECT_CALL(event_handler, OnCreated(_)).Times(Exactly(1)); + EXPECT_CALL(event_handler, OnCreated(_, false)) + .WillOnce(InvokeWithoutArgs([&] { setup_run_loop.QuitWhenIdle(); })); EXPECT_CALL(event_handler, OnLog(_, _)).Times(Exactly(3)); EXPECT_CALL(sync_writer, Close()).Times(Exactly(1)); EXPECT_CALL(event_handler, OnMuted(_, true)) @@ -265,7 +267,7 @@ audio_manager_.get(), &event_handler, &sync_writer, nullptr, params, AudioDeviceDescription::kDefaultDeviceId, false); ASSERT_TRUE(controller.get()); - setup_run_loop.RunUntilIdle(); + RunLoopWithTimeout(&setup_run_loop, timeout); FakeAudioInputStream::SetGlobalMutedState(true); RunLoopWithTimeout(&mute_run_loop, timeout); @@ -288,11 +290,10 @@ base::RunLoop unmute_run_loop; base::RunLoop setup_run_loop; - EXPECT_CALL(event_handler, OnCreated(_)).Times(Exactly(1)); + EXPECT_CALL(event_handler, OnCreated(_, true)) + .WillOnce(InvokeWithoutArgs([&] { setup_run_loop.QuitWhenIdle(); })); EXPECT_CALL(event_handler, OnLog(_, _)).Times(Exactly(3)); EXPECT_CALL(sync_writer, Close()).Times(Exactly(1)); - EXPECT_CALL(event_handler, OnMuted(_, true)) - .WillOnce(InvokeWithoutArgs([&] { setup_run_loop.QuitWhenIdle(); })); EXPECT_CALL(event_handler, OnMuted(_, false)) .WillOnce(InvokeWithoutArgs([&] { unmute_run_loop.Quit(); }));
diff --git a/media/audio/audio_input_device.cc b/media/audio/audio_input_device.cc index eb31a57..3d6819d 100644 --- a/media/audio/audio_input_device.cc +++ b/media/audio/audio_input_device.cc
@@ -149,11 +149,11 @@ this, enabled)); } -void AudioInputDevice::OnStreamCreated( - base::SharedMemoryHandle handle, - base::SyncSocket::Handle socket_handle, - int length, - int total_segments) { +void AudioInputDevice::OnStreamCreated(base::SharedMemoryHandle handle, + base::SyncSocket::Handle socket_handle, + int length, + int total_segments, + bool initially_muted) { DCHECK(task_runner()->BelongsToCurrentThread()); DCHECK(base::SharedMemory::IsHandleValid(handle)); #if defined(OS_WIN) @@ -175,6 +175,10 @@ DCHECK(!audio_callback_); DCHECK(!audio_thread_); + + if (initially_muted) + callback_->OnCaptureMuted(true); + audio_callback_.reset(new AudioInputDevice::AudioThreadCallback( audio_parameters_, handle, length, total_segments, callback_, base::BindRepeating(&AudioInputDevice::SetLastCallbackTimeToNow, this)));
diff --git a/media/audio/audio_input_device.h b/media/audio/audio_input_device.h index 3072e2f..d656256 100644 --- a/media/audio/audio_input_device.h +++ b/media/audio/audio_input_device.h
@@ -104,7 +104,8 @@ void OnStreamCreated(base::SharedMemoryHandle handle, base::SyncSocket::Handle socket_handle, int length, - int total_segments) override; + int total_segments, + bool initially_muted) override; void OnError() override; void OnMuted(bool is_muted) override; void OnIPCClosed() override;
diff --git a/media/audio/audio_input_device_unittest.cc b/media/audio/audio_input_device_unittest.cc index 1642ad0..3862398 100644 --- a/media/audio/audio_input_device_unittest.cc +++ b/media/audio/audio_input_device_unittest.cc
@@ -100,7 +100,7 @@ ACTION_P5(ReportOnStreamCreated, device, handle, socket, length, segments) { static_cast<AudioInputIPCDelegate*>(device)->OnStreamCreated( - handle, socket, length, segments); + handle, socket, length, segments, false); } TEST(AudioInputDeviceTest, CreateStream) {
diff --git a/media/audio/audio_input_ipc.h b/media/audio/audio_input_ipc.h index 058d4d0..1f51ebe 100644 --- a/media/audio/audio_input_ipc.h +++ b/media/audio/audio_input_ipc.h
@@ -30,7 +30,8 @@ virtual void OnStreamCreated(base::SharedMemoryHandle handle, base::SyncSocket::Handle socket_handle, int length, - int total_segments) = 0; + int total_segments, + bool initially_muted) = 0; // Called when state of an audio stream has changed. virtual void OnError() = 0;
diff --git a/media/base/audio_capturer_source.h b/media/base/audio_capturer_source.h index 6e34ddc..1107882 100644 --- a/media/base/audio_capturer_source.h +++ b/media/base/audio_capturer_source.h
@@ -41,7 +41,8 @@ // Signals an error has occurred. virtual void OnCaptureError(const std::string& message) = 0; - // Signals the muted state has changed. + // Signals the muted state has changed. May be called before + // OnCaptureStarted. virtual void OnCaptureMuted(bool is_muted) = 0; protected:
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc b/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc index 7d7a3ed..33e4938 100644 --- a/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc +++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
@@ -96,6 +96,17 @@ g_coordinator_impl = nullptr; } +base::ProcessId CoordinatorImpl::GetProcessIdForClientIdentity( + service_manager::Identity identity) const { + // TODO(primiano): the browser process registers bypassing mojo and ends up + // with an invalid identity. Fix that (crbug.com/733165) and remove the + // special case in the else branch below. + if (!identity.IsValid()) { + return base::GetCurrentProcId(); + } + return process_map_->GetProcessId(identity); +} + service_manager::Identity CoordinatorImpl::GetClientIdentityForCurrentRequest() const { return bindings_.dispatch_context(); @@ -154,14 +165,16 @@ } void CoordinatorImpl::RegisterClientProcess( - mojom::ClientProcessPtr client_process_ptr) { + mojom::ClientProcessPtr client_process_ptr, + mojom::ProcessType process_type) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); mojom::ClientProcess* client_process = client_process_ptr.get(); client_process_ptr.set_connection_error_handler( base::Bind(&CoordinatorImpl::UnregisterClientProcess, base::Unretained(this), client_process)); - auto client_info = base::MakeUnique<ClientInfo>( - GetClientIdentityForCurrentRequest(), std::move(client_process_ptr)); + auto client_info = + base::MakeUnique<ClientInfo>(GetClientIdentityForCurrentRequest(), + std::move(client_process_ptr), process_type); auto iterator_and_inserted = clients_.emplace(client_process, std::move(client_info)); DCHECK(iterator_and_inserted.second); @@ -231,20 +244,15 @@ if (process_memory_dump) { const service_manager::Identity& client_identity = iter->second->identity; - base::ProcessId pid = base::kNullProcessId; + const mojom::ProcessType& process_type = iter->second->process_type; + const base::ProcessId pid = GetProcessIdForClientIdentity(client_identity); - // TODO(primiano): the browser process registers bypassing mojo and ends up - // with an invalid identity. Fix that (crbug.com/733165) and remove the - // special case in the else branch below. - if (client_identity.IsValid()) { - pid = process_map_->GetProcessId(client_identity); - } else { - pid = base::GetCurrentProcId(); - } + auto response = base::MakeUnique<QueuedMemoryDumpRequest::Response>( + process_type, std::move(process_memory_dump)); if (pid != base::kNullProcessId) { - queued_memory_dump_requests_.front().process_memory_dumps.push_back( - std::make_pair(pid, std::move(process_memory_dump))); + queued_memory_dump_requests_.front().responses.push_back( + std::make_pair(pid, std::move(response))); } else { VLOG(1) << "Couldn't find a PID for client \"" << client_identity.name() << "." << client_identity.instance() << "\""; @@ -276,9 +284,9 @@ // opening /proc pseudo files. std::map<base::ProcessId, OSMemDump> os_dumps; - for (auto& result : request->process_memory_dumps) { - const base::ProcessId pid = result.first; - const OSMemDump dump = result.second->os_dump; + for (auto& response : request->responses) { + const base::ProcessId pid = response.first; + const OSMemDump dump = response.second->dump_ptr->os_dump; // TODO(hjd): We should have a better way to tell if os_dump is filled. if (dump.resident_set_kb > 0) { @@ -286,7 +294,7 @@ os_dumps[pid] = dump; } - for (auto& extra : result.second->extra_processes_dumps) { + for (auto& extra : response.second->dump_ptr->extra_processes_dumps) { const base::ProcessId extra_pid = extra.first; const OSMemDump extra_dump = extra.second; DCHECK_EQ(0u, os_dumps.count(extra_pid)); @@ -295,14 +303,14 @@ } std::map<base::ProcessId, mojom::ProcessMemoryDumpPtr> finalized_pmds; - for (auto& result : request->process_memory_dumps) { - const base::ProcessId pid = result.first; + for (auto& response : request->responses) { + const base::ProcessId pid = response.first; mojom::ProcessMemoryDumpPtr& pmd = finalized_pmds[pid]; if (!pmd) pmd = mojom::ProcessMemoryDump::New(); - pmd->process_type = result.second->process_type; - pmd->chrome_dump = result.second->chrome_dump; + pmd->process_type = response.second->process_type; + pmd->chrome_dump = response.second->dump_ptr->chrome_dump; pmd->os_dump = CreatePublicOSDump(os_dumps[pid]); } @@ -342,6 +350,13 @@ } } +CoordinatorImpl::QueuedMemoryDumpRequest::Response::Response( + mojom::ProcessType process_type, + mojom::RawProcessMemoryDumpPtr dump_ptr) + : process_type(process_type), dump_ptr(std::move(dump_ptr)) {} + +CoordinatorImpl::QueuedMemoryDumpRequest::Response::~Response() {} + CoordinatorImpl::QueuedMemoryDumpRequest::QueuedMemoryDumpRequest( const base::trace_event::MemoryDumpRequestArgs& args, const RequestGlobalMemoryDumpCallback callback) @@ -351,8 +366,11 @@ CoordinatorImpl::ClientInfo::ClientInfo( const service_manager::Identity& identity, - mojom::ClientProcessPtr client) - : identity(identity), client(std::move(client)) {} + mojom::ClientProcessPtr client, + mojom::ProcessType process_type) + : identity(identity), + client(std::move(client)), + process_type(process_type) {} CoordinatorImpl::ClientInfo::~ClientInfo() {} } // namespace memory_instrumentation
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl.h b/services/resource_coordinator/memory_instrumentation/coordinator_impl.h index bf81cef..d68c3e3 100644 --- a/services/resource_coordinator/memory_instrumentation/coordinator_impl.h +++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl.h
@@ -43,7 +43,8 @@ mojom::CoordinatorRequest) override; // mojom::Coordinator implementation. - void RegisterClientProcess(mojom::ClientProcessPtr) override; + void RegisterClientProcess(mojom::ClientProcessPtr, + mojom::ProcessType) override; void UnregisterClientProcess(mojom::ClientProcess*); void RequestGlobalMemoryDump(const base::trace_event::MemoryDumpRequestArgs&, const RequestGlobalMemoryDumpCallback&) override; @@ -51,6 +52,9 @@ protected: // virtual for testing. virtual service_manager::Identity GetClientIdentityForCurrentRequest() const; + // virtual for testing. + virtual base::ProcessId GetProcessIdForClientIdentity( + service_manager::Identity identity) const; ~CoordinatorImpl() override; private: @@ -66,18 +70,29 @@ const base::trace_event::MemoryDumpRequestArgs args; const RequestGlobalMemoryDumpCallback callback; + struct Response { + Response(mojom::ProcessType, mojom::RawProcessMemoryDumpPtr); + ~Response(); + + const mojom::ProcessType process_type; + const mojom::RawProcessMemoryDumpPtr dump_ptr; + }; + // Collects the data received from OnProcessMemoryDumpResponse(). - std::vector<std::pair<base::ProcessId, mojom::RawProcessMemoryDumpPtr>> - process_memory_dumps; + std::vector<std::pair<base::ProcessId, std::unique_ptr<Response>>> + responses; }; - // Holds the identy and remote reference of registered clients. + // Holds the identity and remote reference of registered clients. struct ClientInfo { - ClientInfo(const service_manager::Identity&, mojom::ClientProcessPtr); + ClientInfo(const service_manager::Identity&, + mojom::ClientProcessPtr, + mojom::ProcessType); ~ClientInfo(); const service_manager::Identity identity; const mojom::ClientProcessPtr client; + const mojom::ProcessType process_type; }; // Callback of RequestProcessMemoryInternalDump.
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc b/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc index 421ba4e..b661d0f 100644 --- a/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc +++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc
@@ -10,6 +10,7 @@ #include "base/trace_event/memory_dump_request_args.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/interface_request.h" +#include "services/resource_coordinator/memory_instrumentation/process_map.h" #include "services/resource_coordinator/public/interfaces/memory_instrumentation/memory_instrumentation.mojom.h" #include "testing/gmock/include/gmock/gmock.h" @@ -24,6 +25,12 @@ using ::testing::Ne; using ::testing::NotNull; using ::testing::NiceMock; +using ::testing::Return; +using ::testing::Contains; +using ::testing::Property; +using ::testing::Pointee; +using ::testing::Field; +using ::testing::Eq; using RequestGlobalMemoryDumpCallback = memory_instrumentation::CoordinatorImpl::RequestGlobalMemoryDumpCallback; @@ -37,23 +44,35 @@ public: FakeCoordinatorImpl() : CoordinatorImpl(nullptr) {} ~FakeCoordinatorImpl() override {} - service_manager::Identity GetClientIdentityForCurrentRequest() - const override { - return service_manager::Identity(); - } + + MOCK_CONST_METHOD0(GetClientIdentityForCurrentRequest, + service_manager::Identity()); + MOCK_CONST_METHOD1(GetProcessIdForClientIdentity, + base::ProcessId(service_manager::Identity)); }; class CoordinatorImplTest : public testing::Test { public: CoordinatorImplTest() {} void SetUp() override { - coordinator_.reset(new FakeCoordinatorImpl); + coordinator_.reset(new NiceMock<FakeCoordinatorImpl>); } void TearDown() override { coordinator_.reset(); } - void RegisterClientProcess(mojom::ClientProcessPtr client_process) { - coordinator_->RegisterClientProcess(std::move(client_process)); + void RegisterClientProcess(mojom::ClientProcessPtr client_process, + base::ProcessId pid, + mojom::ProcessType process_type) { + auto identity = service_manager::Identity(std::to_string(pid)); + + ON_CALL(*coordinator_, GetClientIdentityForCurrentRequest()) + .WillByDefault(Return(identity)); + + ON_CALL(*coordinator_, GetProcessIdForClientIdentity(identity)) + .WillByDefault(Return(pid)); + + coordinator_->RegisterClientProcess(std::move(client_process), + process_type); } void RequestGlobalMemoryDump(MemoryDumpRequestArgs args, @@ -62,17 +81,26 @@ } private: - std::unique_ptr<CoordinatorImpl> coordinator_; + std::unique_ptr<NiceMock<FakeCoordinatorImpl>> coordinator_; base::MessageLoop message_loop_; }; class MockClientProcess : public mojom::ClientProcess { public: - MockClientProcess(CoordinatorImplTest* test_coordinator) : binding_(this) { + MockClientProcess(CoordinatorImplTest* test_coordinator) + : MockClientProcess(test_coordinator, + base::GetCurrentProcId(), + mojom::ProcessType::OTHER) {} + + MockClientProcess(CoordinatorImplTest* test_coordinator, + base::ProcessId pid, + mojom::ProcessType process_type) + : binding_(this) { // Register to the coordinator. mojom::ClientProcessPtr client_process; binding_.Bind(mojo::MakeRequest(&client_process)); - test_coordinator->RegisterClientProcess(std::move(client_process)); + test_coordinator->RegisterClientProcess(std::move(client_process), pid, + process_type); ON_CALL(*this, RequestProcessMemoryDump(_, _)) .WillByDefault( @@ -187,4 +215,59 @@ run_loop.Run(); } +TEST_F(CoordinatorImplTest, GlobalMemoryDumpStruct) { + base::RunLoop run_loop; + + MockClientProcess client_process_1(this, 1, mojom::ProcessType::BROWSER); + MockClientProcess client_process_2(this, 2, mojom::ProcessType::RENDERER); + EXPECT_CALL(client_process_1, RequestProcessMemoryDump(_, _)) + .WillOnce( + Invoke([](const MemoryDumpRequestArgs& args, + const MockClientProcess::RequestProcessMemoryDumpCallback& + callback) { + auto dump = mojom::RawProcessMemoryDump::New(); + dump->chrome_dump.malloc_total_kb = 1; + dump->os_dump.resident_set_kb = 1; + callback.Run(args.dump_guid, true, std::move(dump)); + + })); + EXPECT_CALL(client_process_2, RequestProcessMemoryDump(_, _)) + .WillOnce( + Invoke([](const MemoryDumpRequestArgs& args, + const MockClientProcess::RequestProcessMemoryDumpCallback& + callback) { + auto dump = mojom::RawProcessMemoryDump::New(); + dump->chrome_dump.malloc_total_kb = 2; + dump->os_dump.resident_set_kb = 2; + callback.Run(args.dump_guid, true, std::move(dump)); + })); + + MockGlobalMemoryDumpCallback callback; + EXPECT_CALL(callback, OnCall(Ne(0u), true, NotNull())) + .WillOnce(Invoke([&run_loop](uint64_t dump_guid, bool success, + GlobalMemoryDump* dump) { + + EXPECT_EQ(2U, dump->process_dumps.size()); + EXPECT_THAT(dump->process_dumps, + Contains(Property( + &mojom::ProcessMemoryDumpPtr::get, + Pointee(Field(&mojom::ProcessMemoryDump::process_type, + Eq(mojom::ProcessType::BROWSER)))))); + + EXPECT_THAT(dump->process_dumps, + Contains(Property( + &mojom::ProcessMemoryDumpPtr::get, + Pointee(Field(&mojom::ProcessMemoryDump::process_type, + Eq(mojom::ProcessType::RENDERER)))))); + + run_loop.Quit(); + })); + + base::trace_event::MemoryDumpRequestArgs args = { + 0, base::trace_event::MemoryDumpType::SUMMARY_ONLY, + base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND}; + RequestGlobalMemoryDump(args, callback.Get()); + run_loop.Run(); +} + } // namespace memory_instrumentation
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc index cc230d0..be1193f 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc
@@ -33,7 +33,7 @@ mojo::MakeRequest(&coordinator_)); mojom::ClientProcessPtr process; binding_.Bind(mojo::MakeRequest(&process)); - coordinator_->RegisterClientProcess(std::move(process)); + coordinator_->RegisterClientProcess(std::move(process), config.process_type); // Initialize the public-facing MemoryInstrumentation helper. MemoryInstrumentation::CreateInstance(config.connector, config.service_name); @@ -69,7 +69,6 @@ const base::Optional<base::trace_event::MemoryDumpCallbackResult>& result) { mojom::RawProcessMemoryDumpPtr process_memory_dump( mojom::RawProcessMemoryDump::New()); - process_memory_dump->process_type = process_type_; if (result) { process_memory_dump->os_dump = result->os_dump; process_memory_dump->chrome_dump = result->chrome_dump;
diff --git a/services/resource_coordinator/public/interfaces/memory_instrumentation/memory_instrumentation.mojom b/services/resource_coordinator/public/interfaces/memory_instrumentation/memory_instrumentation.mojom index 1c3900f..05d0fc4 100644 --- a/services/resource_coordinator/public/interfaces/memory_instrumentation/memory_instrumentation.mojom +++ b/services/resource_coordinator/public/interfaces/memory_instrumentation/memory_instrumentation.mojom
@@ -68,7 +68,6 @@ // This struct is used for internal communication between the memory // service (Coordinator) and the client library (ClientProcessImpl). struct RawProcessMemoryDump { - ProcessType process_type; RawOSMemDump os_dump; ChromeMemDump chrome_dump; @@ -118,7 +117,7 @@ // processes and polls them whenever a global dump is required. interface Coordinator { // Registers a client process. - RegisterClientProcess(ClientProcess client_process); + RegisterClientProcess(ClientProcess client_process, ProcessType process_type); // Broadcasts a dump request to all registered client processes, injects the // dump in the trace buffer (if tracing is enabled) and returns a summarized
diff --git a/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp b/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp index 81a7cfe..e56047d9 100644 --- a/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp +++ b/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp
@@ -188,8 +188,7 @@ responses_.at(responses_.size() - num_responses_left_); request_response.request = request.Url().GetString(); request_response.response = response.StatusText(); - request_response.response_time = - WTF::Time::FromInternalValue(response.ResponseTime()).ToDoubleT(); + request_response.response_time = response.ResponseTime().ToDoubleT(); if (--num_responses_left_ != 0) return;
diff --git a/third_party/WebKit/Source/modules/fetch/FetchResponseData.cpp b/third_party/WebKit/Source/modules/fetch/FetchResponseData.cpp index efe397d..3aa001a9 100644 --- a/third_party/WebKit/Source/modules/fetch/FetchResponseData.cpp +++ b/third_party/WebKit/Source/modules/fetch/FetchResponseData.cpp
@@ -281,8 +281,7 @@ : type_(type), status_(status), status_message_(status_message), - header_list_(FetchHeaderList::Create()), - response_time_(0) {} + header_list_(FetchHeaderList::Create()) {} void FetchResponseData::ReplaceBodyStreamBuffer(BodyStreamBuffer* buffer) { if (type_ == kBasicType || type_ == kCORSType) {
diff --git a/third_party/WebKit/Source/modules/fetch/FetchResponseData.h b/third_party/WebKit/Source/modules/fetch/FetchResponseData.h index 53ef249..03ff6d9 100644 --- a/third_party/WebKit/Source/modules/fetch/FetchResponseData.h +++ b/third_party/WebKit/Source/modules/fetch/FetchResponseData.h
@@ -11,6 +11,7 @@ #include "platform/loader/fetch/CrossOriginAccessControl.h" #include "platform/weborigin/KURL.h" #include "platform/wtf/PassRefPtr.h" +#include "platform/wtf/Time.h" #include "platform/wtf/Vector.h" #include "platform/wtf/text/AtomicString.h" #include "public/platform/modules/serviceworker/WebServiceWorkerRequest.h" @@ -80,7 +81,7 @@ // returns |m_buffer|. BodyStreamBuffer* InternalBuffer() const; String InternalMIMEType() const; - int64_t ResponseTime() const { return response_time_; } + Time ResponseTime() const { return response_time_; } String CacheStorageCacheName() const { return cache_storage_cache_name_; } const HTTPHeaderSet& CorsExposedHeaderNames() const { return cors_exposed_header_names_; @@ -95,9 +96,7 @@ status_message_ = status_message; } void SetMIMEType(const String& type) { mime_type_ = type; } - void SetResponseTime(int64_t response_time) { - response_time_ = response_time; - } + void SetResponseTime(Time response_time) { response_time_ = response_time; } void SetCacheStorageCacheName(const String& cache_storage_cache_name) { cache_storage_cache_name_ = cache_storage_cache_name; } @@ -130,7 +129,7 @@ Member<FetchResponseData> internal_response_; Member<BodyStreamBuffer> buffer_; String mime_type_; - int64_t response_time_; + Time response_time_; String cache_storage_cache_name_; HTTPHeaderSet cors_exposed_header_names_; };
diff --git a/third_party/WebKit/Source/platform/exported/WebServiceWorkerResponse.cpp b/third_party/WebKit/Source/platform/exported/WebServiceWorkerResponse.cpp index a322c00..6e61156 100644 --- a/third_party/WebKit/Source/platform/exported/WebServiceWorkerResponse.cpp +++ b/third_party/WebKit/Source/platform/exported/WebServiceWorkerResponse.cpp
@@ -8,6 +8,7 @@ #include "platform/network/HTTPHeaderMap.h" #include "platform/wtf/HashMap.h" #include "platform/wtf/RefCounted.h" +#include "platform/wtf/Time.h" #include "public/platform/WebHTTPHeaderVisitor.h" namespace blink { @@ -18,8 +19,7 @@ WebServiceWorkerResponsePrivate() : status(0), response_type(kWebServiceWorkerResponseTypeDefault), - error(kWebServiceWorkerResponseErrorUnknown), - response_time(0) {} + error(kWebServiceWorkerResponseErrorUnknown) {} WebVector<WebURL> url_list; unsigned short status; WebString status_text; @@ -27,7 +27,7 @@ HTTPHeaderMap headers; RefPtr<BlobDataHandle> blob_data_handle; WebServiceWorkerResponseError error; - int64_t response_time; + Time response_time; WebString cache_storage_cache_name; WebVector<WebString> cors_exposed_header_names; }; @@ -135,11 +135,11 @@ return private_->error; } -void WebServiceWorkerResponse::SetResponseTime(int64_t time) { +void WebServiceWorkerResponse::SetResponseTime(base::Time time) { private_->response_time = time; } -int64_t WebServiceWorkerResponse::ResponseTime() const { +base::Time WebServiceWorkerResponse::ResponseTime() const { return private_->response_time; }
diff --git a/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp b/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp index 61cf41e..4bd02d4 100644 --- a/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp +++ b/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp
@@ -134,8 +134,8 @@ resource_response_->SetResourceLoadInfo(value); } -void WebURLResponse::SetResponseTime(long long response_time) { - resource_response_->SetResponseTime(static_cast<int64_t>(response_time)); +void WebURLResponse::SetResponseTime(base::Time response_time) { + resource_response_->SetResponseTime(response_time); } WebString WebURLResponse::MimeType() const {
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.cpp index ae852e1f..aea3dba8 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.cpp
@@ -100,7 +100,6 @@ expires_(0.0), last_modified_(0.0), app_cache_id_(0), - response_time_(0), connection_info_( net::HttpResponseInfo::ConnectionInfo::CONNECTION_INFO_UNKNOWN), encoded_data_length_(0), @@ -140,7 +139,6 @@ expires_(0.0), last_modified_(0.0), app_cache_id_(0), - response_time_(0), encoded_data_length_(0), encoded_body_length_(0), decoded_body_length_(0) {}
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.h b/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.h index da5c9ef..813f7172 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.h +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceResponse.h
@@ -36,6 +36,7 @@ #include "platform/weborigin/KURL.h" #include "platform/wtf/RefCounted.h" #include "platform/wtf/RefPtr.h" +#include "platform/wtf/Time.h" #include "platform/wtf/Vector.h" #include "platform/wtf/text/CString.h" #include "public/platform/WebURLResponse.h" @@ -328,10 +329,8 @@ did_service_worker_navigation_preload_ = value; } - int64_t ResponseTime() const { return response_time_; } - void SetResponseTime(int64_t response_time) { - response_time_ = response_time; - } + Time ResponseTime() const { return response_time_; } + void SetResponseTime(Time response_time) { response_time_ = response_time; } const AtomicString& RemoteIPAddress() const { return remote_ip_address_; } void SetRemoteIPAddress(const AtomicString& value) { @@ -491,7 +490,7 @@ // The time at which the response headers were received. For cached // responses, this time could be "far" in the past. - int64_t response_time_; + Time response_time_; // ALPN negotiated protocol of the socket which fetched this resource. AtomicString alpn_negotiated_protocol_; @@ -564,7 +563,7 @@ Vector<KURL> url_list_via_service_worker_; String cache_storage_cache_name_; bool did_service_worker_navigation_preload_; - int64_t response_time_; + Time response_time_; String remote_ip_address_; unsigned short remote_port_; long long encoded_data_length_;
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceTest.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceTest.cpp index 2a8c7c9..0c46634 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceTest.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceTest.cpp
@@ -10,6 +10,7 @@ #include "platform/loader/fetch/ResourceResponse.h" #include "platform/testing/TestingPlatformSupport.h" #include "platform/testing/URLTestHelpers.h" +#include "platform/wtf/Time.h" #include "platform/wtf/Vector.h" #include "public/platform/Platform.h" #include "testing/gtest/include/gtest/gtest.h" @@ -24,7 +25,7 @@ ~MockPlatform() override {} // From blink::Platform: - void CacheMetadata(const WebURL& url, int64_t, const char*, size_t) override { + void CacheMetadata(const WebURL& url, Time, const char*, size_t) override { cached_urls_.push_back(url); }
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 bcfd463..6025012 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
@@ -108,8 +108,6 @@ 'android': ['kitkat'], } - DEFAULT_BUILD_DIRECTORIES = ('out',) - FALLBACK_PATHS = {} SUPPORTED_VERSIONS = [] @@ -125,25 +123,6 @@ return cls.FALLBACK_PATHS[cls.SUPPORTED_VERSIONS[-1]] @classmethod - def _static_build_path(cls, filesystem, build_directory, chromium_base, target, comps): - if build_directory: - return filesystem.join(build_directory, target, *comps) - - hits = [] - for directory in cls.DEFAULT_BUILD_DIRECTORIES: - base_dir = filesystem.join(chromium_base, directory, target) - path = filesystem.join(base_dir, *comps) - if filesystem.exists(path): - hits.append((filesystem.mtime(path), path)) - - if hits: - hits.sort(reverse=True) - return hits[0][1] # Return the newest file found. - - # We have to default to something, so pick the last one. - return filesystem.join(base_dir, *comps) - - @classmethod def determine_full_port_name(cls, host, options, port_name): """Return a fully-specified port name that can be used to construct objects.""" # Subclasses will usually override this. @@ -1587,14 +1566,15 @@ directory) for directory in self._options.image_first_tests) def _build_path(self, *comps): + """Returns a path from the build directory.""" return self._build_path_with_target(self._options.target, *comps) def _build_path_with_target(self, target, *comps): - # Note that we don't do the option caching that the base class does, - # because finding the right directory is relatively fast. target = target or self.get_option('target') - return self._static_build_path(self._filesystem, self.get_option('build_directory'), - self.path_from_chromium_base(), target, comps) + return self._filesystem.join( + self.path_from_chromium_base(), + self.get_option('build_directory') or 'out', + target, *comps) def _check_driver_build_up_to_date(self, target): # FIXME: We should probably get rid of this check altogether as it has
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py index 76f861b0..951edcb 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py
@@ -477,8 +477,14 @@ self.assertNotIn('virtual/virtual_passes/passes/virtual_passes/passes/test-virtual-passes.html', tests) def test_build_path(self): - port = self.make_port(options=optparse.Values({'build_directory': '/my-build-directory/'})) - self.assertEqual(port._build_path(), '/my-build-directory/Release') + # Test for a protected method - pylint: disable=protected-access + # Test that optional paths are used regardless of whether they exist. + options = optparse.Values({'configuration': 'Release', 'build_directory': 'xcodebuild'}) + self.assertEqual(self.make_port(options=options)._build_path(), '/mock-checkout/xcodebuild/Release') + + # Test that "out" is used as the default. + options = optparse.Values({'configuration': 'Release', 'build_directory': None}) + self.assertEqual(self.make_port(options=options)._build_path(), '/mock-checkout/out/Release') def test_dont_require_http_server(self): port = self.make_port()
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/factory.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/factory.py index cdbc1e10..09fcd92 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/factory.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/factory.py
@@ -165,7 +165,7 @@ """Returns the configuration to used based on args.gn, if possible.""" # TODO(qyearsley): Default to 'out' everywhere. - build_directory = getattr(options, 'build_directory', None) or 'out' + build_directory = getattr(options, 'build_directory', 'out') target = options.target finder = PathFinder(fs)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux_unittest.py index 36e85ec..0542200 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux_unittest.py
@@ -84,15 +84,6 @@ def test_operating_system(self): self.assertEqual('linux', self.make_port().operating_system()) - def test_build_path(self): - # Test that optional paths are used regardless of whether they exist. - options = optparse.Values({'configuration': 'Release', 'build_directory': '/foo'}) - self.assert_build_path(options, ['/mock-checkout/out/Release'], '/foo/Release') - - # Test that optional relative paths are returned unmodified. - options = optparse.Values({'configuration': 'Release', 'build_directory': 'foo'}) - self.assert_build_path(options, ['/mock-checkout/out/Release'], 'foo/Release') - def test_driver_name_option(self): self.assertTrue(self.make_port()._path_to_driver().endswith('content_shell')) port = self.make_port(options=optparse.Values({'driver_name': 'OtherDriver'}))
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac.py index 680e06d2..c898e85 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac.py
@@ -54,8 +54,6 @@ FALLBACK_PATHS['mac10.9'] = ['mac-mac10.9'] + FALLBACK_PATHS['mac10.10'] FALLBACK_PATHS['retina'] = ['mac-retina', 'mac'] - DEFAULT_BUILD_DIRECTORIES = ('xcodebuild', 'out') - CONTENT_SHELL_NAME = 'Content Shell' BUILD_REQUIREMENTS_URL = 'https://chromium.googlesource.com/chromium/src/+/master/docs/mac_build_instructions.md'
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac_unittest.py index 5310598..6e2e7c5 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac_unittest.py
@@ -46,32 +46,6 @@ def test_operating_system(self): self.assertEqual('mac', self.make_port().operating_system()) - def test_build_path(self): - # Test that optional paths are used regardless of whether they exist. - options = optparse.Values({'configuration': 'Release', 'build_directory': '/foo'}) - self.assert_build_path(options, ['/mock-checkout/out/Release'], '/foo/Release') - - # Test that optional relative paths are returned unmodified. - options = optparse.Values({'configuration': 'Release', 'build_directory': 'foo'}) - self.assert_build_path(options, ['/mock-checkout/out/Release'], 'foo/Release') - - # Test that we prefer the legacy dir over the new dir. - options = optparse.Values({'configuration': 'Release', 'build_directory': None}) - self.assert_build_path( - options, ['/mock-checkout/xcodebuild/Release', '/mock-checkout/out/Release'], '/mock-checkout/xcodebuild/Release') - - def test_build_path_timestamps(self): - options = optparse.Values({'configuration': 'Release', 'build_directory': None}) - port = self.make_port(options=options) - port.host.filesystem.maybe_make_directory('/mock-checkout/out/Release') - port.host.filesystem.maybe_make_directory('/mock-checkout/xcodebuild/Release') - # Check with 'out' being newer. - port.host.filesystem.mtime = lambda f: 5 if '/out/' in f else 4 - self.assertEqual(port._build_path(), '/mock-checkout/out/Release') - # Check with 'xcodebuild' being newer. - port.host.filesystem.mtime = lambda f: 5 if '/xcodebuild/' in f else 4 - self.assertEqual(port._build_path(), '/mock-checkout/xcodebuild/Release') - def test_driver_name_option(self): self.assertTrue(self.make_port()._path_to_driver().endswith('Content Shell')) port = self.make_port(options=optparse.Values(dict(driver_name='OtherDriver')))
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py index 955a9fd4..a5f8e1f 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py
@@ -219,12 +219,6 @@ u'STDOUT: foo\ufffdbar\n' u'STDERR: foo\ufffdbar\n')) - def assert_build_path(self, options, dirs, expected_path): - port = self.make_port(options=options) - for directory in dirs: - port.host.filesystem.maybe_make_directory(directory) - self.assertEqual(port._build_path(), expected_path) - def test_expectations_files(self): port = self.make_port() self.assertEqual(port.expectations_files(), [
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win.py index 3f5c227b..54c6a02 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win.py
@@ -56,8 +56,6 @@ FALLBACK_PATHS = {'win10': ['win']} FALLBACK_PATHS['win7'] = ['win7'] + FALLBACK_PATHS['win10'] - DEFAULT_BUILD_DIRECTORIES = ('build', 'out') - BUILD_REQUIREMENTS_URL = 'https://chromium.googlesource.com/chromium/src/+/master/docs/windows_build_instructions.md' @classmethod
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win_unittest.py index bbfdc7f..fc3f9de 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win_unittest.py
@@ -100,31 +100,6 @@ self.assert_baseline_paths('win-win7', 'win7', '/win') self.assert_baseline_paths('win-win10', 'win') - def test_build_path(self): - # Test that optional paths are used regardless of whether they exist. - options = optparse.Values({'configuration': 'Release', 'build_directory': '/foo'}) - self.assert_build_path(options, ['/mock-checkout/out/Release'], '/foo/Release') - - # Test that optional relative paths are returned unmodified. - options = optparse.Values({'configuration': 'Release', 'build_directory': 'foo'}) - self.assert_build_path(options, ['/mock-checkout/out/Release'], 'foo/Release') - - # Test that we prefer the legacy dir over the new dir. - options = optparse.Values({'configuration': 'Release', 'build_directory': None}) - self.assert_build_path(options, ['/mock-checkout/build/Release', '/mock-checkout/out'], '/mock-checkout/build/Release') - - def test_build_path_timestamps(self): - options = optparse.Values({'configuration': 'Release', 'build_directory': None}) - port = self.make_port(options=options) - port.host.filesystem.maybe_make_directory('/mock-checkout/out/Release') - port.host.filesystem.maybe_make_directory('/mock-checkout/build/Release') - # Check with 'out' being newer. - port.host.filesystem.mtime = lambda f: 5 if '/out/' in f else 4 - self.assertEqual(port._build_path(), '/mock-checkout/out/Release') - # Check with 'build' being newer. - port.host.filesystem.mtime = lambda f: 5 if '/build/' in f else 4 - self.assertEqual(port._build_path(), '/mock-checkout/build/Release') - def test_operating_system(self): self.assertEqual('win', self.make_port().operating_system())
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py index d5368f51..fcc8191 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
@@ -147,8 +147,9 @@ 'multiple search path entries.')), optparse.make_option( '--build-directory', - help=('Path to the directory under which build files are kept (should not ' - 'include configuration)')), + default='out', + help=('Path to the directory where build files are kept, not including ' + 'configuration. In general this will be "out".')), optparse.make_option( '--clobber-old-results', action='store_true',
diff --git a/third_party/WebKit/public/platform/Platform.h b/third_party/WebKit/public/platform/Platform.h index 96abe0e..cc072e9b 100644 --- a/third_party/WebKit/public/platform/Platform.h +++ b/third_party/WebKit/public/platform/Platform.h
@@ -58,6 +58,7 @@ #include "WebURLLoader.h" #include "WebVector.h" #include "base/metrics/user_metrics_action.h" +#include "base/time/time.h" #include "cc/resources/shared_bitmap.h" #include "cc/surfaces/frame_sink_id.h" #include "mojo/public/cpp/system/data_pipe.h" @@ -350,7 +351,7 @@ // A suggestion to cache this metadata in association with this URL. virtual void CacheMetadata(const WebURL&, - int64_t response_time, + base::Time response_time, const char* data, size_t data_size) {} @@ -358,7 +359,7 @@ // resource is in CacheStorage. virtual void CacheMetadataInCacheStorage( const WebURL&, - int64_t response_time, + base::Time response_time, const char* data, size_t data_size, const blink::WebSecurityOrigin& cache_storage_origin,
diff --git a/third_party/WebKit/public/platform/WebURLResponse.h b/third_party/WebKit/public/platform/WebURLResponse.h index d00f6f1..e0b76eaa 100644 --- a/third_party/WebKit/public/platform/WebURLResponse.h +++ b/third_party/WebKit/public/platform/WebURLResponse.h
@@ -32,6 +32,8 @@ #define WebURLResponse_h #include <memory> + +#include "base/time/time.h" #include "net/http/http_response_info.h" #include "public/platform/WebCString.h" #include "public/platform/WebCommon.h" @@ -160,7 +162,7 @@ BLINK_PLATFORM_EXPORT void SetHTTPLoadInfo(const WebHTTPLoadInfo&); - BLINK_PLATFORM_EXPORT void SetResponseTime(long long); + BLINK_PLATFORM_EXPORT void SetResponseTime(base::Time); BLINK_PLATFORM_EXPORT WebString MimeType() const; BLINK_PLATFORM_EXPORT void SetMIMEType(const WebString&);
diff --git a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponse.h b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponse.h index 8241b96..8942e4d 100644 --- a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponse.h +++ b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponse.h
@@ -5,6 +5,7 @@ #ifndef WebServiceWorkerResponse_h #define WebServiceWorkerResponse_h +#include "base/time/time.h" #include "public/platform/WebCommon.h" #include "public/platform/WebPrivatePtr.h" #include "public/platform/WebString.h" @@ -74,8 +75,8 @@ void SetError(WebServiceWorkerResponseError); WebServiceWorkerResponseError GetError() const; - void SetResponseTime(int64_t); - int64_t ResponseTime() const; + void SetResponseTime(base::Time); + base::Time ResponseTime() const; void SetCacheStorageCacheName(const WebString&); const WebString& CacheStorageCacheName() const;
diff --git a/tools/perf/benchmarks/webrtc.py b/tools/perf/benchmarks/webrtc.py index eb2aeb9f..ffc2e453 100644 --- a/tools/perf/benchmarks/webrtc.py +++ b/tools/perf/benchmarks/webrtc.py
@@ -27,8 +27,7 @@ '-*', 'toplevel', # WebRTC - # TODO(ehmaldonado): Re-enable once http://crbug.com/725502 is fixed. - # 'webrtc', + 'webmediaplayerms', ] category_filter = chrome_trace_category_filter.ChromeTraceCategoryFilter( @@ -36,8 +35,7 @@ options = timeline_based_measurement.Options(category_filter) options.SetTimelineBasedMetrics([ 'cpuTimeMetric', - # TODO(ehmaldonado): Re-enable once http://crbug.com/725502 is fixed. - # 'webrtcRenderingMetric', + 'webrtcRenderingMetric', ]) return options
diff --git a/tools/perf/page_sets/simple_mobile_sites.py b/tools/perf/page_sets/simple_mobile_sites.py index 032e8049d..9ac21b8 100644 --- a/tools/perf/page_sets/simple_mobile_sites.py +++ b/tools/perf/page_sets/simple_mobile_sites.py
@@ -44,7 +44,6 @@ # Why: Scrolls moderately complex pages (up to 60 layers) 'http://www.ebay.co.uk/', 'https://www.flickr.com/', - 'http://www.apple.com/mac/', 'http://www.nyc.gov', 'http://m.nytimes.com/' ]