diff --git a/DEPS b/DEPS index ecf8e66..4c93b900 100644 --- a/DEPS +++ b/DEPS
@@ -59,7 +59,7 @@ # 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': 'd29e0da3523e390eeb77b5a823d7ff86569ac1d3', + 'skia_revision': 'f0a30d71ad242b350d12d8c2d93cc825199ee0f8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -67,7 +67,7 @@ # 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. - 'swarming_revision': 'fe94e7274e40e2e929cdbc8787836f70d38de1f1', + 'swarming_revision': '5da404cf35b6541f16d8bd6cc3e506df1fda8021', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. @@ -605,7 +605,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '34842fa3c36988840c89f5bc6a68503175acf7d9', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '6063e98dcb5044eb010bc69cc307b26925dd033b', # commit position 20528 + Var('webrtc_git') + '/src.git' + '@' + '464e89c0ca66c055c0914f8c21cfba386e0c98ec', # commit position 20528 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 1916aa4..11f0f1e7 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -711,6 +711,9 @@ "utility/transformer_util.h", "virtual_keyboard_controller.cc", "virtual_keyboard_controller.h", + "voice_interaction/voice_interaction_controller.cc", + "voice_interaction/voice_interaction_controller.h", + "voice_interaction/voice_interaction_observer.h", "wallpaper/wallpaper_controller.cc", "wallpaper/wallpaper_controller.h", "wallpaper/wallpaper_controller_observer.h", @@ -1398,6 +1401,7 @@ "tray_action/tray_action_unittest.cc", "utility/screenshot_controller_unittest.cc", "virtual_keyboard_controller_unittest.cc", + "voice_interaction/voice_interaction_controller_unittest.cc", "wallpaper/wallpaper_controller_unittest.cc", "window_user_data_unittest.cc", "wm/always_on_top_controller_unittest.cc",
diff --git a/ash/mojo_interface_factory.cc b/ash/mojo_interface_factory.cc index 98db73eb..fe16e05 100644 --- a/ash/mojo_interface_factory.cc +++ b/ash/mojo_interface_factory.cc
@@ -27,6 +27,7 @@ #include "ash/system/night_light/night_light_controller.h" #include "ash/system/tray/system_tray_controller.h" #include "ash/tray_action/tray_action.h" +#include "ash/voice_interaction/voice_interaction_controller.h" #include "ash/wallpaper/wallpaper_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "base/bind.h" @@ -131,6 +132,11 @@ Shell::Get()->tray_action()->BindRequest(std::move(request)); } +void BindVoiceInteractionControllerRequestOnMainThread( + mojom::VoiceInteractionControllerRequest request) { + Shell::Get()->voice_interaction_controller()->BindRequest(std::move(request)); +} + void BindVpnListRequestOnMainThread(mojom::VpnListRequest request) { Shell::Get()->vpn_list()->BindRequest(std::move(request)); } @@ -193,6 +199,9 @@ main_thread_task_runner); registry->AddInterface(base::Bind(&BindTrayActionRequestOnMainThread), main_thread_task_runner); + registry->AddInterface( + base::Bind(&BindVoiceInteractionControllerRequestOnMainThread), + main_thread_task_runner); registry->AddInterface(base::Bind(&BindVpnListRequestOnMainThread), main_thread_task_runner); registry->AddInterface(base::Bind(&BindWallpaperRequestOnMainThread),
diff --git a/ash/mus/manifest.json b/ash/mus/manifest.json index 3314e7e9..28a02e18 100644 --- a/ash/mus/manifest.json +++ b/ash/mus/manifest.json
@@ -26,6 +26,7 @@ "ash::mojom::SystemTray", "ash::mojom::TabletModeController", "ash::mojom::TrayAction", + "ash::mojom::VoiceInteractionController", "ash::mojom::VpnList", "ash::mojom::WallpaperController" ],
diff --git a/ash/mus/standalone/manifest.json b/ash/mus/standalone/manifest.json index 3410d91..a50e7937 100644 --- a/ash/mus/standalone/manifest.json +++ b/ash/mus/standalone/manifest.json
@@ -19,6 +19,7 @@ "ash::mojom::ShutdownController", "ash::mojom::SystemTray", "ash::mojom::TabletModeController", + "ash::mojom::VoiceInteractionController", "ash::mojom::VpnList", "ash::mojom::WallpaperController" ],
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn index 4992d0c..6da4d1a7 100644 --- a/ash/public/cpp/BUILD.gn +++ b/ash/public/cpp/BUILD.gn
@@ -49,7 +49,6 @@ "shell_window_ids.h", "stylus_utils.cc", "stylus_utils.h", - "voice_interaction_state.h", "window_pin_type.cc", "window_pin_type.h", "window_properties.cc",
diff --git a/ash/public/cpp/voice_interaction_state.h b/ash/public/cpp/voice_interaction_state.h deleted file mode 100644 index fd9d049..0000000 --- a/ash/public/cpp/voice_interaction_state.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_PUBLIC_CPP_VOICE_INTERACTION_STATE_H_ -#define ASH_PUBLIC_CPP_VOICE_INTERACTION_STATE_H_ - -namespace ash { - -enum class VoiceInteractionState { - // Voice interaction service is not ready yet, request sent will be waiting. - NOT_READY = 0, - // Voice interaction session is stopped. - STOPPED, - // Voice interaction session is currently running. - RUNNING -}; - -} // namespace ash - -#endif // ASH_PUBLIC_CPP_VOICE_INTERACTION_STATE_H_
diff --git a/ash/public/interfaces/BUILD.gn b/ash/public/interfaces/BUILD.gn index 3aa2427..1f54d61 100644 --- a/ash/public/interfaces/BUILD.gn +++ b/ash/public/interfaces/BUILD.gn
@@ -37,6 +37,7 @@ "tray_action.mojom", "update.mojom", "user_info.mojom", + "voice_interaction_controller.mojom", "volume.mojom", "vpn_list.mojom", "wallpaper.mojom",
diff --git a/ash/public/interfaces/voice_interaction_controller.mojom b/ash/public/interfaces/voice_interaction_controller.mojom new file mode 100644 index 0000000..8b0e06c8 --- /dev/null +++ b/ash/public/interfaces/voice_interaction_controller.mojom
@@ -0,0 +1,41 @@ +// 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. + +module ash.mojom; + +// There is another copy of the VoiceInteractionState definition in +// //components/arc/common/voice_interaction_framework.mojom +// Please also update the other one if you change it. +// The duplicate definition is because we do not use extensible widely +// (crbug.com/731893). + +// The initial state is NOT_READY, then it will either becomes STOPPED or +// RUNNING. If the mojo connection is lost, the state will be set back to +// NOT_READY. +enum VoiceInteractionState { + // Voice interaction service is not ready yet, request sent will be waiting. + NOT_READY = 0, + // Voice interaction session is stopped. + STOPPED, + // Voice interaction session is currently running. + RUNNING +}; + +// Interface for ash client (Chrome) to connect to the voice interaction +// controller, which notifies changes of voice interaction related flags. +interface VoiceInteractionController { + // Called when the voice interaction state is changed. + NotifyStatusChanged(VoiceInteractionState state); + + // Called when the voice interaction settings is enabled/disabled. + NotifySettingsEnabled(bool enabled); + + // Called when the voice interaction context is enabled/disabled. + // If context is enabled the screenshot will be passed in voice + // interaction session. + NotifyContextEnabled(bool enabled); + + // Called when the voice interaction setup complete status is changed. + NotifySetupCompleted(bool completed); +};
diff --git a/ash/shelf/app_list_button.cc b/ash/shelf/app_list_button.cc index 4aa9b6c..ee394b8 100644 --- a/ash/shelf/app_list_button.cc +++ b/ash/shelf/app_list_button.cc
@@ -18,6 +18,7 @@ #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/tray/tray_popup_utils.h" +#include "ash/voice_interaction/voice_interaction_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "base/command_line.h" #include "base/metrics/histogram_macros.h" @@ -74,6 +75,7 @@ DCHECK(shelf_); Shell::Get()->AddShellObserver(this); Shell::Get()->session_controller()->AddObserver(this); + Shell::Get()->voice_interaction_controller()->AddObserver(this); SetInkDropMode(InkDropMode::ON_NO_GESTURE_HANDLER); set_ink_drop_base_color(kShelfInkDropBaseColor); set_ink_drop_visible_opacity(kShelfInkDropVisibleOpacity); @@ -98,6 +100,7 @@ } AppListButton::~AppListButton() { + Shell::Get()->voice_interaction_controller()->RemoveObserver(this); Shell::Get()->RemoveShellObserver(this); Shell::Get()->session_controller()->RemoveObserver(this); } @@ -381,12 +384,15 @@ fg_flags.setStyle(cc::PaintFlags::kStroke_Style); fg_flags.setColor(kShelfIconColor); - if (UseVoiceInteractionStyle()) + if (UseVoiceInteractionStyle()) { + mojom::VoiceInteractionState state = Shell::Get() + ->voice_interaction_controller() + ->voice_interaction_state(); // active: 100% alpha, inactive: 54% alpha - fg_flags.setAlpha(Shell::Get()->voice_interaction_state() == - ash::VoiceInteractionState::RUNNING + fg_flags.setAlpha(state == mojom::VoiceInteractionState::RUNNING ? kVoiceInteractionRunningAlpha : kVoiceInteractionNotRunningAlpha); + } const float thickness = std::ceil(ring_thickness_dp * dsf); const float radius = std::ceil(ring_outer_radius_dp * dsf) - thickness / 2; @@ -488,19 +494,19 @@ } void AppListButton::OnVoiceInteractionStatusChanged( - ash::VoiceInteractionState state) { + mojom::VoiceInteractionState state) { SchedulePaint(); if (!voice_interaction_overlay_) return; switch (state) { - case ash::VoiceInteractionState::STOPPED: + case mojom::VoiceInteractionState::STOPPED: UMA_HISTOGRAM_TIMES( "VoiceInteraction.OpenDuration", base::TimeTicks::Now() - voice_interaction_start_timestamp_); break; - case ash::VoiceInteractionState::NOT_READY: + case mojom::VoiceInteractionState::NOT_READY: // If we are showing the bursting or waiting animation, no need to do // anything. Otherwise show the waiting animation now. if (!voice_interaction_overlay_->IsBursting() && @@ -508,7 +514,7 @@ voice_interaction_overlay_->WaitingAnimation(); } break; - case ash::VoiceInteractionState::RUNNING: + case mojom::VoiceInteractionState::RUNNING: // we start hiding the animation if it is running. if (voice_interaction_overlay_->IsBursting() || voice_interaction_overlay_->IsWaiting()) { @@ -525,11 +531,11 @@ } } -void AppListButton::OnVoiceInteractionEnabled(bool enabled) { +void AppListButton::OnVoiceInteractionSettingsEnabled(bool enabled) { SchedulePaint(); } -void AppListButton::OnVoiceInteractionSetupCompleted() { +void AppListButton::OnVoiceInteractionSetupCompleted(bool completed) { SchedulePaint(); } @@ -537,7 +543,8 @@ SchedulePaint(); // Initialize voice interaction overlay when primary user session becomes // active. - if (IsUserPrimary() && !voice_interaction_overlay_ && + if (Shell::Get()->session_controller()->IsUserPrimary() && + !voice_interaction_overlay_ && chromeos::switches::IsVoiceInteractionEnabled()) { InitializeVoiceInteractionOverlay(); } @@ -548,11 +555,13 @@ // shelf is at the bottom position and voice interaction is not running and // voice interaction setup flow has completed. ShelfAlignment alignment = shelf_->alignment(); - bool show_icon = (alignment == SHELF_ALIGNMENT_BOTTOM || - alignment == SHELF_ALIGNMENT_BOTTOM_LOCKED) && - Shell::Get()->voice_interaction_state() == - VoiceInteractionState::STOPPED && - Shell::Get()->voice_interaction_setup_completed(); + mojom::VoiceInteractionState state = + Shell::Get()->voice_interaction_controller()->voice_interaction_state(); + bool show_icon = + (alignment == SHELF_ALIGNMENT_BOTTOM || + alignment == SHELF_ALIGNMENT_BOTTOM_LOCKED) && + state == mojom::VoiceInteractionState::STOPPED && + Shell::Get()->voice_interaction_controller()->setup_completed(); voice_interaction_overlay_->StartAnimation(show_icon); } @@ -595,10 +604,14 @@ } bool AppListButton::UseVoiceInteractionStyle() { + VoiceInteractionController* controller = + Shell::Get()->voice_interaction_controller(); + bool settings_enabled = controller->settings_enabled(); + bool setup_completed = controller->setup_completed(); if (voice_interaction_overlay_ && - chromeos::switches::IsVoiceInteractionEnabled() && IsUserPrimary() && - (Shell::Get()->voice_interaction_settings_enabled() || - !Shell::Get()->voice_interaction_setup_completed())) { + chromeos::switches::IsVoiceInteractionEnabled() && + Shell::Get()->session_controller()->IsUserPrimary() && + (settings_enabled || !setup_completed)) { return true; } return false; @@ -614,11 +627,4 @@ std::make_unique<base::OneShotTimer>(); } -bool AppListButton::IsUserPrimary() { - // TODO(updowndota) Switch to use SessionController::IsUserPrimary() when - // refactoring voice interaction related shell methods (crbug.com/758650). - return Shell::Get()->session_controller()->GetPrimaryUserSession() == - Shell::Get()->session_controller()->GetUserSession(0); -} - } // namespace ash
diff --git a/ash/shelf/app_list_button.h b/ash/shelf/app_list_button.h index d9876cf..4edaba02 100644 --- a/ash/shelf/app_list_button.h +++ b/ash/shelf/app_list_button.h
@@ -8,9 +8,9 @@ #include <memory> #include "ash/ash_export.h" -#include "ash/public/cpp/voice_interaction_state.h" #include "ash/session/session_observer.h" #include "ash/shell_observer.h" +#include "ash/voice_interaction/voice_interaction_observer.h" #include "base/macros.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/views/controls/button/image_button.h" @@ -28,7 +28,8 @@ // Button used for the AppList icon on the shelf. class ASH_EXPORT AppListButton : public views::ImageButton, public ShellObserver, - public SessionObserver { + public SessionObserver, + public VoiceInteractionObserver { public: AppListButton(InkDropButtonListener* listener, ShelfView* shelf_view, @@ -77,10 +78,12 @@ // ShellObserver: void OnAppListVisibilityChanged(bool shown, aura::Window* root_window) override; + + // VoiceInteractionObserver: void OnVoiceInteractionStatusChanged( - ash::VoiceInteractionState state) override; - void OnVoiceInteractionEnabled(bool enabled) override; - void OnVoiceInteractionSetupCompleted() override; + mojom::VoiceInteractionState state) override; + void OnVoiceInteractionSettingsEnabled(bool enabled) override; + void OnVoiceInteractionSetupCompleted(bool completed) override; // SessionObserver: void OnActiveUserSessionChanged(const AccountId& account_id) override; @@ -102,9 +105,6 @@ // Initialize the voice interaction overlay. void InitializeVoiceInteractionOverlay(); - // Whether the active user is the primary user. - bool IsUserPrimary(); - // True if the app list is currently showing for this display. // This is useful because other IsApplistVisible functions aren't per-display. bool is_showing_app_list_;
diff --git a/ash/shelf/app_list_button_unittest.cc b/ash/shelf/app_list_button_unittest.cc index 162be32..22b94b8 100644 --- a/ash/shelf/app_list_button_unittest.cc +++ b/ash/shelf/app_list_button_unittest.cc
@@ -15,6 +15,7 @@ #include "ash/shelf/shelf_view_test_api.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/voice_interaction/voice_interaction_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "base/command_line.h" #include "base/i18n/rtl.h" @@ -79,7 +80,7 @@ CreateUserSessions(2); // Enable voice interaction in system settings. - Shell::Get()->NotifyVoiceInteractionEnabled(true); + Shell::Get()->voice_interaction_controller()->NotifySettingsEnabled(true); ui::GestureEvent long_press = CreateGestureEvent(ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS)); @@ -148,7 +149,7 @@ CreateUserSessions(2); // Enable voice interaction in system settings. - Shell::Get()->NotifyVoiceInteractionEnabled(true); + Shell::Get()->voice_interaction_controller()->NotifySettingsEnabled(true); ui::GestureEvent long_press = CreateGestureEvent(ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS)); @@ -166,7 +167,7 @@ SimulateUserLogin("user2@test.com"); // Enable voice interaction in system settings. - Shell::Get()->NotifyVoiceInteractionEnabled(true); + Shell::Get()->voice_interaction_controller()->NotifySettingsEnabled(true); ui::GestureEvent long_press = CreateGestureEvent(ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS)); @@ -187,8 +188,8 @@ // Simulate a user who has already completed setup flow, but disabled voice // interaction in settings. - Shell::Get()->NotifyVoiceInteractionEnabled(false); - Shell::Get()->NotifyVoiceInteractionSetupCompleted(true); + Shell::Get()->voice_interaction_controller()->NotifySettingsEnabled(false); + Shell::Get()->voice_interaction_controller()->NotifySetupCompleted(true); ui::GestureEvent long_press = CreateGestureEvent(ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS)); @@ -208,7 +209,7 @@ CreateUserSessions(2); // Disable voice interaction in system settings. - Shell::Get()->NotifyVoiceInteractionEnabled(false); + Shell::Get()->voice_interaction_controller()->NotifySettingsEnabled(false); ui::GestureEvent long_press = CreateGestureEvent(ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
diff --git a/ash/shelf/voice_interaction_overlay.cc b/ash/shelf/voice_interaction_overlay.cc index 93f2f94..8661b9a 100644 --- a/ash/shelf/voice_interaction_overlay.cc +++ b/ash/shelf/voice_interaction_overlay.cc
@@ -114,8 +114,7 @@ } // namespace -class VoiceInteractionIcon : public ui::Layer, - public ui::CompositorAnimationObserver { +class VoiceInteractionIcon : public ui::Layer { public: VoiceInteractionIcon() : Layer(ui::LAYER_NOT_DRAWN) { set_name("VoiceInteractionOverlay:ICON_LAYER"); @@ -127,32 +126,14 @@ } void StartAnimation() { - if (!GetCompositor()->HasAnimationObserver(this)) - GetCompositor()->AddAnimationObserver(this); + animation_timer_.Start(FROM_HERE, + base::TimeDelta::FromMilliseconds( + base::TimeTicks::kMillisecondsPerSecond / + gfx::LinearAnimation::kDefaultFrameRate), + this, &VoiceInteractionIcon::AnimationProgressed); } - void StopAnimation() { - if (GetCompositor()->HasAnimationObserver(this)) - GetCompositor()->RemoveAnimationObserver(this); - } - - // ui::CompositorAnimationObserver - void OnCompositingShuttingDown(ui::Compositor* compositor) override {} - void OnAnimationStep(base::TimeTicks timestamp) override { - uint64_t elapsed = (timestamp - base::TimeTicks()).InMilliseconds(); - for (int i = 0; i < DOT_COUNT; ++i) { - float normalizedTime = - ((elapsed - kMoleculeAnimationOffset * kMoleculeOrder[i]) % - kMoleculeAnimationDurationMs) / - static_cast<float>(kMoleculeAnimationDurationMs); - - gfx::Transform transform; - transform.Translate(0, - kMoleculeAmplitude * sin(normalizedTime * 2 * M_PI)); - - dot_layers_[i]->SetTransform(transform); - } - } + void StopAnimation() { animation_timer_.Stop(); } private: enum Dot { @@ -181,6 +162,25 @@ return "UNKNOWN"; } + void AnimationProgressed() { + gfx::Transform transform; + + uint64_t now = + (base::TimeTicks::Now() - base::TimeTicks()).InMilliseconds(); + for (int i = 0; i < DOT_COUNT; ++i) { + float normalizedTime = + ((now - kMoleculeAnimationOffset * kMoleculeOrder[i]) % + kMoleculeAnimationDurationMs) / + static_cast<float>(kMoleculeAnimationDurationMs); + + transform.MakeIdentity(); + transform.Translate(0, + kMoleculeAmplitude * sin(normalizedTime * 2 * M_PI)); + + dot_layers_[i]->SetTransform(transform); + } + } + /** * Convenience method to place dots to Molecule shape used by Molecule * animations. @@ -209,6 +209,8 @@ std::unique_ptr<ui::Layer> dot_layers_[DOT_COUNT]; std::unique_ptr<views::CircleLayerDelegate> dot_layer_delegates_[DOT_COUNT]; + base::RepeatingTimer animation_timer_; + DISALLOW_COPY_AND_ASSIGN(VoiceInteractionIcon); }; @@ -849,9 +851,8 @@ } void VoiceInteractionOverlay::EndAnimation() { - if (IsBursting() || IsHidden()) { + if (IsBursting()) { // Too late, user action already fired, we have to finish what's started. - // Or the widget has already been hidden, no need to play the end animation. return; }
diff --git a/ash/shelf/voice_interaction_overlay.h b/ash/shelf/voice_interaction_overlay.h index 69abdd8b..4f89c08 100644 --- a/ash/shelf/voice_interaction_overlay.h +++ b/ash/shelf/voice_interaction_overlay.h
@@ -33,7 +33,6 @@ return AnimationState::BURSTING == animation_state_; } bool IsWaiting() const { return AnimationState::WAITING == animation_state_; } - bool IsHidden() const { return AnimationState::HIDDEN == animation_state_; } private: enum class AnimationState {
diff --git a/ash/shell.cc b/ash/shell.cc index 76178ff..4dadb07 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -101,6 +101,7 @@ #include "ash/tray_action/tray_action.h" #include "ash/utility/screenshot_controller.h" #include "ash/virtual_keyboard_controller.h" +#include "ash/voice_interaction/voice_interaction_controller.h" #include "ash/wallpaper/wallpaper_controller.h" #include "ash/wallpaper/wallpaper_delegate.h" #include "ash/wm/ash_focus_rules.h" @@ -577,32 +578,6 @@ observer.OnAppListVisibilityChanged(visible, root_window); } -void Shell::NotifyVoiceInteractionStatusChanged(VoiceInteractionState state) { - voice_interaction_state_ = state; - for (auto& observer : shell_observers_) - observer.OnVoiceInteractionStatusChanged(state); -} - -void Shell::NotifyVoiceInteractionEnabled(bool enabled) { - // TODO(updowndota) Rename the methods name to be consist with the flag name - // after the methods are refactored into the voice interaction related - // cotroller (crbug.com/758650). - voice_interaction_settings_enabled_ = enabled; - for (auto& observer : shell_observers_) - observer.OnVoiceInteractionEnabled(enabled); -} - -void Shell::NotifyVoiceInteractionContextEnabled(bool enabled) { - for (auto& observer : shell_observers_) - observer.OnVoiceInteractionContextEnabled(enabled); -} - -void Shell::NotifyVoiceInteractionSetupCompleted(bool completed) { - voice_interaction_setup_completed_ = completed; - for (auto& observer : shell_observers_) - observer.OnVoiceInteractionSetupCompleted(); -} - //////////////////////////////////////////////////////////////////////////////// // Shell, private: @@ -773,6 +748,7 @@ laser_pointer_controller_.reset(); partial_magnification_controller_.reset(); highlighter_controller_.reset(); + voice_interaction_controller_.reset(); // This also deletes all RootWindows. Note that we invoke Shutdown() on // WindowTreeHostManager before resetting |window_tree_host_manager_|, since @@ -1082,6 +1058,8 @@ laser_pointer_controller_.reset(new LaserPointerController()); partial_magnification_controller_.reset(new PartialMagnificationController()); highlighter_controller_.reset(new HighlighterController()); + voice_interaction_controller_ = + std::make_unique<VoiceInteractionController>(); magnification_controller_.reset(MagnificationController::CreateInstance()); mru_window_tracker_ = std::make_unique<MruWindowTracker>();
diff --git a/ash/shell.h b/ash/shell.h index ab9f32e..144bc6d0 100644 --- a/ash/shell.h +++ b/ash/shell.h
@@ -12,7 +12,6 @@ #include "ash/ash_export.h" #include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/shelf_types.h" -#include "ash/public/cpp/voice_interaction_state.h" #include "ash/session/session_observer.h" #include "ash/wm/cursor_manager_chromeos.h" #include "ash/wm/system_modal_container_event_filter_delegate.h" @@ -163,6 +162,7 @@ class VirtualKeyboardController; class VideoActivityNotifier; class VideoDetector; +class VoiceInteractionController; class VpnList; class WallpaperController; class WallpaperDelegate; @@ -174,7 +174,6 @@ enum class Config; enum class LoginStatus; -enum class VoiceInteractionState; // Shell is a singleton object that presents the Shell API and implements the // RootWindow's delegate interface. @@ -455,6 +454,9 @@ VirtualKeyboardController* virtual_keyboard_controller() { return virtual_keyboard_controller_.get(); } + VoiceInteractionController* voice_interaction_controller() { + return voice_interaction_controller_.get(); + } VpnList* vpn_list() { return vpn_list_.get(); } WallpaperController* wallpaper_controller() { return wallpaper_controller_.get(); @@ -572,28 +574,6 @@ void NotifyAppListVisibilityChanged(bool visible, aura::Window* root_window); - // TODO(kaznacheev) Move voice interaction related methods to a separate - // controller (crbug.com/758650) - void NotifyVoiceInteractionStatusChanged(VoiceInteractionState state); - - void NotifyVoiceInteractionEnabled(bool enabled); - - void NotifyVoiceInteractionContextEnabled(bool enabled); - - void NotifyVoiceInteractionSetupCompleted(bool completed); - - VoiceInteractionState voice_interaction_state() const { - return voice_interaction_state_; - } - - bool voice_interaction_settings_enabled() const { - return voice_interaction_settings_enabled_; - } - - bool voice_interaction_setup_completed() const { - return voice_interaction_setup_completed_; - } - private: FRIEND_TEST_ALL_PREFIXES(ExtendedDesktopTest, TestCursor); FRIEND_TEST_ALL_PREFIXES(WindowManagerTest, MouseEventCursors); @@ -695,6 +675,7 @@ std::unique_ptr<ToastManager> toast_manager_; std::unique_ptr<TouchDevicesController> touch_devices_controller_; std::unique_ptr<TrayAction> tray_action_; + std::unique_ptr<VoiceInteractionController> voice_interaction_controller_; std::unique_ptr<VpnList> vpn_list_; std::unique_ptr<WallpaperController> wallpaper_controller_; std::unique_ptr<WallpaperDelegate> wallpaper_delegate_; @@ -799,21 +780,6 @@ // hide the cursor on Windows. std::unique_ptr<::wm::CursorManager> cursor_manager_; - // Cached state and flags related to voice interaction. - // TODO(updowndota) Move the cached voice interaction flags into a separate - // controller after the controller is added (crbug.com/758650). - - // Voice interaction state. The intial value should be set to STOPPED to make - // sure the burst animation could be correctly shown. - VoiceInteractionState voice_interaction_state_ = - VoiceInteractionState::STOPPED; - - // Whether voice interaction is enabled in system settings. - bool voice_interaction_settings_enabled_ = false; - - // Whether voice intearction setup flow has completed. - bool voice_interaction_setup_completed_ = false; - // For testing only: simulate that a modal window is open bool simulate_modal_window_open_for_testing_;
diff --git a/ash/shell_observer.h b/ash/shell_observer.h index ed2935c..a283519 100644 --- a/ash/shell_observer.h +++ b/ash/shell_observer.h
@@ -16,8 +16,6 @@ namespace ash { -enum class VoiceInteractionState; - class ASH_EXPORT ShellObserver { public: // Called when the AppList is shown or dismissed. @@ -70,21 +68,6 @@ // Called when a new KeyboardController is created. virtual void OnKeyboardControllerCreated() {} - // TODO(kaznacheev) Move voice interaction related methods to a separate - // observer (crbug.com/758650) - // Called when voice interaction session state changes. - virtual void OnVoiceInteractionStatusChanged(VoiceInteractionState state) {} - - // Called when voice interaction is enabled/disabled. - virtual void OnVoiceInteractionEnabled(bool enabled) {} - - // Called when voice interaction service is allowed/disallowed to access - // the "context" (text and graphic content that is currently on screen). - virtual void OnVoiceInteractionContextEnabled(bool enabled) {} - - // Called when voice interaction setup flow completed. - virtual void OnVoiceInteractionSetupCompleted() {} - // Called at the end of Shell::Init. virtual void OnShellInitialized() {}
diff --git a/ash/system/palette/palette_tray_unittest.cc b/ash/system/palette/palette_tray_unittest.cc index bf485860..e7b4da2 100644 --- a/ash/system/palette/palette_tray_unittest.cc +++ b/ash/system/palette/palette_tray_unittest.cc
@@ -12,7 +12,7 @@ #include "ash/public/cpp/ash_switches.h" #include "ash/public/cpp/config.h" #include "ash/public/cpp/stylus_utils.h" -#include "ash/public/cpp/voice_interaction_state.h" +#include "ash/public/interfaces/voice_interaction_controller.mojom.h" #include "ash/session/session_controller.h" #include "ash/session/test_session_controller_client.h" #include "ash/shell.h" @@ -25,6 +25,7 @@ #include "ash/test/ash_test_base.h" #include "ash/test/ash_test_helper.h" #include "ash/test_shell_delegate.h" +#include "ash/voice_interaction/voice_interaction_controller.h" #include "base/command_line.h" #include "base/memory/ptr_util.h" #include "base/test/simple_test_tick_clock.h" @@ -329,10 +330,10 @@ } TEST_F(PaletteTrayTestWithVoiceInteraction, MetalayerToolActivatesHighlighter) { - Shell::Get()->NotifyVoiceInteractionStatusChanged( - VoiceInteractionState::RUNNING); - Shell::Get()->NotifyVoiceInteractionEnabled(true); - Shell::Get()->NotifyVoiceInteractionContextEnabled(true); + Shell::Get()->voice_interaction_controller()->NotifyStatusChanged( + mojom::VoiceInteractionState::RUNNING); + Shell::Get()->voice_interaction_controller()->NotifySettingsEnabled(true); + Shell::Get()->voice_interaction_controller()->NotifyContextEnabled(true); ui::test::EventGenerator& generator = GetEventGenerator(); generator.EnterPenPointerMode(); @@ -394,7 +395,7 @@ // Disabling metalayer support in the delegate should disable the palette // tool. test_api_->palette_tool_manager()->ActivateTool(PaletteToolId::METALAYER); - Shell::Get()->NotifyVoiceInteractionContextEnabled(false); + Shell::Get()->voice_interaction_controller()->NotifyContextEnabled(false); EXPECT_FALSE(metalayer_enabled()); // With the metalayer disabled again, press/drag does not activate the @@ -406,10 +407,10 @@ TEST_F(PaletteTrayTestWithVoiceInteraction, StylusBarrelButtonActivatesHighlighter) { - Shell::Get()->NotifyVoiceInteractionStatusChanged( - VoiceInteractionState::NOT_READY); - Shell::Get()->NotifyVoiceInteractionEnabled(false); - Shell::Get()->NotifyVoiceInteractionContextEnabled(false); + Shell::Get()->voice_interaction_controller()->NotifyStatusChanged( + mojom::VoiceInteractionState::NOT_READY); + Shell::Get()->voice_interaction_controller()->NotifySettingsEnabled(false); + Shell::Get()->voice_interaction_controller()->NotifyContextEnabled(false); ui::test::EventGenerator& generator = GetEventGenerator(); generator.EnterPenPointerMode(); @@ -429,20 +430,20 @@ false /* no highlighter on press */); // Enable one of the two user prefs, should not be sufficient. - Shell::Get()->NotifyVoiceInteractionContextEnabled(true); + Shell::Get()->voice_interaction_controller()->NotifyContextEnabled(true); WaitDragAndAssertMetalayer("one pref enabled", origin, ui::EF_LEFT_MOUSE_BUTTON, false /* no metalayer */, false /* no highlighter on press */); // Enable the other user pref, still not sufficient. - Shell::Get()->NotifyVoiceInteractionEnabled(true); + Shell::Get()->voice_interaction_controller()->NotifySettingsEnabled(true); WaitDragAndAssertMetalayer("two prefs enabled", origin, ui::EF_LEFT_MOUSE_BUTTON, false /* no metalayer */, false /* no highlighter on press */); // Once the service is ready, the button should start working. - Shell::Get()->NotifyVoiceInteractionStatusChanged( - VoiceInteractionState::RUNNING); + Shell::Get()->voice_interaction_controller()->NotifyStatusChanged( + mojom::VoiceInteractionState::RUNNING); // Press and drag with no button, still no highlighter. WaitDragAndAssertMetalayer("all enabled, no button ", origin, ui::EF_NONE, @@ -506,7 +507,7 @@ // Disable the metalayer support. // This should deactivate both the palette tool and the highlighter. - Shell::Get()->NotifyVoiceInteractionContextEnabled(false); + Shell::Get()->voice_interaction_controller()->NotifyContextEnabled(false); EXPECT_FALSE(test_api_->palette_tool_manager()->IsToolActive( PaletteToolId::METALAYER));
diff --git a/ash/system/palette/tools/metalayer_mode.cc b/ash/system/palette/tools/metalayer_mode.cc index 13e6dbb1..1d71e01 100644 --- a/ash/system/palette/tools/metalayer_mode.cc +++ b/ash/system/palette/tools/metalayer_mode.cc
@@ -14,6 +14,7 @@ #include "ash/system/toast/toast_manager.h" #include "ash/system/tray/hover_highlight_view.h" #include "ash/system/tray/tray_constants.h" +#include "ash/voice_interaction/voice_interaction_controller.h" #include "ui/base/l10n/l10n_util.h" #include "ui/events/event.h" #include "ui/gfx/paint_vector_icon.h" @@ -37,11 +38,11 @@ MetalayerMode::MetalayerMode(Delegate* delegate) : CommonPaletteTool(delegate), weak_factory_(this) { Shell::Get()->AddPreTargetHandler(this); - Shell::Get()->AddShellObserver(this); + Shell::Get()->voice_interaction_controller()->AddObserver(this); } MetalayerMode::~MetalayerMode() { - Shell::Get()->RemoveShellObserver(this); + Shell::Get()->voice_interaction_controller()->RemoveObserver(this); Shell::Get()->RemovePreTargetHandler(this); } @@ -141,12 +142,12 @@ } void MetalayerMode::OnVoiceInteractionStatusChanged( - VoiceInteractionState state) { + mojom::VoiceInteractionState state) { voice_interaction_state_ = state; UpdateState(); } -void MetalayerMode::OnVoiceInteractionEnabled(bool enabled) { +void MetalayerMode::OnVoiceInteractionSettingsEnabled(bool enabled) { voice_interaction_enabled_ = enabled; UpdateState(); }
diff --git a/ash/system/palette/tools/metalayer_mode.h b/ash/system/palette/tools/metalayer_mode.h index d43dd8f..581d3a04 100644 --- a/ash/system/palette/tools/metalayer_mode.h +++ b/ash/system/palette/tools/metalayer_mode.h
@@ -6,9 +6,9 @@ #define ASH_SYSTEM_PALETTE_TOOLS_METALAYER_MODE_H_ #include "ash/ash_export.h" -#include "ash/public/cpp/voice_interaction_state.h" -#include "ash/shell_observer.h" +#include "ash/public/interfaces/voice_interaction_controller.mojom.h" #include "ash/system/palette/common_palette_tool.h" +#include "ash/voice_interaction/voice_interaction_observer.h" #include "base/memory/weak_ptr.h" #include "ui/events/event_handler.h" @@ -21,7 +21,7 @@ // menu, but also by the stylus button click. class ASH_EXPORT MetalayerMode : public CommonPaletteTool, public ui::EventHandler, - public ShellObserver { + public VoiceInteractionObserver { public: explicit MetalayerMode(Delegate* delegate); ~MetalayerMode() override; @@ -37,14 +37,14 @@ // Whether the tool is in "loading" state. bool loading() const { return feature_enabled() && - voice_interaction_state_ == VoiceInteractionState::NOT_READY; + voice_interaction_state_ == mojom::VoiceInteractionState::NOT_READY; } // Whether the tool can be selected from the menu (only true when enabled // by the user and fully loaded). bool selectable() const { return feature_enabled() && - voice_interaction_state_ != VoiceInteractionState::NOT_READY; + voice_interaction_state_ != mojom::VoiceInteractionState::NOT_READY; } // PaletteTool: @@ -61,10 +61,10 @@ // ui::EventHandler: void OnTouchEvent(ui::TouchEvent* event) override; - // ShellObserver: + // VoiceInteractionObserver: void OnVoiceInteractionStatusChanged( - ash::VoiceInteractionState state) override; - void OnVoiceInteractionEnabled(bool enabled) override; + mojom::VoiceInteractionState state) override; + void OnVoiceInteractionSettingsEnabled(bool enabled) override; void OnVoiceInteractionContextEnabled(bool enabled) override; // Update the state of the tool based on the current availability of the tool. @@ -76,8 +76,8 @@ // Called when the metalayer session is complete. void OnMetalayerSessionComplete(); - ash::VoiceInteractionState voice_interaction_state_ = - ash::VoiceInteractionState::NOT_READY; + mojom::VoiceInteractionState voice_interaction_state_ = + mojom::VoiceInteractionState::NOT_READY; bool voice_interaction_enabled_ = false;
diff --git a/ash/system/palette/tools/metalayer_unittest.cc b/ash/system/palette/tools/metalayer_unittest.cc index 367480a..c6954f1 100644 --- a/ash/system/palette/tools/metalayer_unittest.cc +++ b/ash/system/palette/tools/metalayer_unittest.cc
@@ -6,6 +6,7 @@ #include "ash/highlighter/highlighter_controller.h" #include "ash/highlighter/highlighter_controller_test_api.h" +#include "ash/public/interfaces/voice_interaction_controller.mojom.h" #include "ash/shell.h" #include "ash/shell_test_api.h" #include "ash/system/palette/mock_palette_tool_delegate.h" @@ -14,6 +15,7 @@ #include "ash/system/palette/tools/metalayer_mode.h" #include "ash/system/tray/hover_highlight_view.h" #include "ash/test/ash_test_base.h" +#include "ash/voice_interaction/voice_interaction_controller.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" @@ -61,21 +63,25 @@ // The metalayer tool is always visible, but only enabled when the user // has enabled the metalayer AND the voice interaction framework is ready. TEST_F(MetalayerToolTest, PaletteMenuState) { - const VoiceInteractionState kStates[] = {VoiceInteractionState::NOT_READY, - VoiceInteractionState::STOPPED, - VoiceInteractionState::RUNNING}; + const mojom::VoiceInteractionState kStates[] = { + mojom::VoiceInteractionState::NOT_READY, + mojom::VoiceInteractionState::STOPPED, + mojom::VoiceInteractionState::RUNNING}; const base::string16 kLoading(base::ASCIIToUTF16("loading")); // Iterate over every possible combination of states. - for (VoiceInteractionState state : kStates) { + for (mojom::VoiceInteractionState state : kStates) { for (int enabled = 0; enabled <= 1; enabled++) { for (int context = 0; context <= 1; context++) { - const bool ready = state != VoiceInteractionState::NOT_READY; + const bool ready = state != mojom::VoiceInteractionState::NOT_READY; const bool selectable = enabled && context && ready; - Shell::Get()->NotifyVoiceInteractionStatusChanged(state); - Shell::Get()->NotifyVoiceInteractionEnabled(enabled); - Shell::Get()->NotifyVoiceInteractionContextEnabled(context); + Shell::Get()->voice_interaction_controller()->NotifyStatusChanged( + state); + Shell::Get()->voice_interaction_controller()->NotifySettingsEnabled( + enabled); + Shell::Get()->voice_interaction_controller()->NotifyContextEnabled( + context); std::unique_ptr<views::View> view = base::WrapUnique(tool_->CreateView()); @@ -117,25 +123,25 @@ // Verifies that disabling the metalayer support disables the tool. TEST_F(MetalayerToolTest, MetalayerUnsupportedDisablesPaletteTool) { - Shell::Get()->NotifyVoiceInteractionStatusChanged( - VoiceInteractionState::RUNNING); - Shell::Get()->NotifyVoiceInteractionEnabled(true); - Shell::Get()->NotifyVoiceInteractionContextEnabled(true); + Shell::Get()->voice_interaction_controller()->NotifyStatusChanged( + mojom::VoiceInteractionState::RUNNING); + Shell::Get()->voice_interaction_controller()->NotifySettingsEnabled(true); + Shell::Get()->voice_interaction_controller()->NotifyContextEnabled(true); // Disabling the user prefs individually should disable the tool. tool_->OnEnable(); EXPECT_CALL(*palette_tool_delegate_.get(), DisableTool(PaletteToolId::METALAYER)); - Shell::Get()->NotifyVoiceInteractionEnabled(false); + Shell::Get()->voice_interaction_controller()->NotifySettingsEnabled(false); testing::Mock::VerifyAndClearExpectations(palette_tool_delegate_.get()); - Shell::Get()->NotifyVoiceInteractionEnabled(true); + Shell::Get()->voice_interaction_controller()->NotifySettingsEnabled(true); tool_->OnEnable(); EXPECT_CALL(*palette_tool_delegate_.get(), DisableTool(PaletteToolId::METALAYER)); - Shell::Get()->NotifyVoiceInteractionContextEnabled(false); + Shell::Get()->voice_interaction_controller()->NotifyContextEnabled(false); testing::Mock::VerifyAndClearExpectations(palette_tool_delegate_.get()); - Shell::Get()->NotifyVoiceInteractionContextEnabled(true); + Shell::Get()->voice_interaction_controller()->NotifyContextEnabled(true); // Test VoiceInteractionState changes. tool_->OnEnable(); @@ -145,17 +151,17 @@ EXPECT_CALL(*palette_tool_delegate_.get(), DisableTool(PaletteToolId::METALAYER)) .Times(0); - Shell::Get()->NotifyVoiceInteractionStatusChanged( - VoiceInteractionState::STOPPED); - Shell::Get()->NotifyVoiceInteractionStatusChanged( - VoiceInteractionState::RUNNING); + Shell::Get()->voice_interaction_controller()->NotifyStatusChanged( + mojom::VoiceInteractionState::STOPPED); + Shell::Get()->voice_interaction_controller()->NotifyStatusChanged( + mojom::VoiceInteractionState::RUNNING); testing::Mock::VerifyAndClearExpectations(palette_tool_delegate_.get()); // Changing the state to NOT_READY should disable the tool. EXPECT_CALL(*palette_tool_delegate_.get(), DisableTool(PaletteToolId::METALAYER)); - Shell::Get()->NotifyVoiceInteractionStatusChanged( - VoiceInteractionState::NOT_READY); + Shell::Get()->voice_interaction_controller()->NotifyStatusChanged( + mojom::VoiceInteractionState::NOT_READY); testing::Mock::VerifyAndClearExpectations(palette_tool_delegate_.get()); }
diff --git a/ash/voice_interaction/OWNERS b/ash/voice_interaction/OWNERS new file mode 100644 index 0000000..bb65116 --- /dev/null +++ b/ash/voice_interaction/OWNERS
@@ -0,0 +1,2 @@ +per-file *_struct_traits*.*=set noparent +per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/ash/voice_interaction/voice_interaction_controller.cc b/ash/voice_interaction/voice_interaction_controller.cc new file mode 100644 index 0000000..cac4ac81 --- /dev/null +++ b/ash/voice_interaction/voice_interaction_controller.cc
@@ -0,0 +1,52 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/voice_interaction/voice_interaction_controller.h" + +namespace ash { + +VoiceInteractionController::VoiceInteractionController() : binding_(this) {} + +VoiceInteractionController::~VoiceInteractionController() {} + +void VoiceInteractionController::BindRequest( + mojom::VoiceInteractionControllerRequest request) { + binding_.Bind(std::move(request)); +} + +void VoiceInteractionController::AddObserver( + VoiceInteractionObserver* observer) { + observers_.AddObserver(observer); +} + +void VoiceInteractionController::RemoveObserver( + VoiceInteractionObserver* observer) { + observers_.RemoveObserver(observer); +} + +void VoiceInteractionController::NotifyStatusChanged( + mojom::VoiceInteractionState state) { + voice_interaction_state_ = state; + for (auto& observer : observers_) + observer.OnVoiceInteractionStatusChanged(state); +} + +void VoiceInteractionController::NotifySettingsEnabled(bool enabled) { + settings_enabled_ = enabled; + for (auto& observer : observers_) + observer.OnVoiceInteractionSettingsEnabled(enabled); +} + +void VoiceInteractionController::NotifyContextEnabled(bool enabled) { + for (auto& observer : observers_) + observer.OnVoiceInteractionContextEnabled(enabled); +} + +void VoiceInteractionController::NotifySetupCompleted(bool completed) { + setup_completed_ = completed; + for (auto& observer : observers_) + observer.OnVoiceInteractionSetupCompleted(completed); +} + +} // namespace ash
diff --git a/ash/voice_interaction/voice_interaction_controller.h b/ash/voice_interaction/voice_interaction_controller.h new file mode 100644 index 0000000..c8f593f --- /dev/null +++ b/ash/voice_interaction/voice_interaction_controller.h
@@ -0,0 +1,63 @@ +// 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 ASH_VOICE_INTERACTION_VOICE_INTERACTION_CONTROLLER_H_ +#define ASH_VOICE_INTERACTION_VOICE_INTERACTION_CONTROLLER_H_ + +#include <memory> + +#include "ash/ash_export.h" +#include "ash/public/interfaces/voice_interaction_controller.mojom.h" +#include "ash/voice_interaction/voice_interaction_observer.h" +#include "mojo/public/cpp/bindings/binding.h" + +namespace ash { + +class ASH_EXPORT VoiceInteractionController + : public mojom::VoiceInteractionController { + public: + VoiceInteractionController(); + ~VoiceInteractionController() override; + + void BindRequest(mojom::VoiceInteractionControllerRequest request); + + void AddObserver(VoiceInteractionObserver* observer); + void RemoveObserver(VoiceInteractionObserver* observer); + + // ash::mojom::VoiceInteractionController: + void NotifyStatusChanged(mojom::VoiceInteractionState state) override; + void NotifySettingsEnabled(bool enabled) override; + void NotifyContextEnabled(bool enabled) override; + void NotifySetupCompleted(bool completed) override; + + mojom::VoiceInteractionState voice_interaction_state() const { + return voice_interaction_state_; + } + + bool settings_enabled() const { return settings_enabled_; } + + bool setup_completed() const { return setup_completed_; } + + private: + // Voice interaction state. The initial value should be set to STOPPED to make + // sure the app list button burst animation could be correctly shown. + mojom::VoiceInteractionState voice_interaction_state_ = + mojom::VoiceInteractionState::STOPPED; + + // Whether voice interaction is enabled in system settings. + bool settings_enabled_ = false; + + // Whether voice intearction setup flow has completed. + bool setup_completed_ = false; + + base::ObserverList<VoiceInteractionObserver> observers_; + + mojo::Binding<mojom::VoiceInteractionController> binding_; + + DISALLOW_COPY_AND_ASSIGN(VoiceInteractionController); +}; + +} // namespace ash + +#endif // ASH_VOICE_INTERACTION_VOICE_INTERACTION_CONTROLLER_H_
diff --git a/ash/voice_interaction/voice_interaction_controller_unittest.cc b/ash/voice_interaction/voice_interaction_controller_unittest.cc new file mode 100644 index 0000000..fe84a5b --- /dev/null +++ b/ash/voice_interaction/voice_interaction_controller_unittest.cc
@@ -0,0 +1,118 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/voice_interaction/voice_interaction_controller.h" + +#include <memory> + +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "ash/voice_interaction/voice_interaction_observer.h" + +namespace ash { +namespace { + +class TestVoiceInteractionObserver : public VoiceInteractionObserver { + public: + TestVoiceInteractionObserver() = default; + ~TestVoiceInteractionObserver() override = default; + + // VoiceInteractionObserver overrides: + void OnVoiceInteractionStatusChanged( + mojom::VoiceInteractionState state) override { + state_ = state; + } + void OnVoiceInteractionSettingsEnabled(bool enabled) override { + settings_enabled_ = enabled; + } + void OnVoiceInteractionContextEnabled(bool enabled) override { + context_enabled_ = enabled; + } + void OnVoiceInteractionSetupCompleted(bool completed) override { + setup_completed_ = completed; + } + + mojom::VoiceInteractionState voice_interaction_state() const { + return state_; + } + bool settings_enabled() const { return settings_enabled_; } + bool context_enabled() const { return context_enabled_; } + bool setup_completed() const { return setup_completed_; } + + private: + mojom::VoiceInteractionState state_ = mojom::VoiceInteractionState::STOPPED; + bool settings_enabled_ = false; + bool context_enabled_ = false; + bool setup_completed_ = false; + + DISALLOW_COPY_AND_ASSIGN(TestVoiceInteractionObserver); +}; + +class VoiceInteractionControllerTest : public AshTestBase { + public: + VoiceInteractionControllerTest() {} + ~VoiceInteractionControllerTest() override {} + + void SetUp() override { + AshTestBase::SetUp(); + + observer_ = std::make_unique<TestVoiceInteractionObserver>(); + controller()->AddObserver(observer_.get()); + } + + void TearDown() override { + controller()->RemoveObserver(observer_.get()); + observer_.reset(); + + AshTestBase::TearDown(); + } + + protected: + VoiceInteractionController* controller() { + return Shell::Get()->voice_interaction_controller(); + } + + TestVoiceInteractionObserver* observer() { return observer_.get(); } + + private: + std::unique_ptr<TestVoiceInteractionObserver> observer_; + + DISALLOW_COPY_AND_ASSIGN(VoiceInteractionControllerTest); +}; + +} // namespace + +TEST_F(VoiceInteractionControllerTest, NotifyStatusChanged) { + controller()->NotifyStatusChanged(mojom::VoiceInteractionState::RUNNING); + // The cached state should be updated. + EXPECT_EQ(mojom::VoiceInteractionState::RUNNING, + controller()->voice_interaction_state()); + // The observers should be notified. + EXPECT_EQ(mojom::VoiceInteractionState::RUNNING, + observer()->voice_interaction_state()); +} + +TEST_F(VoiceInteractionControllerTest, NotifySettingsEnabled) { + controller()->NotifySettingsEnabled(true); + // The cached state should be updated. + EXPECT_TRUE(controller()->settings_enabled()); + // The observers should be notified. + EXPECT_TRUE(observer()->settings_enabled()); +} + +TEST_F(VoiceInteractionControllerTest, NotifyContextEnabled) { + controller()->NotifyContextEnabled(true); + // The observers should be notified. + EXPECT_TRUE(observer()->context_enabled()); +} + +TEST_F(VoiceInteractionControllerTest, NotifySetupCompleted) { + controller()->NotifySetupCompleted(true); + // The cached state should be updated. + EXPECT_TRUE(controller()->setup_completed()); + // The observers should be notified. + EXPECT_TRUE(observer()->setup_completed()); +} + +} // namespace ash
diff --git a/ash/voice_interaction/voice_interaction_observer.h b/ash/voice_interaction/voice_interaction_observer.h new file mode 100644 index 0000000..fb6711e --- /dev/null +++ b/ash/voice_interaction/voice_interaction_observer.h
@@ -0,0 +1,38 @@ +// 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 ASH_VOICE_INTERACTION_VOICE_INTERACTION_OBSERVER_H_ +#define ASH_VOICE_INTERACTION_VOICE_INTERACTION_OBSERVER_H_ + +namespace ash { + +namespace mojom { + +enum class VoiceInteractionState; + +} // namespace mojom + +class VoiceInteractionObserver { + public: + // Called when voice interaction session state changes. + virtual void OnVoiceInteractionStatusChanged( + mojom::VoiceInteractionState state) {} + + // Called when voice interaction is enabled/disabled in settings. + virtual void OnVoiceInteractionSettingsEnabled(bool enabled) {} + + // Called when voice interaction service is allowed/disallowed to access + // the "context" (text and graphic content that is currently on screen). + virtual void OnVoiceInteractionContextEnabled(bool enabled) {} + + // Called when voice interaction setup flow completed. + virtual void OnVoiceInteractionSetupCompleted(bool completed) {} + + protected: + virtual ~VoiceInteractionObserver() = default; +}; + +} // namespace ash + +#endif // ASH_VOICE_INTERACTION_VOICE_INTERACTION_OBSERVER_H_
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index d66be26..ca34d83 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -531,4 +531,10 @@ <!-- Reader Mode dimensions --> <!-- Padding surrounding the message. --> <dimen name="reader_mode_infobar_text_padding">8dp</dimen> + + <!-- Defaults for TabbedModeFirstRunActivity values. --> + <item type="dimen" name="dialog_fixed_width_major">100%</item> + <item type="dimen" name="dialog_fixed_width_minor">100%</item> + <item type="dimen" name="dialog_fixed_height_major">100%</item> + <item type="dimen" name="dialog_fixed_height_minor">100%</item> </resources>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/TabbedModeFirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/TabbedModeFirstRunActivity.java index 08258096..371d11db 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/TabbedModeFirstRunActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/TabbedModeFirstRunActivity.java
@@ -5,6 +5,8 @@ package org.chromium.chrome.browser.firstrun; import android.content.Context; +import android.content.res.Resources; +import android.support.annotation.AnyRes; import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.Gravity; @@ -59,6 +61,19 @@ fetchConstraints(); } + /** + * Wrapper around Resources.getValue() that translates Resources.NotFoundException + * into false return value. Otherwise the function returns true. + */ + private boolean safeGetResourceValue(@AnyRes int id, TypedValue value) { + try { + getContext().getResources().getValue(id, value, true); + return true; + } catch (Resources.NotFoundException e) { + return false; + } + } + private void fetchConstraints() { // Fetch size constraints. These are copies of corresponding abc_* AppCompat values, // because abc_* values are private, and even though corresponding theme attributes @@ -67,14 +82,10 @@ // system DialogWhenLarge theme. // Note that we don't care about the return values, because onMeasure() handles null // constraints (and they will be null when the device is not considered "large"). - getContext().getResources().getValue( - R.dimen.dialog_fixed_width_minor, mFixedWidthMinor, true); - getContext().getResources().getValue( - R.dimen.dialog_fixed_width_major, mFixedWidthMajor, true); - getContext().getResources().getValue( - R.dimen.dialog_fixed_height_minor, mFixedHeightMinor, true); - getContext().getResources().getValue( - R.dimen.dialog_fixed_height_major, mFixedHeightMajor, true); + safeGetResourceValue(R.dimen.dialog_fixed_width_minor, mFixedWidthMinor); + safeGetResourceValue(R.dimen.dialog_fixed_width_major, mFixedWidthMajor); + safeGetResourceValue(R.dimen.dialog_fixed_height_minor, mFixedHeightMinor); + safeGetResourceValue(R.dimen.dialog_fixed_height_major, mFixedHeightMajor); } @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java index c7e25758..fcc6e854 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java
@@ -140,10 +140,13 @@ final ActivityMonitor activityMonitor = new ActivityMonitor(asyncClassName, null, false); final ActivityMonitor freMonitor = new ActivityMonitor(FirstRunActivity.class.getName(), null, false); + final ActivityMonitor tabbedFREMonitor = + new ActivityMonitor(TabbedModeFirstRunActivity.class.getName(), null, false); Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); instrumentation.addMonitor(activityMonitor); instrumentation.addMonitor(freMonitor); + instrumentation.addMonitor(tabbedFREMonitor); runnable.run(); // The original activity should be started because it was directly specified. @@ -163,7 +166,7 @@ CriteriaHelper.pollInstrumentationThread(new Criteria() { @Override public boolean isSatisfied() { - return freMonitor.getHits() == 1; + return freMonitor.getHits() == 1 || tabbedFREMonitor.getHits() == 1; } }); }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 7d7c907..4ff70bd 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -460,8 +460,6 @@ "font_pref_change_notifier.h", "font_pref_change_notifier_factory.cc", "font_pref_change_notifier_factory.h", - "fullscreen.h", - "fullscreen_chromeos.cc", "fullscreen_mac.mm", "fullscreen_win.cc", "gcm/gcm_product_util.cc", @@ -2766,6 +2764,7 @@ } } else { # Non-ChromeOS. sources += [ + "fullscreen.h", "policy/cloud/user_cloud_policy_manager_factory.cc", "policy/cloud/user_cloud_policy_manager_factory.h", "policy/cloud/user_policy_signin_service_base.cc",
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 72f45afa..b74bd89 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -433,6 +433,8 @@ "arc/voice_interaction/arc_voice_interaction_framework_service.h", "arc/voice_interaction/highlighter_controller_client.cc", "arc/voice_interaction/highlighter_controller_client.h", + "arc/voice_interaction/voice_interaction_controller_client.cc", + "arc/voice_interaction/voice_interaction_controller_client.h", "arc/wallpaper/arc_wallpaper_service.cc", "arc/wallpaper/arc_wallpaper_service.h", "ash_config.cc",
diff --git a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc index 6555aa33..cc0d10ba 100644 --- a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc +++ b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc
@@ -23,6 +23,7 @@ #include "base/task_scheduler/post_task.h" #include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h" #include "chrome/browser/chromeos/arc/voice_interaction/highlighter_controller_client.h" +#include "chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.h" #include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/login/helper.h" #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" @@ -55,6 +56,32 @@ #include "ui/wm/core/window_util.h" #include "ui/wm/public/activation_client.h" +namespace mojo { + +// Map VoiceInteractionState from arc::mojom into ash::mojom. The duplicate +// definition is because we do not want to use extensible widely. +// (crbug.com/731893). +template <> +struct TypeConverter<ash::mojom::VoiceInteractionState, + arc::mojom::VoiceInteractionState> { + static ash::mojom::VoiceInteractionState Convert( + arc::mojom::VoiceInteractionState state) { + switch (state) { + case arc::mojom::VoiceInteractionState::NOT_READY: + return ash::mojom::VoiceInteractionState::NOT_READY; + case arc::mojom::VoiceInteractionState::STOPPED: + return ash::mojom::VoiceInteractionState::STOPPED; + case arc::mojom::VoiceInteractionState::RUNNING: + return ash::mojom::VoiceInteractionState::RUNNING; + } + + NOTREACHED() << "Invalid state: " << static_cast<int>(state); + return ash::mojom::VoiceInteractionState::NOT_READY; + } +}; + +} // namespace mojo + namespace arc { namespace { @@ -200,6 +227,8 @@ arc_bridge_service_(bridge_service), binding_(this), highlighter_client_(std::make_unique<HighlighterControllerClient>(this)), + voice_interaction_controller_client_( + std::make_unique<VoiceInteractionControllerClient>()), weak_ptr_factory_(this) { arc_bridge_service_->voice_interaction_framework()->AddObserver(this); ArcSessionManager::Get()->AddObserver(this); @@ -275,13 +304,16 @@ } void ArcVoiceInteractionFrameworkService::SetVoiceInteractionState( - ash::VoiceInteractionState state) { + arc::mojom::VoiceInteractionState voice_interaction_state) { + ash::mojom::VoiceInteractionState state = + mojo::ConvertTo<ash::mojom::VoiceInteractionState>( + voice_interaction_state); DCHECK_NE(state_, state); // Assume voice interaction state changing from NOT_READY to a state other // than ready indicates container boot complete and it's safe to synchronize // voice interaction flags. VoiceInteractionEnabled is locked at true in // Android side so we don't need to synchronize it here. - if (state_ == ash::VoiceInteractionState::NOT_READY) { + if (state_ == ash::mojom::VoiceInteractionState::NOT_READY) { PrefService* prefs = Profile::FromBrowserContext(context_)->GetPrefs(); bool value_prop_accepted = prefs->GetBoolean(prefs::kArcVoiceInteractionValuePropAccepted); @@ -312,14 +344,11 @@ } // If voice session stopped running, we also stop the assist layer session. - if (state_ == ash::VoiceInteractionState::RUNNING) + if (state_ == ash::mojom::VoiceInteractionState::RUNNING) highlighter_client_->Exit(); state_ = state; - // TODO(crbug.com/757012): Mash support. - if (chromeos::GetAshConfig() == ash::Config::MASH) - return; - ash::Shell::Get()->NotifyVoiceInteractionStatusChanged(state); + voice_interaction_controller_client_->NotifyStatusChanged(state); } void ArcVoiceInteractionFrameworkService::OnMetalayerClosed() { @@ -365,20 +394,16 @@ if (session_state != session_manager::SessionState::ACTIVE) return; - // TODO(crbug.com/757012): Avoid using ash::Shell here so that it can work in - // mash. - if (chromeos::GetAshConfig() == ash::Config::MASH) - return; PrefService* prefs = Profile::FromBrowserContext(context_)->GetPrefs(); bool enabled = prefs->GetBoolean(prefs::kVoiceInteractionEnabled); - ash::Shell::Get()->NotifyVoiceInteractionEnabled(enabled); + voice_interaction_controller_client_->NotifySettingsEnabled(enabled); bool context = prefs->GetBoolean(prefs::kVoiceInteractionContextEnabled); - ash::Shell::Get()->NotifyVoiceInteractionContextEnabled(context); + voice_interaction_controller_client_->NotifyContextEnabled(context); bool setup_completed = prefs->GetBoolean(prefs::kArcVoiceInteractionValuePropAccepted); - ash::Shell::Get()->NotifyVoiceInteractionSetupCompleted(setup_completed); + voice_interaction_controller_client_->NotifySetupCompleted(setup_completed); // We only want notify the status change on first user signed in. session_manager::SessionManager::Get()->RemoveObserver(this); @@ -443,9 +468,7 @@ VoiceInteractionSettingCompleteCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - // TODO(crbug.com/757012): Mash support. - if (chromeos::GetAshConfig() != ash::Config::MASH) - ash::Shell::Get()->NotifyVoiceInteractionEnabled(enable); + voice_interaction_controller_client_->NotifySettingsEnabled(enable); PrefService* prefs = Profile::FromBrowserContext(context_)->GetPrefs(); @@ -469,9 +492,7 @@ bool enable) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - // TODO(crbug.com/757012): Mash support. - if (chromeos::GetAshConfig() != ash::Config::MASH) - ash::Shell::Get()->NotifyVoiceInteractionContextEnabled(enable); + voice_interaction_controller_client_->NotifyContextEnabled(enable); PrefService* prefs = Profile::FromBrowserContext(context_)->GetPrefs(); prefs->SetBoolean(prefs::kVoiceInteractionContextEnabled, enable); @@ -588,13 +609,10 @@ if (!prefs->GetBoolean(prefs::kVoiceInteractionEnabled)) return false; - if (state_ == ash::VoiceInteractionState::NOT_READY) { + if (state_ == ash::mojom::VoiceInteractionState::NOT_READY) { // If the container side is not ready, we will be waiting for a while. - // TODO(crbug.com/757012): Mash support. - if (chromeos::GetAshConfig() != ash::Config::MASH) { - ash::Shell::Get()->NotifyVoiceInteractionStatusChanged( - ash::VoiceInteractionState::NOT_READY); - } + voice_interaction_controller_client_->NotifyStatusChanged( + ash::mojom::VoiceInteractionState::NOT_READY); } ArcBootPhaseMonitorBridge::RecordFirstAppLaunchDelayUMA(context_); @@ -616,10 +634,7 @@ PrefService* prefs = Profile::FromBrowserContext(context_)->GetPrefs(); prefs->SetBoolean(prefs::kArcVoiceInteractionValuePropAccepted, completed); - // TODO(crbug.com/757012): Mash support. - if (chromeos::GetAshConfig() == ash::Config::MASH) - return; - ash::Shell::Get()->NotifyVoiceInteractionSetupCompleted(completed); + voice_interaction_controller_client_->NotifySetupCompleted(completed); } bool ArcVoiceInteractionFrameworkService::IsHomescreenActive() {
diff --git a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.h b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.h index 042a5c0..0f8ae7e 100644 --- a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.h +++ b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.h
@@ -7,6 +7,7 @@ #include <memory> +#include "ash/public/interfaces/voice_interaction_controller.mojom.h" #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -33,6 +34,7 @@ class ArcBridgeService; class HighlighterControllerClient; +class VoiceInteractionControllerClient; // This provides voice interaction context (currently screenshots) // to ARC to be used by VoiceInteractionSession. This class lives on the UI @@ -67,7 +69,8 @@ void OnMetalayerClosed() override; void SetMetalayerEnabled(bool enabled) override; void SetVoiceInteractionRunning(bool running) override; - void SetVoiceInteractionState(ash::VoiceInteractionState state) override; + void SetVoiceInteractionState( + arc::mojom::VoiceInteractionState state) override; void ShowMetalayer(); void HideMetalayer(); @@ -127,7 +130,14 @@ return highlighter_client_.get(); } - ash::VoiceInteractionState GetStateForTesting() const { return state_; } + ash::mojom::VoiceInteractionState GetStateForTesting() const { + return state_; + } + + VoiceInteractionControllerClient* + GetVoiceInteractionControllerClientForTesting() const { + return voice_interaction_controller_client_.get(); + } // For supporting ArcServiceManager::GetService<T>(). static const char kArcServiceName[]; @@ -160,7 +170,8 @@ // delay after boot before the service is ready. We wait for the container // to tell us if it is ready to quickly serve voice interaction requests. // We also give user proper feedback based on the state. - ash::VoiceInteractionState state_ = ash::VoiceInteractionState::NOT_READY; + ash::mojom::VoiceInteractionState state_ = + ash::mojom::VoiceInteractionState::NOT_READY; // The time when a user initated an interaction. base::TimeTicks user_interaction_start_time_; @@ -174,6 +185,9 @@ std::unique_ptr<HighlighterControllerClient> highlighter_client_; + std::unique_ptr<VoiceInteractionControllerClient> + voice_interaction_controller_client_; + base::WeakPtrFactory<ArcVoiceInteractionFrameworkService> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ArcVoiceInteractionFrameworkService);
diff --git a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service_unittest.cc b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service_unittest.cc index 19f2e2c..79e2196a 100644 --- a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service_unittest.cc +++ b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service_unittest.cc
@@ -14,6 +14,7 @@ #include "base/files/scoped_temp_dir.h" #include "chrome/browser/chromeos/arc/arc_session_manager.h" #include "chrome/browser/chromeos/arc/voice_interaction/highlighter_controller_client.h" +#include "chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.h" #include "chrome/test/base/testing_profile.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/fake_cras_audio_client.h" @@ -90,6 +91,57 @@ DISALLOW_COPY_AND_ASSIGN(TestHighlighterController); }; +class TestVoiceInteractionController + : public ash::mojom::VoiceInteractionController { + public: + TestVoiceInteractionController() : binding_(this) {} + ~TestVoiceInteractionController() override = default; + + ash::mojom::VoiceInteractionControllerPtr CreateInterfacePtrAndBind() { + ash::mojom::VoiceInteractionControllerPtr ptr; + binding_.Bind(mojo::MakeRequest(&ptr)); + return ptr; + } + + // ash::mojom::VoiceInteractionController: + void NotifyStatusChanged(ash::mojom::VoiceInteractionState state) override { + voice_interaction_state_ = state; + } + void NotifySettingsEnabled(bool enabled) override { + voice_interaction_settings_enabled_ = enabled; + } + void NotifyContextEnabled(bool enabled) override { + voice_interaction_context_enabled_ = enabled; + } + void NotifySetupCompleted(bool completed) override { + voice_interaction_setup_completed_ = completed; + } + + ash::mojom::VoiceInteractionState voice_interaction_state() const { + return voice_interaction_state_; + } + bool voice_interaction_settings_enabled() const { + return voice_interaction_settings_enabled_; + } + bool voice_interaction_context_enabled() const { + return voice_interaction_context_enabled_; + } + bool voice_interaction_setup_completed() const { + return voice_interaction_setup_completed_; + } + + private: + ash::mojom::VoiceInteractionState voice_interaction_state_ = + ash::mojom::VoiceInteractionState::STOPPED; + bool voice_interaction_settings_enabled_ = false; + bool voice_interaction_context_enabled_ = false; + bool voice_interaction_setup_completed_ = false; + + mojo::Binding<ash::mojom::VoiceInteractionController> binding_; + + DISALLOW_COPY_AND_ASSIGN(TestVoiceInteractionController); +}; + } // namespace class ArcVoiceInteractionFrameworkServiceTest : public ash::AshTestBase { @@ -115,6 +167,8 @@ auto highlighter_controller_ptr = std::make_unique<TestHighlighterController>(); highlighter_controller_ = highlighter_controller_ptr.get(); + voice_interaction_controller_ = + std::make_unique<TestVoiceInteractionController>(); connector_factory_ = std::make_unique<service_manager::TestConnectorFactory>( std::move(highlighter_controller_ptr)); @@ -123,6 +177,8 @@ profile_.get(), arc_bridge_service_.get()); framework_service_->GetHighlighterClientForTesting() ->SetConnectorForTesting(connector_.get()); + voice_interaction_controller_client()->SetControllerForTesting( + voice_interaction_controller_->CreateInterfacePtrAndBind()); framework_instance_ = std::make_unique<FakeVoiceInteractionFrameworkInstance>(); arc_bridge_service_->voice_interaction_framework()->SetInstance( @@ -132,6 +188,9 @@ FlushHighlighterControllerMojo(); framework_service()->SetVoiceInteractionSetupCompleted(); + // Flushing is required for the notify mojo call to get through to the voice + // interaction controller. + FlushVoiceInteractionControllerMojo(); } void TearDown() override { @@ -161,10 +220,22 @@ return highlighter_controller_; } + TestVoiceInteractionController* voice_interaction_controller() { + return voice_interaction_controller_.get(); + } + + VoiceInteractionControllerClient* voice_interaction_controller_client() { + return framework_service_->GetVoiceInteractionControllerClientForTesting(); + } + void FlushHighlighterControllerMojo() { framework_service_->GetHighlighterClientForTesting()->FlushMojoForTesting(); } + void FlushVoiceInteractionControllerMojo() { + voice_interaction_controller_client()->FlushMojoForTesting(); + } + private: base::ScopedTempDir temp_dir_; std::unique_ptr<TestingProfile> profile_; @@ -175,6 +246,7 @@ std::unique_ptr<service_manager::Connector> connector_; // |highlighter_controller_| is valid until |connector_factory_| is deleted. TestHighlighterController* highlighter_controller_; + std::unique_ptr<TestVoiceInteractionController> voice_interaction_controller_; std::unique_ptr<ArcVoiceInteractionFrameworkService> framework_service_; std::unique_ptr<FakeVoiceInteractionFrameworkInstance> framework_instance_; @@ -195,6 +267,10 @@ TEST_F(ArcVoiceInteractionFrameworkServiceTest, StartSession) { framework_service()->StartSessionFromUserInteraction(gfx::Rect()); + // A notification should be sent if the container is not ready yet. + FlushVoiceInteractionControllerMojo(); + EXPECT_EQ(ash::mojom::VoiceInteractionState::NOT_READY, + voice_interaction_controller()->voice_interaction_state()); // The signal to start voice interaction session should be sent. EXPECT_EQ(1u, framework_instance()->start_session_count()); } @@ -214,12 +290,20 @@ arc_bridge_service()->voice_interaction_framework()->SetInstance(nullptr); framework_service()->StartSessionFromUserInteraction(gfx::Rect()); + // A notification should be sent if the container is not ready yet. + FlushVoiceInteractionControllerMojo(); + EXPECT_EQ(ash::mojom::VoiceInteractionState::NOT_READY, + voice_interaction_controller()->voice_interaction_state()); // The signal should not be sent when framework instance not ready. EXPECT_EQ(0u, framework_instance()->start_session_count()); } TEST_F(ArcVoiceInteractionFrameworkServiceTest, ToggleSession) { framework_service()->ToggleSessionFromUserInteraction(); + // A notification should be sent if the container is not ready yet. + FlushVoiceInteractionControllerMojo(); + EXPECT_EQ(ash::mojom::VoiceInteractionState::NOT_READY, + voice_interaction_controller()->voice_interaction_state()); // The signal to toggle voice interaction session should be sent. EXPECT_EQ(1u, framework_instance()->toggle_session_count()); } @@ -304,16 +388,51 @@ framework_service()->ToggleSessionFromUserInteraction(); framework_instance()->FlushMojoForTesting(); FlushHighlighterControllerMojo(); - EXPECT_EQ(ash::VoiceInteractionState::RUNNING, + EXPECT_EQ(ash::mojom::VoiceInteractionState::RUNNING, framework_service()->GetStateForTesting()); framework_service()->ToggleSessionFromUserInteraction(); framework_instance()->FlushMojoForTesting(); FlushHighlighterControllerMojo(); - EXPECT_EQ(ash::VoiceInteractionState::STOPPED, + EXPECT_EQ(ash::mojom::VoiceInteractionState::STOPPED, framework_service()->GetStateForTesting()); EXPECT_FALSE(highlighter_controller()->is_enabled()); } +TEST_F(ArcVoiceInteractionFrameworkServiceTest, + VoiceInteractionControllerClient) { + TestVoiceInteractionController* controller = voice_interaction_controller(); + VoiceInteractionControllerClient* controller_client = + voice_interaction_controller_client(); + // The voice interaction flags should be set after the initial setup. + EXPECT_TRUE(controller->voice_interaction_settings_enabled()); + EXPECT_TRUE(controller->voice_interaction_context_enabled()); + EXPECT_TRUE(controller->voice_interaction_setup_completed()); + EXPECT_EQ(controller->voice_interaction_state(), + ash::mojom::VoiceInteractionState::STOPPED); + + // Send the signal to disable voice interaction settings. + controller_client->NotifySettingsEnabled(false); + FlushVoiceInteractionControllerMojo(); + EXPECT_FALSE(controller->voice_interaction_settings_enabled()); + + // Send the signal to disable voice interaction context. + controller_client->NotifyContextEnabled(false); + FlushVoiceInteractionControllerMojo(); + EXPECT_FALSE(controller->voice_interaction_context_enabled()); + + // Send the signal to disable the voice interaction setup completed flag. + controller_client->NotifySetupCompleted(false); + FlushVoiceInteractionControllerMojo(); + EXPECT_FALSE(controller->voice_interaction_setup_completed()); + + // Send the signal to set the voice interaction state. + controller_client->NotifyStatusChanged( + ash::mojom::VoiceInteractionState::RUNNING); + FlushVoiceInteractionControllerMojo(); + EXPECT_EQ(controller->voice_interaction_state(), + ash::mojom::VoiceInteractionState::RUNNING); +} + } // namespace arc
diff --git a/chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.cc b/chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.cc new file mode 100644 index 0000000..71e85a4 --- /dev/null +++ b/chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.cc
@@ -0,0 +1,58 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.h" + +#include "ash/public/interfaces/constants.mojom.h" +#include "content/public/common/service_manager_connection.h" +#include "services/service_manager/public/cpp/connector.h" + +namespace arc { + +VoiceInteractionControllerClient::VoiceInteractionControllerClient() { + ConnectToVoiceInteractionController(); +} + +VoiceInteractionControllerClient::~VoiceInteractionControllerClient() = default; + +void VoiceInteractionControllerClient::NotifyStatusChanged( + ash::mojom::VoiceInteractionState state) { + DCHECK(voice_interaction_controller_); + voice_interaction_controller_->NotifyStatusChanged(state); +} + +void VoiceInteractionControllerClient::NotifySettingsEnabled(bool enabled) { + DCHECK(voice_interaction_controller_); + voice_interaction_controller_->NotifySettingsEnabled(enabled); +} + +void VoiceInteractionControllerClient::NotifyContextEnabled(bool enabled) { + DCHECK(voice_interaction_controller_); + voice_interaction_controller_->NotifyContextEnabled(enabled); +} + +void VoiceInteractionControllerClient::NotifySetupCompleted(bool completed) { + DCHECK(voice_interaction_controller_); + voice_interaction_controller_->NotifySetupCompleted(completed); +} + +void VoiceInteractionControllerClient::SetControllerForTesting( + ash::mojom::VoiceInteractionControllerPtr controller) { + voice_interaction_controller_ = std::move(controller); +} + +void VoiceInteractionControllerClient::FlushMojoForTesting() { + voice_interaction_controller_.FlushForTesting(); +} + +void VoiceInteractionControllerClient::ConnectToVoiceInteractionController() { + content::ServiceManagerConnection* connection = + content::ServiceManagerConnection::GetForProcess(); + // Tests may bind to their own VoiceInteractionController later. + if (connection) + connection->GetConnector()->BindInterface(ash::mojom::kServiceName, + &voice_interaction_controller_); +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.h b/chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.h new file mode 100644 index 0000000..4f9cfd7 --- /dev/null +++ b/chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.h
@@ -0,0 +1,42 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ARC_VOICE_INTERACTION_VOICE_INTERACTION_CONTROLLER_CLIENT_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_VOICE_INTERACTION_VOICE_INTERACTION_CONTROLLER_CLIENT_H_ + +#include <memory> + +#include "ash/public/interfaces/voice_interaction_controller.mojom.h" + +namespace arc { + +// The client of VoiceInteractionController. Can be used to notify the +// controller on ash side about the changes of voice interaction flags. +class VoiceInteractionControllerClient { + public: + VoiceInteractionControllerClient(); + ~VoiceInteractionControllerClient(); + + // Notify the controller about state changes. + void NotifyStatusChanged(ash::mojom::VoiceInteractionState state); + void NotifySettingsEnabled(bool enabled); + void NotifyContextEnabled(bool enabled); + void NotifySetupCompleted(bool completed); + + // Testing methods. + void SetControllerForTesting( + ash::mojom::VoiceInteractionControllerPtr controller); + void FlushMojoForTesting(); + + private: + void ConnectToVoiceInteractionController(); + + ash::mojom::VoiceInteractionControllerPtr voice_interaction_controller_; + + DISALLOW_COPY_AND_ASSIGN(VoiceInteractionControllerClient); +}; + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_VOICE_INTERACTION_VOICE_INTERACTION_CONTROLLER_CLIENT_H_
diff --git a/chrome/browser/fullscreen.h b/chrome/browser/fullscreen.h index 71e2c5f..5738d7d76 100644 --- a/chrome/browser/fullscreen.h +++ b/chrome/browser/fullscreen.h
@@ -9,7 +9,8 @@ #include "build/build_config.h" -// |display_id| is used in OS_CHROMEOS build config only, ignored otherwise. -bool IsFullScreenMode(int64_t display_id); +// Safe to call from cross-platform code; implementation is different for each +// platform. Not implemented on Chrome OS. +bool IsFullScreenMode(); #endif // CHROME_BROWSER_FULLSCREEN_H_
diff --git a/chrome/browser/fullscreen_aurax11.cc b/chrome/browser/fullscreen_aurax11.cc index 2ceb01de..b186c00 100644 --- a/chrome/browser/fullscreen_aurax11.cc +++ b/chrome/browser/fullscreen_aurax11.cc
@@ -10,7 +10,7 @@ #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" #include "ui/views/widget/widget.h" -bool IsFullScreenMode(int64_t display_id) { +bool IsFullScreenMode() { std::vector<aura::Window*> all_windows = views::DesktopWindowTreeHostX11::GetAllOpenWindows(); // Only the topmost window is checked. This works fine in the most cases, but
diff --git a/chrome/browser/fullscreen_chromeos.cc b/chrome/browser/fullscreen_chromeos.cc deleted file mode 100644 index 8ceaecd4..0000000 --- a/chrome/browser/fullscreen_chromeos.cc +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/fullscreen.h" - -#include "ash/root_window_controller.h" -#include "ash/shell.h" -#include "chrome/browser/ui/ash/ash_util.h" -#include "ui/display/display.h" -#include "ui/display/screen.h" - -bool IsFullScreenMode(int64_t display_id) { - if (ash_util::IsRunningInMash()) { - // TODO: http://crbug.com/640390. - NOTIMPLEMENTED(); - return false; - } - - for (ash::RootWindowController* controller : - ash::Shell::Get()->GetAllRootWindowControllers()) { - if (display::Screen::GetScreen() - ->GetDisplayNearestWindow(controller->GetRootWindow()) - .id() == display_id) { - return controller && controller->GetWindowForFullscreenMode(); - } - } - - return false; -}
diff --git a/chrome/browser/fullscreen_mac.mm b/chrome/browser/fullscreen_mac.mm index 15fb90633..350ea688 100644 --- a/chrome/browser/fullscreen_mac.mm +++ b/chrome/browser/fullscreen_mac.mm
@@ -8,7 +8,7 @@ #include "base/command_line.h" -bool IsFullScreenMode(int64_t display_id) { +bool IsFullScreenMode() { NSApplicationPresentationOptions options = [NSApp currentSystemPresentationOptions];
diff --git a/chrome/browser/fullscreen_win.cc b/chrome/browser/fullscreen_win.cc index 0ebd703..88887651 100644 --- a/chrome/browser/fullscreen_win.cc +++ b/chrome/browser/fullscreen_win.cc
@@ -6,6 +6,6 @@ #include "ui/base/fullscreen_win.h" -bool IsFullScreenMode(int64_t display_id) { +bool IsFullScreenMode() { return ui::IsFullScreenMode(); }
diff --git a/chrome/browser/notifications/fullscreen_notification_blocker.cc b/chrome/browser/notifications/fullscreen_notification_blocker.cc index 37b2ba18..3d9fd64f 100644 --- a/chrome/browser/notifications/fullscreen_notification_blocker.cc +++ b/chrome/browser/notifications/fullscreen_notification_blocker.cc
@@ -9,7 +9,6 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/fullscreen.h" #include "content/public/browser/notification_service.h" -#include "ui/display/types/display_constants.h" #include "ui/message_center/notifier_settings.h" using message_center::NotifierId; @@ -27,7 +26,7 @@ void FullscreenNotificationBlocker::CheckState() { bool was_fullscreen_mode = is_fullscreen_mode_; - is_fullscreen_mode_ = IsFullScreenMode(display::kInvalidDisplayId); + is_fullscreen_mode_ = IsFullScreenMode(); if (is_fullscreen_mode_ != was_fullscreen_mode) NotifyBlockingStateChanged(); }
diff --git a/chrome/browser/resource_coordinator/tab_manager_grc_tab_signal_observer.cc b/chrome/browser/resource_coordinator/tab_manager_grc_tab_signal_observer.cc index 708381e..1e5987e 100644 --- a/chrome/browser/resource_coordinator/tab_manager_grc_tab_signal_observer.cc +++ b/chrome/browser/resource_coordinator/tab_manager_grc_tab_signal_observer.cc
@@ -55,33 +55,25 @@ TabManager::GRCTabSignalObserver::~GRCTabSignalObserver() = default; -void TabManager::GRCTabSignalObserver::OnEventReceived( - const CoordinationUnitID& cu_id, - mojom::TabEvent event) { - if (event == mojom::TabEvent::kDoneLoading) { - auto web_contents_iter = cu_id_web_contents_map_.find(cu_id); - if (web_contents_iter == cu_id_web_contents_map_.end()) - return; - auto* web_contents_data = - TabManager::WebContentsData::FromWebContents(web_contents_iter->second); - web_contents_data->DoneLoading(); - } +void TabManager::GRCTabSignalObserver::NotifyPageAlmostIdle( + const CoordinationUnitID& cu_id) { + auto web_contents_iter = cu_id_web_contents_map_.find(cu_id); + if (web_contents_iter == cu_id_web_contents_map_.end()) + return; + auto* web_contents_data = + TabManager::WebContentsData::FromWebContents(web_contents_iter->second); + web_contents_data->NotifyAlmostIdle(); } -void TabManager::GRCTabSignalObserver::OnPropertyChanged( +void TabManager::GRCTabSignalObserver::SetExpectedTaskQueueingDuration( const CoordinationUnitID& cu_id, - mojom::PropertyType property_type, - int64_t value) { - if (property_type == mojom::PropertyType::kExpectedTaskQueueingDuration) { - auto web_contents_iter = cu_id_web_contents_map_.find(cu_id); - if (web_contents_iter == cu_id_web_contents_map_.end()) - return; - g_browser_process->GetTabManager() - ->stats_collector() - ->RecordExpectedTaskQueueingDuration( - web_contents_iter->second, - base::TimeDelta::FromMilliseconds(value)); - } + base::TimeDelta duration) { + auto web_contents_iter = cu_id_web_contents_map_.find(cu_id); + if (web_contents_iter == cu_id_web_contents_map_.end()) + return; + g_browser_process->GetTabManager() + ->stats_collector() + ->RecordExpectedTaskQueueingDuration(web_contents_iter->second, duration); } void TabManager::GRCTabSignalObserver::
diff --git a/chrome/browser/resource_coordinator/tab_manager_grc_tab_signal_observer.h b/chrome/browser/resource_coordinator/tab_manager_grc_tab_signal_observer.h index 5d93e35..23183eb 100644 --- a/chrome/browser/resource_coordinator/tab_manager_grc_tab_signal_observer.h +++ b/chrome/browser/resource_coordinator/tab_manager_grc_tab_signal_observer.h
@@ -30,11 +30,9 @@ static GRCTabSignalObserver* GetInstance(); // mojom::TabSignalObserver implementation. - void OnEventReceived(const CoordinationUnitID& cu_id, - mojom::TabEvent event) override; - void OnPropertyChanged(const CoordinationUnitID& cu_id, - mojom::PropertyType property_type, - int64_t value) override; + void NotifyPageAlmostIdle(const CoordinationUnitID& cu_id) override; + void SetExpectedTaskQueueingDuration(const CoordinationUnitID& cu_id, + base::TimeDelta duration) override; void AssociateCoordinationUnitIDWithWebContents( const CoordinationUnitID& cu_id,
diff --git a/chrome/browser/resource_coordinator/tab_manager_web_contents_data.h b/chrome/browser/resource_coordinator/tab_manager_web_contents_data.h index dc56d42..a807171 100644 --- a/chrome/browser/resource_coordinator/tab_manager_web_contents_data.h +++ b/chrome/browser/resource_coordinator/tab_manager_web_contents_data.h
@@ -63,8 +63,8 @@ void WasShown() override; void WebContentsDestroyed() override; - // Tab signal received from GRC. - void DoneLoading() {} + // idle signal received from GRC. + void NotifyAlmostIdle() {} // Returns true if the tab has been discarded to save memory. bool IsDiscarded();
diff --git a/chrome/browser/resources/chromeos/login/oobe_change_picture.html b/chrome/browser/resources/chromeos/login/oobe_change_picture.html index c8ec243..9804e86c 100644 --- a/chrome/browser/resources/chromeos/login/oobe_change_picture.html +++ b/chrome/browser/resources/chromeos/login/oobe_change_picture.html
@@ -49,7 +49,8 @@ image-type="[[getImageType_(selectedItem_)]]" discard-image-label="[[i18nDynamic(locale, 'discardPhoto')]]" take-photo-label="[[i18nDynamic(locale, 'takePhoto')]]" - switch-mode-label="[[i18nDynamic(locale, 'switchMode')]]"> + switch-mode-label="[[i18nDynamic(locale, 'switchMode')]]" + camera-video-mode-enabled="[[cameraVideoModeEnabled]]"> </cr-picture-pane> <cr-picture-list id="pictureList" camera-present="[[cameraPresent]]"
diff --git a/chrome/browser/resources/chromeos/login/oobe_change_picture.js b/chrome/browser/resources/chromeos/login/oobe_change_picture.js index d1a25ec..becae4d 100644 --- a/chrome/browser/resources/chromeos/login/oobe_change_picture.js +++ b/chrome/browser/resources/chromeos/login/oobe_change_picture.js
@@ -63,6 +63,15 @@ firstDefaultImageIndex: Number, /** + * True when camera video mode is enabled. + * @private {boolean} + */ + cameraVideoModeEnabled: { + type: Boolean, + value: true, + }, + + /** * The currently selected item. This property is bound to the iron-selector * and never directly assigned. This may be undefined momentarily as * the selection changes due to iron-selector implementation details.
diff --git a/chrome/browser/resources/settings/people_page/change_picture.html b/chrome/browser/resources/settings/people_page/change_picture.html index 82cbc58..e01e6709 100644 --- a/chrome/browser/resources/settings/people_page/change_picture.html +++ b/chrome/browser/resources/settings/people_page/change_picture.html
@@ -84,7 +84,8 @@ discard-image-label="$i18n{discardPhoto}" preview-alt-text="$i18n{previewAltText}" take-photo-label="$i18n{takePhoto}" - switch-mode-label="$i18n{switchMode}"> + switch-mode-label="$i18n{switchMode}" + camera-video-mode-enabled="[[cameraVideoModeEnabled_]]"> </cr-picture-pane> <div id="authorCredit" hidden="[[!isAuthorCreditShown_(selectedItem_)]]">
diff --git a/chrome/browser/resources/settings/people_page/change_picture.js b/chrome/browser/resources/settings/people_page/change_picture.js index b610c1d4..dc3b175a 100644 --- a/chrome/browser/resources/settings/people_page/change_picture.js +++ b/chrome/browser/resources/settings/people_page/change_picture.js
@@ -53,6 +53,15 @@ * @private */ firstDefaultImageIndex_: Number, + + /** + * True when camera video mode is enabled. + * @private {boolean} + */ + cameraVideoModeEnabled_: { + type: Boolean, + value: true, + }, }, listeners: {
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc index c0a5b9e..3761732 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
@@ -1169,14 +1169,17 @@ } { // If the response is UNKNOWN the result should also be marked as - // UNKNOWN + // UNKNOWN. And if the server requests an upload, we should upload. PrepareResponse(&factory, ClientDownloadResponse::UNKNOWN, net::HTTP_OK, - net::URLRequestStatus::SUCCESS); + net::URLRequestStatus::SUCCESS, + true /* upload_requested */); RunLoop run_loop; download_service_->CheckClientDownload( &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this), run_loop.QuitClosure())); run_loop.Run(); + EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting( + item, &feedback_ping, &feedback_response)); EXPECT_TRUE(IsResult(DownloadCheckResult::UNKNOWN)); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest();
diff --git a/chrome/browser/ui/cocoa/extensions/extension_uninstall_dialog_cocoa.mm b/chrome/browser/ui/cocoa/extensions/extension_uninstall_dialog_cocoa.mm index 4543754..be53c50 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_uninstall_dialog_cocoa.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_uninstall_dialog_cocoa.mm
@@ -9,6 +9,7 @@ #include <string> #import "base/mac/scoped_nsobject.h" +#include "base/message_loop/message_loop.h" #import "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/cocoa/browser_dialogs_views_mac.h" @@ -69,7 +70,13 @@ [alert setAccessoryView:reportAbuseCheckbox]; } - if ([alert runModal] == NSAlertFirstButtonReturn) { + NSModalResponse response; + { + base::MessageLoop::ScopedNestableTaskAllower allow_nested( + base::MessageLoop::current()); + response = [alert runModal]; + } + if (response == NSAlertFirstButtonReturn) { bool report_abuse_checked = reportAbuseCheckbox.get() && [reportAbuseCheckbox state] == NSOnState; OnDialogClosed(report_abuse_checked ?
diff --git a/chrome/browser/ui/page_info/page_info.cc b/chrome/browser/ui/page_info/page_info.cc index 861c923..a993285 100644 --- a/chrome/browser/ui/page_info/page_info.cc +++ b/chrome/browser/ui/page_info/page_info.cc
@@ -431,7 +431,9 @@ content_settings_->SetNarrowestContentSetting(site_url_, site_url_, type, setting); - show_info_bar_ = true; + // When the sound setting is changed, no reload is necessary. + if (type != CONTENT_SETTINGS_TYPE_SOUND) + show_info_bar_ = true; // Refresh the UI to reflect the new setting. PresentSitePermissions();
diff --git a/chrome/browser/ui/page_info/page_info_unittest.cc b/chrome/browser/ui/page_info/page_info_unittest.cc index 8e2ca2b..e07de43 100644 --- a/chrome/browser/ui/page_info/page_info_unittest.cc +++ b/chrome/browser/ui/page_info/page_info_unittest.cc
@@ -783,6 +783,26 @@ infobar_service()->RemoveInfoBar(infobar_service()->infobar_at(0)); } + +TEST_F(PageInfoTest, NoInfoBarWhenSoundSettingChanged) { + EXPECT_EQ(0u, infobar_service()->infobar_count()); + page_info()->OnSitePermissionChanged(CONTENT_SETTINGS_TYPE_SOUND, + CONTENT_SETTING_BLOCK); + page_info()->OnUIClosing(); + EXPECT_EQ(0u, infobar_service()->infobar_count()); +} + +TEST_F(PageInfoTest, ShowInfoBarWhenSoundSettingAndAnotherSettingChanged) { + EXPECT_EQ(0u, infobar_service()->infobar_count()); + page_info()->OnSitePermissionChanged(CONTENT_SETTINGS_TYPE_JAVASCRIPT, + CONTENT_SETTING_BLOCK); + page_info()->OnSitePermissionChanged(CONTENT_SETTINGS_TYPE_SOUND, + CONTENT_SETTING_BLOCK); + page_info()->OnUIClosing(); + EXPECT_EQ(1u, infobar_service()->infobar_count()); + + infobar_service()->RemoveInfoBar(infobar_service()->infobar_at(0)); +} #endif TEST_F(PageInfoTest, AboutBlankPage) {
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc index a0292d8..f7444b7 100644 --- a/chrome/browser/ui/views/download/download_item_view.cc +++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -250,7 +250,7 @@ void DownloadItemView::MaybeSubmitDownloadToFeedbackService( DownloadCommands::Command download_command) { PrefService* prefs = shelf_->browser()->profile()->GetPrefs(); - if (model_.MightBeMalicious() && model_.ShouldAllowDownloadFeedback() && + if (model_.ShouldAllowDownloadFeedback() && !shelf_->browser()->profile()->IsOffTheRecord()) { if (safe_browsing::ExtendedReportingPrefExists(*prefs)) { SubmitDownloadWhenFeedbackServiceEnabled( @@ -601,8 +601,9 @@ ExperienceSamplingEvent::kProceed); sampling_event_.reset(); } - // This will change the state and notify us. - download()->ValidateDangerousDownload(); + // This will call ValidateDangerousDownload(), change download state and + // notify us. + MaybeSubmitDownloadToFeedbackService(DownloadCommands::KEEP); return; }
diff --git a/chrome/renderer/chrome_render_frame_observer.cc b/chrome/renderer/chrome_render_frame_observer.cc index 69f16b8..39cc5890 100644 --- a/chrome/renderer/chrome_render_frame_observer.cc +++ b/chrome/renderer/chrome_render_frame_observer.cc
@@ -73,6 +73,7 @@ // Constants for UMA statistic collection. static const char kTranslateCaptureText[] = "Translate.CaptureText"; +static const char kTranslatePageCaptured[] = "Translate.PageCaptured"; // For a page that auto-refreshes, we still show the bubble, if // the refresh delay is less than this value (in seconds). @@ -412,8 +413,10 @@ // We should run language detection only once. Parsing finishes before // the page loads, so let's pick that timing. - if (translate_helper_ && capture_type == PRELIMINARY_CAPTURE) + if (translate_helper_ && capture_type == PRELIMINARY_CAPTURE) { + SCOPED_UMA_HISTOGRAM_TIMER(kTranslatePageCaptured); translate_helper_->PageCaptured(contents); + } TRACE_EVENT0("renderer", "ChromeRenderFrameObserver::CapturePageText");
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index bdc15bb..a9a8ecb 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -140,6 +140,7 @@ ] deps = [ + "//ash/public/cpp:ash_public_cpp", "//base", "//chromeos", "//components/keyed_service/content",
diff --git a/components/arc/common/typemaps.gni b/components/arc/common/typemaps.gni index 0845620d..62c8190 100644 --- a/components/arc/common/typemaps.gni +++ b/components/arc/common/typemaps.gni
@@ -10,6 +10,5 @@ "//components/arc/common/intent_helper.typemap", "//components/arc/common/video_common.typemap", "//components/arc/common/video_encode_accelerator.typemap", - "//components/arc/common/voice_interaction_framework.typemap", "//components/arc/common/volume_mounter.typemap", ]
diff --git a/components/arc/common/voice_interaction_framework.mojom b/components/arc/common/voice_interaction_framework.mojom index 3a9d70d..d7d43c23 100644 --- a/components/arc/common/voice_interaction_framework.mojom +++ b/components/arc/common/voice_interaction_framework.mojom
@@ -8,6 +8,12 @@ import "gfx.mojom"; +// There is another copy of the VoiceInteractionState definition in +// //ash/public/interfaces/voice_interaction_controller.mojom +// Please also update the other one if you change it. +// The duplicate definition is because we do not use extensible widely +// (crbug.com/731893). + [Extensible] enum VoiceInteractionState { NOT_READY = 0,
diff --git a/components/arc/common/voice_interaction_framework.typemap b/components/arc/common/voice_interaction_framework.typemap deleted file mode 100644 index 8254719..0000000 --- a/components/arc/common/voice_interaction_framework.typemap +++ /dev/null
@@ -1,13 +0,0 @@ -# Copyright 2017 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = "//components/arc/common/voice_interaction_framework.mojom" -public_headers = [ "//ash/public/cpp/voice_interaction_state.h" ] -public_deps = [ - "//ash/public/cpp:ash_public_cpp", -] -traits_headers = - [ "//components/arc/voice_interaction/voice_interaction_struct_traits.h" ] -sources = [] -type_mappings = [ "arc.mojom.VoiceInteractionState=ash::VoiceInteractionState" ]
diff --git a/components/arc/test/fake_voice_interaction_framework_instance.cc b/components/arc/test/fake_voice_interaction_framework_instance.cc index 01c17a1..8a8adf5 100644 --- a/components/arc/test/fake_voice_interaction_framework_instance.cc +++ b/components/arc/test/fake_voice_interaction_framework_instance.cc
@@ -22,17 +22,17 @@ void FakeVoiceInteractionFrameworkInstance::StartVoiceInteractionSession( bool homescreen_is_active) { start_session_count_++; - state_ = ash::VoiceInteractionState::RUNNING; + state_ = arc::mojom::VoiceInteractionState::RUNNING; host_->SetVoiceInteractionState(state_); } void FakeVoiceInteractionFrameworkInstance::ToggleVoiceInteractionSession( bool homescreen_is_active) { toggle_session_count_++; - if (state_ == ash::VoiceInteractionState::RUNNING) - state_ = ash::VoiceInteractionState::STOPPED; + if (state_ == arc::mojom::VoiceInteractionState::RUNNING) + state_ = arc::mojom::VoiceInteractionState::STOPPED; else - state_ = ash::VoiceInteractionState::RUNNING; + state_ = arc::mojom::VoiceInteractionState::RUNNING; host_->SetVoiceInteractionState(state_); }
diff --git a/components/arc/test/fake_voice_interaction_framework_instance.h b/components/arc/test/fake_voice_interaction_framework_instance.h index e4b5a5ee..17b61f90 100644 --- a/components/arc/test/fake_voice_interaction_framework_instance.h +++ b/components/arc/test/fake_voice_interaction_framework_instance.h
@@ -67,7 +67,8 @@ size_t start_session_for_region_count_ = 0u; gfx::Rect selected_region_; mojom::VoiceInteractionFrameworkHostPtr host_; - ash::VoiceInteractionState state_ = ash::VoiceInteractionState::STOPPED; + arc::mojom::VoiceInteractionState state_ = + arc::mojom::VoiceInteractionState::STOPPED; DISALLOW_COPY_AND_ASSIGN(FakeVoiceInteractionFrameworkInstance); };
diff --git a/components/arc/voice_interaction/OWNERS b/components/arc/voice_interaction/OWNERS deleted file mode 100644 index ef5cf84..0000000 --- a/components/arc/voice_interaction/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -per-file *_struct_traits*.*=set noparent -per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS -per-file *_struct_traits*.*=file://components/arc/common/ARC_SECURITY_OWNERS
diff --git a/components/arc/voice_interaction/voice_interaction_struct_traits.h b/components/arc/voice_interaction/voice_interaction_struct_traits.h deleted file mode 100644 index c519f96..0000000 --- a/components/arc/voice_interaction/voice_interaction_struct_traits.h +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_ARC_VOICE_INTERACTION_VOICE_INTERACTION_STRUCT_TRAITS_H_ -#define COMPONENTS_ARC_VOICE_INTERACTION_VOICE_INTERACTION_STRUCT_TRAITS_H_ - -#include "ash/public/cpp/voice_interaction_state.h" -#include "components/arc/common/voice_interaction_framework.mojom.h" - -namespace mojo { - -template <> -struct EnumTraits<arc::mojom::VoiceInteractionState, - ash::VoiceInteractionState> { - static arc::mojom::VoiceInteractionState ToMojom( - ash::VoiceInteractionState state) { - switch (state) { - case ash::VoiceInteractionState::NOT_READY: - return arc::mojom::VoiceInteractionState::NOT_READY; - case ash::VoiceInteractionState::STOPPED: - return arc::mojom::VoiceInteractionState::STOPPED; - case ash::VoiceInteractionState::RUNNING: - return arc::mojom::VoiceInteractionState::RUNNING; - } - - NOTREACHED() << "Invalid state: " << static_cast<int>(state); - return arc::mojom::VoiceInteractionState::NOT_READY; - } - - static bool FromMojom(arc::mojom::VoiceInteractionState mojom_state, - ash::VoiceInteractionState* state) { - switch (mojom_state) { - case arc::mojom::VoiceInteractionState::NOT_READY: - *state = ash::VoiceInteractionState::NOT_READY; - return true; - case arc::mojom::VoiceInteractionState::STOPPED: - *state = ash::VoiceInteractionState::STOPPED; - return true; - case arc::mojom::VoiceInteractionState::RUNNING: - *state = ash::VoiceInteractionState::RUNNING; - return true; - } - - NOTREACHED() << "Invalid state: " << static_cast<int>(mojom_state); - *state = ash::VoiceInteractionState::NOT_READY; - return false; - } -}; - -} // namespace mojo - -#endif // COMPONENTS_ARC_VOICE_INTERACTION_VOICE_INTERACTION_STRUCT_TRAITS_H_
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 90a6376..16e6396b 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -1642,6 +1642,7 @@ } void RenderFrameImpl::ScriptedPrint(bool user_initiated) { + SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.ScriptedPrint"); for (auto& observer : observers_) observer.ScriptedPrint(user_initiated); } @@ -1676,9 +1677,12 @@ GetContentClient()->SetActiveURL(frame_->GetDocument().Url()); - for (auto& observer : observers_) { - if (observer.OnMessageReceived(msg)) - return true; + { + SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.OnMessageReceived"); + for (auto& observer : observers_) { + if (observer.OnMessageReceived(msg)) + return true; + } } bool handled = true; @@ -2655,6 +2659,7 @@ void RenderFrameImpl::DidMeaningfulLayout( blink::WebMeaningfulLayout layout_type) { + SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidMeaningfulLayout"); for (auto& observer : observers_) observer.DidMeaningfulLayout(layout_type); } @@ -3203,8 +3208,12 @@ provider->IsControlledByServiceWorker()); worker_fetch_context->set_origin_url( GURL(frame_->GetDocument().Url()).GetOrigin()); - for (auto& observer : observers_) - observer.WillCreateWorkerFetchContext(worker_fetch_context.get()); + { + SCOPED_UMA_HISTOGRAM_TIMER( + "RenderFrameObservers.WillCreateWorkerFetchContext"); + for (auto& observer : observers_) + observer.WillCreateWorkerFetchContext(worker_fetch_context.get()); + } return std::move(worker_fetch_context); } @@ -3435,6 +3444,7 @@ } void RenderFrameImpl::WillCommitProvisionalLoad() { + SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.WillCommitProvisionalLoad"); for (auto& observer : observers_) observer.WillCommitProvisionalLoad(); } @@ -3564,6 +3574,7 @@ } void RenderFrameImpl::WillSendSubmitEvent(const blink::WebFormElement& form) { + SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.WillSendSubmitEvent"); for (auto& observer : observers_) observer.WillSendSubmitEvent(form); } @@ -3587,8 +3598,11 @@ internal_data->set_searchable_form_encoding( web_searchable_form_data.Encoding().Utf8()); - for (auto& observer : observers_) - observer.WillSubmitForm(form); + { + SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.WillSubmitForm"); + for (auto& observer : observers_) + observer.WillSubmitForm(form); + } } void RenderFrameImpl::DidCreateDocumentLoader( @@ -3745,8 +3759,11 @@ navigation_state->common_params().navigation_start; DCHECK(!navigation_start.is_null()); - for (auto& observer : observers_) - observer.DidStartProvisionalLoad(document_loader); + { + SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidStartProvisionalLoad"); + for (auto& observer : observers_) + observer.DidStartProvisionalLoad(document_loader); + } std::vector<GURL> redirect_chain; GetRedirectChain(document_loader, &redirect_chain); @@ -3772,8 +3789,11 @@ // for (auto& observer : render_view_->observers()) observer.DidFailProvisionalLoad(frame_, error); - for (auto& observer : observers_) - observer.DidFailProvisionalLoad(error); + { + SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidFailProvisionalLoad"); + for (auto& observer : observers_) + observer.DidFailProvisionalLoad(error); + } WebDocumentLoader* document_loader = frame_->GetProvisionalDocumentLoader(); if (!document_loader) @@ -3948,9 +3968,12 @@ for (auto& observer : render_view_->observers_) observer.DidCommitProvisionalLoad(frame_, is_new_navigation); - for (auto& observer : observers_) { - observer.DidCommitProvisionalLoad( - is_new_navigation, navigation_state->WasWithinSameDocument()); + { + SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidCommitProvisionalLoad"); + for (auto& observer : observers_) { + observer.DidCommitProvisionalLoad( + is_new_navigation, navigation_state->WasWithinSameDocument()); + } } // Notify the MediaPermissionDispatcher that its connection will be closed @@ -4008,8 +4031,11 @@ for (auto& observer : render_view_->observers()) observer.DidClearWindowObject(frame_); - for (auto& observer : observers_) - observer.DidClearWindowObject(); + { + SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidClearWindowObject"); + for (auto& observer : observers_) + observer.DidClearWindowObject(); + } } void RenderFrameImpl::DidCreateDocumentElement() { @@ -4085,8 +4111,11 @@ "RenderFrameImpl::didFinishDocumentLoad", "id", routing_id_); Send(new FrameHostMsg_DidFinishDocumentLoad(routing_id_)); - for (auto& observer : observers_) - observer.DidFinishDocumentLoad(); + { + SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidFinishDocumentLoad"); + for (auto& observer : observers_) + observer.DidFinishDocumentLoad(); + } // Check whether we have new encoding name. UpdateEncoding(frame_, frame_->View()->PageEncoding().Utf8()); @@ -4176,8 +4205,11 @@ TRACE_EVENT_SCOPE_PROCESS); } - for (auto& observer : observers_) - observer.DidFinishLoad(); + { + SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidFinishLoad"); + for (auto& observer : observers_) + observer.DidFinishLoad(); + } WebDocumentLoader* document_loader = frame_->GetDocumentLoader(); Send(new FrameHostMsg_DidFinishLoad(routing_id_, @@ -4785,8 +4817,11 @@ blink::WebContextFeatures::EnableMojoJS(context, true); } - for (auto& observer : observers_) - observer.DidCreateScriptContext(context, world_id); + { + SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidCreateScriptContext"); + for (auto& observer : observers_) + observer.DidCreateScriptContext(context, world_id); + } } void RenderFrameImpl::WillReleaseScriptContext(v8::Local<v8::Context> context, @@ -4798,8 +4833,11 @@ void RenderFrameImpl::DidChangeScrollOffset() { render_view_->StartNavStateSyncTimerIfNecessary(this); - for (auto& observer : observers_) - observer.DidChangeScrollOffset(); + { + SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidChangeScrollOffset"); + for (auto& observer : observers_) + observer.DidChangeScrollOffset(); + } } void RenderFrameImpl::WillInsertBody() { @@ -5399,8 +5437,11 @@ // focused input and the newly focused input share the exact same state. GetRenderWidget()->ClearTextInputState(); - for (auto& observer : observers_) - observer.FocusedNodeChanged(node); + { + SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.FocusedNodeChanged"); + for (auto& observer : observers_) + observer.FocusedNodeChanged(node); + } } void RenderFrameImpl::FocusedNodeChangedForAccessibility(const WebNode& node) {
diff --git a/device/BUILD.gn b/device/BUILD.gn index 587ab9e8..faa6a625 100644 --- a/device/BUILD.gn +++ b/device/BUILD.gn
@@ -132,8 +132,6 @@ "//device/hid", "//device/hid:mocks", "//device/serial", - "//device/u2f", - "//device/u2f:mocks", "//services/service_manager/public/cpp", "//services/service_manager/public/interfaces", ] @@ -222,6 +220,11 @@ deps += [ "//dbus" ] } + # BLE discovery: works on Linux. + if (is_linux) { + sources += [ "u2f/u2f_ble_discovery_unittest.cc" ] + } + if (is_mac) { deps += [ "//third_party/ocmock" ] ldflags = [ "-ObjC" ]
diff --git a/device/bluetooth/test/bluetooth_test.cc b/device/bluetooth/test/bluetooth_test.cc index 8cfe116..66749eb9 100644 --- a/device/bluetooth/test/bluetooth_test.cc +++ b/device/bluetooth/test/bluetooth_test.cc
@@ -20,6 +20,7 @@ const char BluetoothTestBase::kTestDeviceName[] = "FakeBluetoothDevice"; const char BluetoothTestBase::kTestDeviceNameEmpty[] = ""; +const char BluetoothTestBase::kTestDeviceNameU2f[] = "U2F FakeDevice"; const char BluetoothTestBase::kTestDeviceAddress1[] = "01:00:00:90:1E:BE"; const char BluetoothTestBase::kTestDeviceAddress2[] = "02:00:00:8B:74:63"; @@ -36,6 +37,8 @@ "00001803-0000-1000-8000-00805f9b34fb"; const char BluetoothTestBase::kTestUUIDHeartRate[] = "0000180d-0000-1000-8000-00805f9b34fb"; +const char BluetoothTestBase::kTestUUIDU2f[] = + "0000fffd-0000-1000-8000-00805f9b34fb"; // Characteristic UUIDs const char BluetoothTestBase::kTestUUIDDeviceName[] = "00002a00-0000-1000-8000-00805f9b34fb"; @@ -45,6 +48,8 @@ "00002a03-0000-1000-8000-00805f9b34fb"; const char BluetoothTestBase::kTestUUIDHeartRateMeasurement[] = "00002a37-0000-1000-8000-00805f9b34fb"; +const char BluetoothTestBase::kTestUUIDU2fControlPointLength[] = + "f1d0fff3-deaa-ecee-b42f-c9ba7ed623bb"; // Descriptor UUIDs const char BluetoothTestBase::kTestUUIDCharacteristicUserDescription[] = "00002901-0000-1000-8000-00805f9b34fb";
diff --git a/device/bluetooth/test/bluetooth_test.h b/device/bluetooth/test/bluetooth_test.h index de9dc73..562a528 100644 --- a/device/bluetooth/test/bluetooth_test.h +++ b/device/bluetooth/test/bluetooth_test.h
@@ -67,6 +67,7 @@ static const char kTestDeviceName[]; static const char kTestDeviceNameEmpty[]; + static const char kTestDeviceNameU2f[]; static const char kTestDeviceAddress1[]; static const char kTestDeviceAddress2[]; @@ -93,6 +94,7 @@ static const char kTestUUIDImmediateAlert[]; static const char kTestUUIDLinkLoss[]; static const char kTestUUIDHeartRate[]; + static const char kTestUUIDU2f[]; // Characteristics // The following three characteristics are for kTestUUIDGenericAccess. static const char kTestUUIDDeviceName[]; @@ -100,6 +102,8 @@ static const char kTestUUIDReconnectionAddress[]; // This characteristic is for kTestUUIDHeartRate. static const char kTestUUIDHeartRateMeasurement[]; + // This characteristic is for kTestUUIDU2f. + static const char kTestUUIDU2fControlPointLength[]; // Descriptors static const char kTestUUIDCharacteristicUserDescription[]; static const char kTestUUIDClientCharacteristicConfiguration[]; @@ -193,6 +197,13 @@ // No Service Data // No Tx Power // Supports BR/EDR and LE. + // 7: Name: kTestDeviceNameU2f + // Address: kTestDeviceAddress1 + // RSSI: kTestRSSI1, + // Advertised UUIDs: {kTestUUIDU2fControlPointLength} + // Service Data: {kTestUUIDU2fControlPointLength: [0, 20]} + // No Tx Power + // Supports LE. virtual BluetoothDevice* SimulateLowEnergyDevice(int device_ordinal); // Simulates a connected low energy device. Used before starting a low energy
diff --git a/device/bluetooth/test/bluetooth_test_bluez.cc b/device/bluetooth/test/bluetooth_test_bluez.cc index dd406644..51fb511a 100644 --- a/device/bluetooth/test/bluetooth_test_bluez.cc +++ b/device/bluetooth/test/bluetooth_test_bluez.cc
@@ -115,7 +115,7 @@ BluetoothDevice* BluetoothTestBlueZ::SimulateLowEnergyDevice( int device_ordinal) { - if (device_ordinal > 6 || device_ordinal < 1) + if (device_ordinal > 7 || device_ordinal < 1) return nullptr; base::Optional<std::string> device_name = std::string(kTestDeviceName); @@ -149,6 +149,11 @@ device_address = kTestDeviceAddress2; device_type = BLUETOOTH_TRANSPORT_DUAL; break; + case 7: + device_name.emplace(kTestDeviceNameU2f); + service_uuids.push_back(kTestUUIDU2f); + service_data[kTestUUIDU2fControlPointLength] = {0x00, 0x14}; + break; } BluetoothDevice* device = adapter_->GetDevice(device_address);
diff --git a/device/u2f/BUILD.gn b/device/u2f/BUILD.gn index b4fbe217..b32749c 100644 --- a/device/u2f/BUILD.gn +++ b/device/u2f/BUILD.gn
@@ -11,8 +11,11 @@ "u2f_apdu_command.h", "u2f_apdu_response.cc", "u2f_apdu_response.h", + "u2f_ble_discovery.cc", + "u2f_ble_discovery.h", "u2f_ble_frames.cc", "u2f_ble_frames.h", + "u2f_ble_uuids.h", "u2f_command_type.h", "u2f_device.cc", "u2f_device.h",
diff --git a/device/u2f/u2f_ble_discovery.cc b/device/u2f/u2f_ble_discovery.cc new file mode 100644 index 0000000..fa414ba --- /dev/null +++ b/device/u2f/u2f_ble_discovery.cc
@@ -0,0 +1,172 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "device/u2f/u2f_ble_discovery.h" + +#include "base/bind.h" +#include "base/stl_util.h" +#include "base/strings/string_piece.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" +#include "device/bluetooth/bluetooth_common.h" +#include "device/bluetooth/bluetooth_discovery_filter.h" +#include "device/bluetooth/bluetooth_discovery_session.h" +#include "device/bluetooth/bluetooth_uuid.h" +#include "device/u2f/u2f_apdu_command.h" +#include "device/u2f/u2f_ble_uuids.h" +#include "device/u2f/u2f_device.h" + +namespace device { + +namespace { + +// TODO(crbug/763303): Remove this once a U2fDevice for BLE is implemented. +class U2fFakeBleDevice : public U2fDevice { + public: + static std::string GetId(base::StringPiece address) { + std::string result = "ble:"; + result.append(address.data(), address.size()); + return result; + } + + U2fFakeBleDevice(base::StringPiece address) + : id_(GetId(address)), weak_factory_(this) {} + + ~U2fFakeBleDevice() override = default; + + void TryWink(const WinkCallback& callback) override {} + std::string GetId() const override { return id_; } + + protected: + void DeviceTransact(std::unique_ptr<U2fApduCommand> command, + const DeviceCallback& callback) override { + callback.Run(false, nullptr); + } + + base::WeakPtr<U2fDevice> GetWeakPtr() override { + return weak_factory_.GetWeakPtr(); + } + + private: + std::string id_; + + base::WeakPtrFactory<U2fFakeBleDevice> weak_factory_; +}; + +} // namespace + +U2fBleDiscovery::U2fBleDiscovery() : weak_factory_(this) {} + +U2fBleDiscovery::~U2fBleDiscovery() { + adapter_->RemoveObserver(this); +} + +void U2fBleDiscovery::Start() { + auto& factory = BluetoothAdapterFactory::Get(); + factory.GetAdapter(base::Bind(&U2fBleDiscovery::GetAdapterCallback, + weak_factory_.GetWeakPtr())); +} + +void U2fBleDiscovery::Stop() { + adapter_->RemoveObserver(this); + + discovery_session_->Stop( + base::Bind(&U2fBleDiscovery::OnStopped, weak_factory_.GetWeakPtr(), true), + base::Bind(&U2fBleDiscovery::OnStopped, weak_factory_.GetWeakPtr(), + false)); +} + +// static +const BluetoothUUID& U2fBleDiscovery::U2fServiceUUID() { + static const BluetoothUUID service_uuid(U2F_SERVICE_UUID); + return service_uuid; +} + +void U2fBleDiscovery::GetAdapterCallback( + scoped_refptr<BluetoothAdapter> adapter) { + adapter_ = std::move(adapter); + DCHECK(adapter_); + VLOG(2) << "Got adapter " << adapter_->GetAddress(); + + adapter_->AddObserver(this); + if (adapter_->IsPowered()) { + OnSetPowered(); + } else { + adapter_->SetPowered( + true, + base::Bind(&U2fBleDiscovery::OnSetPowered, weak_factory_.GetWeakPtr()), + base::Bind( + [](base::WeakPtr<Delegate> delegate) { + LOG(ERROR) << "Failed to power on the adapter."; + if (delegate) + delegate->OnStarted(false); + }, + delegate_)); + } +} + +void U2fBleDiscovery::OnSetPowered() { + VLOG(2) << "Adapter " << adapter_->GetAddress() << " is powered on."; + + for (BluetoothDevice* device : adapter_->GetDevices()) { + if (base::ContainsKey(device->GetUUIDs(), U2fServiceUUID())) { + VLOG(2) << "U2F BLE device: " << device->GetAddress(); + if (delegate_) { + delegate_->OnDeviceAdded( + std::make_unique<U2fFakeBleDevice>(device->GetAddress())); + } + } + } + + auto filter = std::make_unique<BluetoothDiscoveryFilter>( + BluetoothTransport::BLUETOOTH_TRANSPORT_LE); + filter->AddUUID(U2fServiceUUID()); + + adapter_->StartDiscoverySessionWithFilter( + std::move(filter), + base::Bind(&U2fBleDiscovery::DiscoverySessionStarted, + weak_factory_.GetWeakPtr()), + base::Bind( + [](base::WeakPtr<Delegate> delegate) { + LOG(ERROR) << "Discovery session not started."; + if (delegate) + delegate->OnStarted(false); + }, + delegate_)); +} + +void U2fBleDiscovery::DiscoverySessionStarted( + std::unique_ptr<BluetoothDiscoverySession> session) { + discovery_session_ = std::move(session); + VLOG(2) << "Discovery session started."; + if (delegate_) + delegate_->OnStarted(true); +} + +void U2fBleDiscovery::DeviceAdded(BluetoothAdapter* adapter, + BluetoothDevice* device) { + if (base::ContainsKey(device->GetUUIDs(), U2fServiceUUID())) { + VLOG(2) << "Discovered U2F BLE device: " << device->GetAddress(); + if (delegate_) { + delegate_->OnDeviceAdded( + std::make_unique<U2fFakeBleDevice>(device->GetAddress())); + } + } +} + +void U2fBleDiscovery::DeviceRemoved(BluetoothAdapter* adapter, + BluetoothDevice* device) { + if (base::ContainsKey(device->GetUUIDs(), U2fServiceUUID())) { + VLOG(2) << "U2F BLE device removed: " << device->GetAddress(); + if (delegate_) + delegate_->OnDeviceRemoved(U2fFakeBleDevice::GetId(device->GetAddress())); + } +} + +void U2fBleDiscovery::OnStopped(bool success) { + discovery_session_.reset(); + if (delegate_) + delegate_->OnStopped(success); +} + +} // namespace device
diff --git a/device/u2f/u2f_ble_discovery.h b/device/u2f/u2f_ble_discovery.h new file mode 100644 index 0000000..68c93ff --- /dev/null +++ b/device/u2f/u2f_ble_discovery.h
@@ -0,0 +1,54 @@ +// 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 DEVICE_U2F_U2F_BLE_DISCOVERY_H_ +#define DEVICE_U2F_U2F_BLE_DISCOVERY_H_ + +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/u2f/u2f_discovery.h" + +#include <memory> + +namespace device { + +class BluetoothDevice; +class BluetoothDiscoverySession; +class BluetoothUUID; + +class U2fBleDiscovery : public U2fDiscovery, BluetoothAdapter::Observer { + public: + U2fBleDiscovery(); + ~U2fBleDiscovery() override; + + // U2fDiscovery: + void Start() override; + void Stop() override; + + private: + static const BluetoothUUID& U2fServiceUUID(); + + void GetAdapterCallback(scoped_refptr<BluetoothAdapter> adapter); + void OnSetPowered(); + void DiscoverySessionStarted(std::unique_ptr<BluetoothDiscoverySession>); + + // BluetoothAdapter::Observer: + void DeviceAdded(BluetoothAdapter* adapter, BluetoothDevice* device) override; + void DeviceRemoved(BluetoothAdapter* adapter, + BluetoothDevice* device) override; + + void OnStopped(bool success); + + scoped_refptr<BluetoothAdapter> adapter_; + std::unique_ptr<BluetoothDiscoverySession> discovery_session_; + + base::WeakPtrFactory<U2fBleDiscovery> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(U2fBleDiscovery); +}; + +} // namespace device + +#endif // DEVICE_U2F_U2F_BLE_DISCOVERY_H_
diff --git a/device/u2f/u2f_ble_discovery_unittest.cc b/device/u2f/u2f_ble_discovery_unittest.cc new file mode 100644 index 0000000..1042484 --- /dev/null +++ b/device/u2f/u2f_ble_discovery_unittest.cc
@@ -0,0 +1,116 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "device/u2f/u2f_ble_discovery.h" + +#include "base/bind.h" +#include "build/build_config.h" +#include "device/bluetooth/test/bluetooth_test.h" +#include "device/u2f/mock_u2f_discovery.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if defined(OS_ANDROID) +#include "device/bluetooth/test/bluetooth_test_android.h" +#elif defined(OS_MACOSX) +#include "device/bluetooth/test/bluetooth_test_mac.h" +#elif defined(OS_WIN) +#include "device/bluetooth/test/bluetooth_test_win.h" +#elif defined(OS_CHROMEOS) || defined(OS_LINUX) +#include "device/bluetooth/test/bluetooth_test_bluez.h" +#endif + +namespace device { + +ACTION_P(ReturnFromAsyncCall, closure) { + closure.Run(); +} + +std::string GetTestDeviceId(std::string address) { + return "ble:" + address; +} + +TEST_F(BluetoothTest, U2fBleDiscoveryFindsKnownDevice) { + if (!PlatformSupportsLowEnergy()) { + LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; + return; + } + InitWithFakeAdapter(); + + SimulateLowEnergyDevice(4); // This device should be ignored. + SimulateLowEnergyDevice(7); + + U2fBleDiscovery discovery; + MockU2fDiscovery::MockDelegate delegate; + discovery.SetDelegate(delegate.GetWeakPtr()); + + { + base::RunLoop run_loop; + auto quit = run_loop.QuitClosure(); + EXPECT_CALL(delegate, OnDeviceAddedStr(GetTestDeviceId( + BluetoothTestBase::kTestDeviceAddress1))); + EXPECT_CALL(delegate, OnStarted(true)).WillOnce(ReturnFromAsyncCall(quit)); + + discovery.Start(); + run_loop.Run(); + } + + // TODO(crbug/763303): Delete device and check OnDeviceDeleted invocation. + + { + base::RunLoop run_loop; + auto quit = run_loop.QuitClosure(); + + EXPECT_CALL(delegate, OnStopped(true)).WillOnce(ReturnFromAsyncCall(quit)); + + discovery.Stop(); + run_loop.Run(); + } +} + +TEST_F(BluetoothTest, U2fBleDiscoveryFindsNewDevice) { + if (!PlatformSupportsLowEnergy()) { + LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; + return; + } + InitWithFakeAdapter(); + + U2fBleDiscovery discovery; + MockU2fDiscovery::MockDelegate delegate; + discovery.SetDelegate(delegate.GetWeakPtr()); + + { + base::RunLoop run_loop; + auto quit = run_loop.QuitClosure(); + EXPECT_CALL(delegate, OnStarted(true)).WillOnce(ReturnFromAsyncCall(quit)); + + discovery.Start(); + run_loop.Run(); + } + + { + base::RunLoop run_loop; + auto quit = run_loop.QuitClosure(); + EXPECT_CALL(delegate, OnDeviceAddedStr(GetTestDeviceId( + BluetoothTestBase::kTestDeviceAddress1))) + .WillOnce(ReturnFromAsyncCall(quit)); + + SimulateLowEnergyDevice(4); // This device should be ignored. + SimulateLowEnergyDevice(7); + + run_loop.Run(); + } + + // TODO(crbug/763303): Delete device and check OnDeviceDeleted invocation. + + { + base::RunLoop run_loop; + auto quit = run_loop.QuitClosure(); + EXPECT_CALL(delegate, OnStopped(true)).WillOnce(ReturnFromAsyncCall(quit)); + discovery.Stop(); + run_loop.Run(); + } +} + +} // namespace device
diff --git a/device/u2f/u2f_ble_uuids.h b/device/u2f/u2f_ble_uuids.h new file mode 100644 index 0000000..8820e04 --- /dev/null +++ b/device/u2f/u2f_ble_uuids.h
@@ -0,0 +1,27 @@ +// 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 DEVICE_U2F_U2F_BLE_UUIDS_H_ +#define DEVICE_U2F_U2F_BLE_UUIDS_H_ + +namespace device { + +// U2F GATT Service's UUIDs as defined by the standard: +// https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-bt-protocol-v1.2-ps-20170411.html#h3_u2f-service +// +// For details on how the short U2F Service UUID (0xfffd) was converted to the +// long one below, see +// https://www.bluetooth.com/specifications/assigned-numbers/service-discovery +static constexpr const char U2F_SERVICE_UUID[] = + "0000fffd-0000-1000-8000-00805f9b34fb"; +static constexpr const char U2F_CONTROL_POINT_UUID[] = + "f1d0fff1-deaa-ecee-b42f-c9ba7ed623bb"; +static constexpr const char U2F_STATUS_UUID[] = + "f1d0fff2-deaa-ecee-b42f-c9ba7ed623bb"; +static constexpr const char U2F_CONTROL_POINT_LENGTH_UUID[] = + "f1d0fff3-deaa-ecee-b42f-c9ba7ed623bb"; + +} // namespace device + +#endif // DEVICE_U2F_U2F_BLE_UUIDS_H_
diff --git a/extensions/browser/api/power/power_api_unittest.cc b/extensions/browser/api/power/power_api_unittest.cc index adad62d..db732f6 100644 --- a/extensions/browser/api/power/power_api_unittest.cc +++ b/extensions/browser/api/power/power_api_unittest.cc
@@ -87,6 +87,9 @@ requests_.push_back(BLOCK_DISPLAY_SLEEP); requests_.push_back(UNBLOCK_APP_SUSPENSION); break; + case device::mojom::WakeLockType::PreventDisplaySleepAllowDimming: + NOTREACHED() << "Unexpected wake lock type " << type; + break; } type_ = type; @@ -102,6 +105,9 @@ case device::mojom::WakeLockType::PreventDisplaySleep: requests_.push_back(BLOCK_DISPLAY_SLEEP); break; + case device::mojom::WakeLockType::PreventDisplaySleepAllowDimming: + NOTREACHED() << "Unexpected wake lock type " << type; + break; } type_ = type; @@ -119,6 +125,9 @@ case device::mojom::WakeLockType::PreventDisplaySleep: requests_.push_back(UNBLOCK_DISPLAY_SLEEP); break; + case device::mojom::WakeLockType::PreventDisplaySleepAllowDimming: + NOTREACHED() << "Unexpected wake lock type " << type_; + break; } is_active_ = false; }
diff --git a/ios/testing/wait_util.h b/ios/testing/wait_util.h index 263912c..c3c436d 100644 --- a/ios/testing/wait_util.h +++ b/ios/testing/wait_util.h
@@ -7,6 +7,7 @@ #import <Foundation/Foundation.h> +#include "base/compiler_specific.h" #import "base/ios/block_types.h" namespace testing { @@ -29,7 +30,7 @@ // Returns true when condition() becomes true, otherwise returns false after // |timeout|. bool WaitUntilConditionOrTimeout(NSTimeInterval timeout, - ConditionBlock condition); + ConditionBlock condition) WARN_UNUSED_RESULT; } // namespace testing
diff --git a/media/blink/multibuffer_data_source.h b/media/blink/multibuffer_data_source.h index fcb8563..ca080d116 100644 --- a/media/blink/multibuffer_data_source.h +++ b/media/blink/multibuffer_data_source.h
@@ -253,14 +253,6 @@ DownloadingCB downloading_cb_; - // The original URL of the first response. If the request is redirected to - // another URL it is the URL after redirected. If the response is generated in - // a Service Worker this URL is empty. MultibufferDataSource checks the - // original URL of each successive response. If the origin URL of it is - // different from the original URL of the first response, it is treated - // as an error. - GURL response_original_url_; - // Disallow rebinding WeakReference ownership to a different thread by keeping // a persistent reference. This avoids problems with the thread-safety of // reaching into this class from multiple threads to attain a WeakPtr.
diff --git a/pdf/pdfium/fuzzers/pdfium_fuzzer_helper.cc b/pdf/pdfium/fuzzers/pdfium_fuzzer_helper.cc index d15d621..ea66092 100644 --- a/pdf/pdfium/fuzzers/pdfium_fuzzer_helper.cc +++ b/pdf/pdfium/fuzzers/pdfium_fuzzer_helper.cc
@@ -8,23 +8,27 @@ #include <assert.h> #include <limits.h> + #include <stddef.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#ifdef _MSC_VER +#ifdef _WIN32 #include <Windows.h> -#else +#elif defined(__APPLE__) +#include <mach-o/dyld.h> +#else // Linux #include <unistd.h> -#endif +#endif // _WIN32 #include <memory> #include <sstream> #include <string> #include <utility> +#include "base/memory/free_deleter.h" #include "third_party/pdfium/public/cpp/fpdf_deleters.h" #include "third_party/pdfium/public/fpdf_dataavail.h" #include "third_party/pdfium/public/fpdf_text.h" @@ -78,22 +82,30 @@ void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) {} std::string ProgramPath() { -#ifdef _MSC_VER + std::string result; + +#ifdef _WIN32 wchar_t wpath[MAX_PATH]; char path[MAX_PATH]; - DWORD res = GetModuleFileName(NULL, wpath, MAX_PATH); - assert(res != 0); - wcstombs(path, wpath, MAX_PATH); - return std::string(path, res); -#else - char* path = new char[PATH_MAX + 1]; - assert(path); - ssize_t sz = readlink("/proc/self/exe", path, PATH_MAX); - assert(sz > 0); - std::string result(path, sz); - delete[] path; - return result; + DWORD len = GetModuleFileNameA(NULL, path, MAX_PATH); + if (len != 0) + result = std::string(path, len); +#elif defined(__APPLE__) + char path[PATH_MAX]; + unsigned int len = PATH_MAX; + if (!_NSGetExecutablePath(path, &len)) { + std::unique_ptr<char, base::FreeDeleter> resolved_path( + realpath(path, nullptr)); + if (resolved_path.get()) + result = std::string(resolved_path.get()); + } +#else // Linux + char path[PATH_MAX]; + ssize_t len = readlink("/proc/self/exe", path, PATH_MAX); + if (len > 0) + result = std::string(path, len); #endif + return result; } } // namespace
diff --git a/ppapi/proxy/ppb_var_unittest.cc b/ppapi/proxy/ppb_var_unittest.cc index cfabf0f..38afb60c 100644 --- a/ppapi/proxy/ppb_var_unittest.cc +++ b/ppapi/proxy/ppb_var_unittest.cc
@@ -98,12 +98,14 @@ // |strings_in|, |vars|, and |strings_out| are arrays, and size is their size. // For each |strings_in[i]|, we will set |vars[i]| using that value. Then we // read the var back out to |strings_out[i]|. - CreateVarThreadDelegate(PP_Module pp_module, const std::string* strings_in, - PP_Var* vars_out, std::string* strings_out, + CreateVarThreadDelegate(const std::string* strings_in, + PP_Var* vars_out, + std::string* strings_out, size_t size) - : pp_module_(pp_module), strings_in_(strings_in), vars_out_(vars_out), - strings_out_(strings_out), size_(size) { - } + : strings_in_(strings_in), + vars_out_(vars_out), + strings_out_(strings_out), + size_(size) {} virtual ~CreateVarThreadDelegate() {} virtual void ThreadMain() { const PPB_Var* ppb_var = ppapi::PPB_Var_Shared::GetVarInterface1_2(); @@ -115,7 +117,6 @@ } } private: - PP_Module pp_module_; const std::string* strings_in_; PP_Var* vars_out_; std::string* strings_out_; @@ -181,13 +182,10 @@ // kNumThreads). for (size_t slice_start= 0; slice_start < kNumStrings; slice_start += strings_per_thread) { - create_var_delegates.push_back( - CreateVarThreadDelegate(pp_module(), - &test_strings_[slice_start], - &vars_[slice_start], - &strings_out[slice_start], - std::min(strings_per_thread, - kNumStrings - slice_start))); + create_var_delegates.push_back(CreateVarThreadDelegate( + &test_strings_[slice_start], &vars_[slice_start], + &strings_out[slice_start], + std::min(strings_per_thread, kNumStrings - slice_start))); } // Now run then join all the threads. for (size_t i = 0; i < kNumThreads; ++i)
diff --git a/remoting/protocol/webrtc_transport.cc b/remoting/protocol/webrtc_transport.cc index cc741e26..e7718c50b 100644 --- a/remoting/protocol/webrtc_transport.cc +++ b/remoting/protocol/webrtc_transport.cc
@@ -78,7 +78,7 @@ // underlying bug is fixed to handle high load at high bitrate. if (sdp_message->has_video()) { const char* kParameters = - "x-google-min-bitrate=0; x-google-max-bitrate=20000"; + "x-google-min-bitrate=1000; x-google-max-bitrate=20000"; bool param_added = sdp_message->AddCodecParameter("VP8", kParameters); param_added |= sdp_message->AddCodecParameter("VP9", kParameters); param_added |= sdp_message->AddCodecParameter("H264", kParameters);
diff --git a/services/device/public/interfaces/wake_lock.mojom b/services/device/public/interfaces/wake_lock.mojom index 97352c7f..c5e1309 100644 --- a/services/device/public/interfaces/wake_lock.mojom +++ b/services/device/public/interfaces/wake_lock.mojom
@@ -17,6 +17,11 @@ // app from being suspended on some platforms if the user hides it. // Example use case: playing video. PreventDisplaySleep = 1, + + // Like PreventDisplaySleep, but permits the display to dim while remaining + // on. On some platforms, this may be treated identically to + // PreventDisplaySleep. + PreventDisplaySleepAllowDimming = 2, }; enum WakeLockReason {
diff --git a/services/device/wake_lock/power_save_blocker/power_save_blocker.h b/services/device/wake_lock/power_save_blocker/power_save_blocker.h index bd4332a..7045eb1d 100644 --- a/services/device/wake_lock/power_save_blocker/power_save_blocker.h +++ b/services/device/wake_lock/power_save_blocker/power_save_blocker.h
@@ -36,6 +36,11 @@ // app from being suspended on some platforms if the user hides it. // Example use case: playing video. kPowerSaveBlockPreventDisplaySleep, + + // Like kPowerSaveBlockPreventDisplaySleep, but permits the display to dim + // while remaining on. On some platforms, this may be treated identically to + // kPowerSaveBlockPreventDisplaySleep. + kPowerSaveBlockPreventDisplaySleepAllowDimming, }; // Reasons why power-saving features may be blocked.
diff --git a/services/device/wake_lock/power_save_blocker/power_save_blocker_chromeos.cc b/services/device/wake_lock/power_save_blocker/power_save_blocker_chromeos.cc index 87e9c13..ccef189 100644 --- a/services/device/wake_lock/power_save_blocker/power_save_blocker_chromeos.cc +++ b/services/device/wake_lock/power_save_blocker/power_save_blocker_chromeos.cc
@@ -63,6 +63,10 @@ block_id_ = controller->AddScreenWakeLock(GetWakeLockReason(reason_), description_); break; + case kPowerSaveBlockPreventDisplaySleepAllowDimming: + block_id_ = controller->AddDimWakeLock(GetWakeLockReason(reason_), + description_); + break; default: NOTREACHED() << "Unhandled block type " << type_; }
diff --git a/services/device/wake_lock/power_save_blocker/power_save_blocker_mac.cc b/services/device/wake_lock/power_save_blocker/power_save_blocker_mac.cc index 52c96d8..0f27634 100644 --- a/services/device/wake_lock/power_save_blocker/power_save_blocker_mac.cc +++ b/services/device/wake_lock/power_save_blocker/power_save_blocker_mac.cc
@@ -73,6 +73,7 @@ level = kIOPMAssertionTypeNoIdleSleep; break; case PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep: + case PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleepAllowDimming: level = kIOPMAssertionTypeNoDisplaySleep; break; default:
diff --git a/services/device/wake_lock/power_save_blocker/power_save_blocker_win.cc b/services/device/wake_lock/power_save_blocker/power_save_blocker_win.cc index 03eb9ce..6850bdd2 100644 --- a/services/device/wake_lock/power_save_blocker/power_save_blocker_win.cc +++ b/services/device/wake_lock/power_save_blocker/power_save_blocker_win.cc
@@ -99,7 +99,8 @@ } POWER_REQUEST_TYPE PowerSaveBlocker::Delegate::RequestType() { - if (type_ == kPowerSaveBlockPreventDisplaySleep) + if (type_ == kPowerSaveBlockPreventDisplaySleep || + type_ == kPowerSaveBlockPreventDisplaySleepAllowDimming) return PowerRequestDisplayRequired; if (base::win::GetVersion() == base::win::VERSION_WIN7)
diff --git a/services/device/wake_lock/power_save_blocker/power_save_blocker_x11.cc b/services/device/wake_lock/power_save_blocker/power_save_blocker_x11.cc index f8a4ac3..1f8c5fe 100644 --- a/services/device/wake_lock/power_save_blocker/power_save_blocker_x11.cc +++ b/services/device/wake_lock/power_save_blocker/power_save_blocker_x11.cc
@@ -276,6 +276,7 @@ uint32_t flags = 0; switch (type_) { case kPowerSaveBlockPreventDisplaySleep: + case kPowerSaveBlockPreventDisplaySleepAllowDimming: flags |= INHIBIT_MARK_SESSION_IDLE; flags |= INHIBIT_SUSPEND_SESSION; break; @@ -289,6 +290,7 @@ case FREEDESKTOP_API: switch (type_) { case kPowerSaveBlockPreventDisplaySleep: + case kPowerSaveBlockPreventDisplaySleepAllowDimming: object_proxy = bus_->GetObjectProxy( kFreeDesktopAPIScreenServiceName, dbus::ObjectPath(kFreeDesktopAPIScreenObjectPath)); @@ -374,6 +376,7 @@ case FREEDESKTOP_API: switch (type_) { case kPowerSaveBlockPreventDisplaySleep: + case kPowerSaveBlockPreventDisplaySleepAllowDimming: object_proxy = bus_->GetObjectProxy( kFreeDesktopAPIScreenServiceName, dbus::ObjectPath(kFreeDesktopAPIScreenObjectPath)); @@ -497,7 +500,8 @@ blocking_task_runner_(blocking_task_runner) { delegate_->Init(); - if (type == kPowerSaveBlockPreventDisplaySleep) { + if (type == kPowerSaveBlockPreventDisplaySleep || + type == kPowerSaveBlockPreventDisplaySleepAllowDimming) { freedesktop_suspend_delegate_ = new Delegate( kPowerSaveBlockPreventAppSuspension, description, true /* freedesktop_only */, ui_task_runner, blocking_task_runner);
diff --git a/services/device/wake_lock/wake_lock.cc b/services/device/wake_lock/wake_lock.cc index dda98f3f..7391a886 100644 --- a/services/device/wake_lock/wake_lock.cc +++ b/services/device/wake_lock/wake_lock.cc
@@ -21,6 +21,9 @@ case mojom::WakeLockType::PreventDisplaySleep: return PowerSaveBlocker::PowerSaveBlockerType:: kPowerSaveBlockPreventDisplaySleep; + case mojom::WakeLockType::PreventDisplaySleepAllowDimming: + return PowerSaveBlocker::PowerSaveBlockerType:: + kPowerSaveBlockPreventDisplaySleepAllowDimming; } NOTREACHED();
diff --git a/services/device/wake_lock/wake_lock_unittest.cc b/services/device/wake_lock/wake_lock_unittest.cc index d6109ca..2b79e8e 100644 --- a/services/device/wake_lock/wake_lock_unittest.cc +++ b/services/device/wake_lock/wake_lock_unittest.cc
@@ -121,6 +121,8 @@ // Call ChangeType() on a wake lock that is in inactive status. EXPECT_TRUE(ChangeType(device::mojom::WakeLockType::PreventAppSuspension)); EXPECT_TRUE(ChangeType(device::mojom::WakeLockType::PreventDisplaySleep)); + EXPECT_TRUE( + ChangeType(device::mojom::WakeLockType::PreventDisplaySleepAllowDimming)); EXPECT_FALSE(HasWakeLock()); // still inactive. wake_lock_->RequestWakeLock(); @@ -128,6 +130,8 @@ // Call ChangeType() on a wake lock that is in active status. EXPECT_TRUE(ChangeType(device::mojom::WakeLockType::PreventAppSuspension)); EXPECT_TRUE(ChangeType(device::mojom::WakeLockType::PreventDisplaySleep)); + EXPECT_TRUE( + ChangeType(device::mojom::WakeLockType::PreventDisplaySleepAllowDimming)); EXPECT_TRUE(HasWakeLock()); // still active. // Send multiple requests, should be coalesced as usual. @@ -145,6 +149,8 @@ #else // OS_ANDROID: EXPECT_FALSE(ChangeType(device::mojom::WakeLockType::PreventAppSuspension)); EXPECT_FALSE(ChangeType(device::mojom::WakeLockType::PreventDisplaySleep)); + EXPECT_FALSE( + ChangeType(device::mojom::WakeLockType::PreventDisplaySleepAllowDimming)); #endif }
diff --git a/services/resource_coordinator/observers/tab_signal_generator_impl.cc b/services/resource_coordinator/observers/tab_signal_generator_impl.cc index 3c0f8bca..2c4faf6 100644 --- a/services/resource_coordinator/observers/tab_signal_generator_impl.cc +++ b/services/resource_coordinator/observers/tab_signal_generator_impl.cc
@@ -6,16 +6,15 @@ #include <utility> -#include "base/values.h" #include "services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.h" #include "services/resource_coordinator/coordination_unit/page_coordination_unit_impl.h" #include "services/service_manager/public/cpp/bind_source_info.h" namespace resource_coordinator { -#define DISPATCH_TAB_SIGNAL(observers, METHOD, cu, ...) \ +#define DISPATCH_TAB_SIGNAL(observers, METHOD, ...) \ observers.ForAllPtrs([&](mojom::TabSignalObserver* observer) { \ - observer->METHOD(cu->id(), __VA_ARGS__); \ + observer->METHOD(__VA_ARGS__); \ }); TabSignalGeneratorImpl::TabSignalGeneratorImpl() = default; @@ -43,8 +42,7 @@ return; // TODO(lpy) Combine CPU usage or long task idleness signal. if (auto* page_cu = frame_cu->GetPageCoordinationUnit()) { - DISPATCH_TAB_SIGNAL(observers_, OnEventReceived, page_cu, - mojom::TabEvent::kDoneLoading); + DISPATCH_TAB_SIGNAL(observers_, NotifyPageAlmostIdle, page_cu->id()); } } } @@ -54,8 +52,9 @@ const mojom::PropertyType property_type, int64_t value) { if (property_type == mojom::PropertyType::kExpectedTaskQueueingDuration) { - DISPATCH_TAB_SIGNAL(observers_, OnPropertyChanged, page_cu, property_type, - value); + DISPATCH_TAB_SIGNAL(observers_, SetExpectedTaskQueueingDuration, + page_cu->id(), + base::TimeDelta::FromMilliseconds(value)); } }
diff --git a/services/resource_coordinator/public/interfaces/tab_signal.mojom b/services/resource_coordinator/public/interfaces/tab_signal.mojom index 5fc7c1df..cb7a5e4 100644 --- a/services/resource_coordinator/public/interfaces/tab_signal.mojom +++ b/services/resource_coordinator/public/interfaces/tab_signal.mojom
@@ -5,13 +5,7 @@ module resource_coordinator.mojom; import "coordination_unit.mojom"; -import "mojo/common/values.mojom"; -import "signals.mojom"; - -// Event signal scoped to a tab. -enum TabEvent { - kDoneLoading, -}; +import "mojo/common/time.mojom"; // A TabSignalObserver implementation receives tab-scoped signal from // TabSignalGenerator. @@ -20,9 +14,9 @@ // pass the interface pointer of mojo channel to TabSignalGenerator through // TabSignalGenerator::AddObserver. interface TabSignalObserver { - OnEventReceived(CoordinationUnitID cu_id, TabEvent event); - OnPropertyChanged(CoordinationUnitID cu_id, PropertyType property_type, - int64 value); + NotifyPageAlmostIdle(CoordinationUnitID cu_id); + SetExpectedTaskQueueingDuration(CoordinationUnitID cu_id, + mojo.common.mojom.TimeDelta duration); }; // A TabSignalGenerator implementation will be implemented inside GRC to observe
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls b/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls index bdee97b..fdca0fa 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls +++ b/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls
@@ -193,7 +193,6 @@ crbug.com/417782 paint/invalidation/caret-with-composited-scroll.html [ Failure ] crbug.com/417782 paint/invalidation/change-text-content-and-background-color.html [ Failure ] crbug.com/417782 paint/invalidation/details-open-repaint.html [ Failure ] -crbug.com/417782 paint/invalidation/fixed-child-of-transformed-move-after-scroll.html [ Failure ] crbug.com/417782 paint/invalidation/invalidate-caret-in-composited-scrolling-container.html [ Failure ] crbug.com/417782 paint/invalidation/invalidate-caret-in-non-composited-scrolling-container.html [ Failure ] crbug.com/417782 paint/invalidation/multi-layout-one-frame.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 6672cba4..b5fc9b5 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -291,6 +291,9 @@ ### virtual/layout_ng Mac 1px glyph difference. crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/basic/015.html [ Failure ] +crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/026.html [ Failure ] +crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/028.html [ Failure ] +crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/shrink-to-avoid-float-complexity.html [ Failure ] ### virtual/layout_ng/external/wpt/css/CSS2/floats crbug.com/711704 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-rule3-outside-left-002.xht [ Failure ] @@ -319,7 +322,6 @@ crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/float-applies-to-008.xht [ Failure ] crbug.com/635619 [ Linux ] virtual/layout_ng/external/wpt/css/CSS2/floats-clear/clear-applies-to-012.xht [ Failure ] crbug.com/635619 [ Linux ] virtual/layout_ng/external/wpt/css/CSS2/floats-clear/float-applies-to-012.xht [ Failure ] -crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/float-replaced-width-002.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floating-replaced-height-008.xht [ Skip ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-028.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-036.xht [ Failure ] @@ -350,10 +352,6 @@ crbug.com/636993 [ Linux ] virtual/layout_ng/external/wpt/css/CSS2/linebox/vertical-align-sub-001.xht [ Failure ] crbug.com/636993 [ Linux ] virtual/layout_ng/external/wpt/css/CSS2/linebox/vertical-align-super-001.xht [ Failure ] -# Inline: abspos inline static positions. -crbug.com/636993 virtual/layout_ng/external/wpt/css/CSS2/linebox/vertical-align-baseline-004a.xht [ Failure ] -crbug.com/636993 virtual/layout_ng/external/wpt/css/CSS2/linebox/vertical-align-baseline-005a.xht [ Failure ] - ### virtual/layout_ng/external/wpt/css/CSS2/normal-flow # Block: percent height in continuations. @@ -438,7 +436,6 @@ crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-034.xht [ Skip ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-035.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-036.xht [ Skip ] -crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-static-001.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/positioning-float-001.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/positioning-float-002.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/relpos-calcs-004.xht [ Failure ] @@ -466,7 +463,6 @@ crbug.com/635619 virtual/layout_ng/fast/block/basic/014.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/basic/018.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/basic/020.html [ Failure ] -crbug.com/635619 virtual/layout_ng/fast/block/basic/fieldset-stretch-to-legend.html [ Failure Crash ] crbug.com/635619 virtual/layout_ng/fast/block/basic/quirk-height.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/basic/quirk-percent-height-grandchild.html [ Failure ] crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/basic/text-indent-rtl.html [ Failure ] @@ -480,8 +476,6 @@ crbug.com/635619 virtual/layout_ng/fast/block/float/018.html [ Failure ] crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/020.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/022.html [ Failure ] -crbug.com/635619 virtual/layout_ng/fast/block/float/026.html [ Failure ] -crbug.com/635619 virtual/layout_ng/fast/block/float/028.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/031.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/035.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/assert-when-moving-float.html [ Failure ] @@ -500,9 +494,7 @@ crbug.com/635619 virtual/layout_ng/fast/block/float/float-in-float-painting.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/float-inserted-into-clean-line.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/float-list-changed-before-layout-crash.html [ Crash Pass ] -crbug.com/635619 virtual/layout_ng/fast/block/float/float-not-removed-from-first-letter.html [ Crash Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/float-not-removed-from-next-sibling4.html [ Crash Pass ] -crbug.com/635619 virtual/layout_ng/fast/block/float/float-on-zero-height-line.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/float-overflow-hidden-containing-block-width.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/float-reparent-during-detach-crash.html [ Crash Pass ] crbug.com/635619 virtual/layout_ng/fast/block/float/floats-and-text-indent-rl.html [ Failure ] @@ -523,10 +515,8 @@ crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/intruding-painted-twice.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/line-break-after-white-space-crash.html [ Pass Crash Timeout ] crbug.com/635619 virtual/layout_ng/fast/block/float/logical-bottom-exceeds-layoutunit-max.html [ Failure ] -crbug.com/635619 virtual/layout_ng/fast/block/float/marquee-shrink-to-avoid-floats.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/negative-margin-on-element-avoiding-floats-with-margin-on-parent.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/negative-margin-on-element-avoiding-floats.html [ Failure ] -crbug.com/635619 virtual/layout_ng/fast/block/float/nested-clearance.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/nopaint-after-layer-destruction.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/nopaint-after-layer-destruction2.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/overhanging-float-remove-from-fixed-position-block.html [ Failure ] @@ -536,7 +526,6 @@ crbug.com/635619 virtual/layout_ng/fast/block/float/overhanging-tall-block.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/rubybase-children-moved-crash-2.html [ Failure Crash ] crbug.com/635619 virtual/layout_ng/fast/block/float/rubybase-children-moved-crash.html [ Crash Pass ] -crbug.com/635619 virtual/layout_ng/fast/block/float/shrink-to-avoid-float-complexity.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/trailing-float-with-columns.html [ Crash Failure ] ### virtual/layout_ng/fast/block/margin-collapse @@ -544,7 +533,6 @@ crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/033.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/057.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/103.html [ Failure ] -crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/self-collapsing-cols-creates-block-formatting-context.html [ Failure ] ### virtual/layout_ng/fast/block/margin-collapse/block-inside-inline crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/block-inside-inline/006.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/overflow-with-negative-z-index-child-expected.html b/third_party/WebKit/LayoutTests/compositing/overflow/overflow-with-negative-z-index-child-expected.html new file mode 100644 index 0000000..bbe0163 --- /dev/null +++ b/third_party/WebKit/LayoutTests/compositing/overflow/overflow-with-negative-z-index-child-expected.html
@@ -0,0 +1,3 @@ +<!doctype html> +This test passes if there is a green box. +<div style="width: 100px; height: 100px; background: green;"></div>
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/overflow-with-negative-z-index-child.html b/third_party/WebKit/LayoutTests/compositing/overflow/overflow-with-negative-z-index-child.html new file mode 100644 index 0000000..7add31920 --- /dev/null +++ b/third_party/WebKit/LayoutTests/compositing/overflow/overflow-with-negative-z-index-child.html
@@ -0,0 +1,30 @@ +<!doctype html> +<style> + ::-webkit-scrollbar { + display: none; + } + #scroller { + position: absolute; + width: 400px; + height: 400px; + overflow-y: scroll; + will-change: transform; + } + #container { + transform: translate(0, 0); + } + #rect { + width: 100px; + height: 100px; + background: green; + position: absolute; + z-index: -5; + } +</style> +This test passes if there is a green box. +<div id="scroller"> + <div id="container"> + <div id="rect"></div> + </div> + <div id="forcescroll" style="height: 1000px;"></div> +</div>
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.cpp b/third_party/WebKit/Source/core/frame/UseCounter.cpp index 56a732c..9616543df 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.cpp +++ b/third_party/WebKit/Source/core/frame/UseCounter.cpp
@@ -1192,7 +1192,6 @@ } features_recorded_.QuickSet(feature_id); } - legacy_counter_.CountFeature(feature); } bool UseCounter::HasRecordedMeasurement(WebFeature feature) const { @@ -1242,8 +1241,6 @@ } void UseCounter::DidCommitLoad(const KURL& url) { - legacy_counter_.UpdateMeasurements(); - // Reset state from previous load. // Use the protocol of the document being loaded into the main frame to // decide whether this page is interesting from a metrics perspective. @@ -1346,12 +1343,9 @@ } css_recorded_.QuickSet(property); } - legacy_counter_.CountCSS(property); } void UseCounter::Count(WebFeature feature, const LocalFrame* source_frame) { - // TODO(rbyers): Report UseCounter to browser process along with page - // load metrics for sourceFrame crbug.com/716565 RecordMeasurement(feature, *source_frame); } @@ -1460,70 +1454,4 @@ return context_ == kSVGImageContext ? svg_histogram : histogram; } -/* - * - * LEGACY metrics support - WebCore.FeatureObserver is to be superceded by - * WebCore.UseCounter - * - */ - -static EnumerationHistogram& FeatureObserverHistogram() { - DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, - ("WebCore.FeatureObserver", - static_cast<int32_t>(WebFeature::kNumberOfFeatures))); - return histogram; -} - -UseCounter::LegacyCounter::LegacyCounter() - : feature_bits_(static_cast<int>(WebFeature::kNumberOfFeatures)), - css_bits_(numCSSPropertyIDs) {} - -UseCounter::LegacyCounter::~LegacyCounter() { - // PageDestruction was intended to be used as a scale, but it's broken (due to - // fast shutdown). See https://crbug.com/597963. - FeatureObserverHistogram().Count( - static_cast<int>(WebFeature::kOBSOLETE_PageDestruction)); - UpdateMeasurements(); -} - -void UseCounter::LegacyCounter::CountFeature(WebFeature feature) { - feature_bits_.QuickSet(static_cast<int>(feature)); -} - -void UseCounter::LegacyCounter::CountCSS(CSSPropertyID property) { - css_bits_.QuickSet(property); -} - -void UseCounter::LegacyCounter::UpdateMeasurements() { - EnumerationHistogram& feature_histogram = FeatureObserverHistogram(); - feature_histogram.Count(static_cast<int>(WebFeature::kPageVisits)); - for (size_t i = 0; i < static_cast<int>(WebFeature::kNumberOfFeatures); ++i) { - if (feature_bits_.QuickGet(i)) - feature_histogram.Count(i); - } - // Clearing count bits is timing sensitive. - feature_bits_.ClearAll(); - - // FIXME: Sometimes this function is called more than once per page. The - // following bool guards against incrementing the page count when there are no - // CSS bits set. https://crbug.com/236262. - DEFINE_STATIC_LOCAL( - EnumerationHistogram, css_properties_histogram, - ("WebCore.FeatureObserver.CSSProperties", kMaximumCSSSampleId)); - bool needs_pages_measured_update = false; - for (size_t i = firstCSSProperty; i < numCSSPropertyIDs; ++i) { - if (css_bits_.QuickGet(i)) { - int css_sample_id = MapCSSPropertyIdToCSSSampleIdForHistogram( - static_cast<CSSPropertyID>(i)); - css_properties_histogram.Count(css_sample_id); - needs_pages_measured_update = true; - } - } - - if (needs_pages_measured_update) - css_properties_histogram.Count(totalPagesMeasuredCSSSampleId()); - - css_bits_.ClearAll(); -} - } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h index 7b0b22d3..a6d83e5 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.h +++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -169,31 +169,12 @@ // the duration of a page but can change when a new page is loaded. Context context_; - // Track what features/properties have been reported to the (non-legacy) - // histograms. + // Track what features/properties have been reported to the histograms. BitVector features_recorded_; BitVector css_recorded_; BitVector animated_css_recorded_; HeapHashSet<Member<Observer>> observers_; - - // Encapsulates the work to preserve the old "FeatureObserver" histogram with - // original semantics - // TODO(rbyers): remove this - http://crbug.com/676837 - class CORE_EXPORT LegacyCounter { - public: - LegacyCounter(); - ~LegacyCounter(); - void CountFeature(WebFeature); - void CountCSS(CSSPropertyID); - void UpdateMeasurements(); - - private: - // Tracks what features/properties need to be reported to the legacy - // histograms. - BitVector feature_bits_; - BitVector css_bits_; - } legacy_counter_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/UseCounterTest.cpp b/third_party/WebKit/Source/core/frame/UseCounterTest.cpp index a38c9790..42c634c8 100644 --- a/third_party/WebKit/Source/core/frame/UseCounterTest.cpp +++ b/third_party/WebKit/Source/core/frame/UseCounterTest.cpp
@@ -25,9 +25,6 @@ const char kSVGAnimatedCSSHistogramName[] = "Blink.UseCounter.SVGImage.AnimatedCSSProperties"; -const char kLegacyFeaturesHistogramName[] = "WebCore.FeatureObserver"; -const char kLegacyCSSHistogramName[] = "WebCore.FeatureObserver.CSSProperties"; - // In practice, SVGs always appear to be loaded with an about:blank URL const char kSvgUrl[] = "about:blank"; const char* const kInternalUrl = kSvgUrl; @@ -54,7 +51,6 @@ LocalFrame* GetFrame() { return &dummy_->GetFrame(); } template <typename T> void HistogramBasicTest(const std::string& histogram, - const std::string& legacy_histogram, T item, T second_item, std::function<bool(T)> counted, @@ -69,7 +65,6 @@ template <typename T> void UseCounterTest::HistogramBasicTest( const std::string& histogram, - const std::string& legacy_histogram, T item, T second_item, std::function<bool(T)> counted, @@ -84,16 +79,10 @@ count(item); EXPECT_TRUE(counted(item)); histogram_tester_.ExpectUniqueSample(histogram, histogram_map(item), 1); - if (!legacy_histogram.empty()) { - histogram_tester_.ExpectTotalCount(legacy_histogram, 0); - } // Test that repeated measurements have no effect count(item); histogram_tester_.ExpectUniqueSample(histogram, histogram_map(item), 1); - if (!legacy_histogram.empty()) { - histogram_tester_.ExpectTotalCount(legacy_histogram, 0); - } // Test recording a different sample EXPECT_FALSE(counted(second_item)); @@ -102,9 +91,6 @@ histogram_tester_.ExpectBucketCount(histogram, histogram_map(item), 1); histogram_tester_.ExpectBucketCount(histogram, histogram_map(second_item), 1); histogram_tester_.ExpectTotalCount(histogram, 2); - if (!legacy_histogram.empty()) { - histogram_tester_.ExpectTotalCount(legacy_histogram, 0); - } // After a page load, the histograms will be updated, even when the URL // scheme is internal @@ -114,16 +100,6 @@ histogram_tester_.ExpectBucketCount(histogram, page_visit_bucket, 1); histogram_tester_.ExpectTotalCount(histogram, 3); - // And verify the legacy histogram now looks the same - if (!legacy_histogram.empty()) { - histogram_tester_.ExpectBucketCount(legacy_histogram, histogram_map(item), - 1); - histogram_tester_.ExpectBucketCount(legacy_histogram, - histogram_map(second_item), 1); - histogram_tester_.ExpectBucketCount(legacy_histogram, page_visit_bucket, 1); - histogram_tester_.ExpectTotalCount(legacy_histogram, 3); - } - // Now a repeat measurement should get recorded again, exactly once EXPECT_FALSE(counted(item)); count(item); @@ -132,20 +108,8 @@ histogram_tester_.ExpectBucketCount(histogram, histogram_map(item), 2); histogram_tester_.ExpectTotalCount(histogram, 4); - // And on the next page load, the legacy histogram will again be updated - did_commit_load(URLTestHelpers::ToKURL(url)); - if (!legacy_histogram.empty()) { - histogram_tester_.ExpectBucketCount(legacy_histogram, histogram_map(item), - 2); - histogram_tester_.ExpectBucketCount(legacy_histogram, - histogram_map(second_item), 1); - histogram_tester_.ExpectBucketCount(legacy_histogram, page_visit_bucket, 2); - histogram_tester_.ExpectTotalCount(legacy_histogram, 5); - } - // For all histograms, no other histograms besides |histogram| should - // be affected. Legacy histograms are not included in the list because they - // soon will be removed. + // be affected. for (const std::string& unaffected_histogram : {kAnimatedCSSHistogramName, kCSSHistogramName, kExtensionFeaturesHistogramName, kFeaturesHistogramName, @@ -175,8 +139,7 @@ TEST_F(UseCounterTest, RecordingFeatures) { UseCounter use_counter; HistogramBasicTest<WebFeature>( - kFeaturesHistogramName, kLegacyFeaturesHistogramName, WebFeature::kFetch, - WebFeature::kFetchBodyStream, + kFeaturesHistogramName, WebFeature::kFetch, WebFeature::kFetchBodyStream, [&](WebFeature feature) -> bool { return use_counter.HasRecordedMeasurement(feature); }, @@ -190,8 +153,7 @@ TEST_F(UseCounterTest, RecordingCSSProperties) { UseCounter use_counter; HistogramBasicTest<CSSPropertyID>( - kCSSHistogramName, kLegacyCSSHistogramName, CSSPropertyFont, - CSSPropertyZoom, + kCSSHistogramName, CSSPropertyFont, CSSPropertyZoom, [&](CSSPropertyID property) -> bool { return use_counter.IsCounted(property); }, @@ -207,7 +169,7 @@ TEST_F(UseCounterTest, RecordingAnimatedCSSProperties) { UseCounter use_counter; HistogramBasicTest<CSSPropertyID>( - kAnimatedCSSHistogramName, "", CSSPropertyOpacity, CSSPropertyVariable, + kAnimatedCSSHistogramName, CSSPropertyOpacity, CSSPropertyVariable, [&](CSSPropertyID property) -> bool { return use_counter.IsCountedAnimatedCSS(property); }, @@ -221,8 +183,8 @@ TEST_F(UseCounterTest, RecordingExtensions) { UseCounter use_counter(UseCounter::kExtensionContext); HistogramBasicTest<WebFeature>( - kExtensionFeaturesHistogramName, kLegacyFeaturesHistogramName, - WebFeature::kFetch, WebFeature::kFetchBodyStream, + kExtensionFeaturesHistogramName, WebFeature::kFetch, + WebFeature::kFetchBodyStream, [&](WebFeature feature) -> bool { return use_counter.HasRecordedMeasurement(feature); }, @@ -236,8 +198,7 @@ TEST_F(UseCounterTest, SVGImageContextFeatures) { UseCounter use_counter(UseCounter::kSVGImageContext); HistogramBasicTest<WebFeature>( - kSVGFeaturesHistogramName, kLegacyFeaturesHistogramName, - WebFeature::kSVGSMILAdditiveAnimation, + kSVGFeaturesHistogramName, WebFeature::kSVGSMILAdditiveAnimation, WebFeature::kSVGSMILAnimationElementTiming, [&](WebFeature feature) -> bool { return use_counter.HasRecordedMeasurement(feature); @@ -252,8 +213,7 @@ TEST_F(UseCounterTest, SVGImageContextCSSProperties) { UseCounter use_counter(UseCounter::kSVGImageContext); HistogramBasicTest<CSSPropertyID>( - kSVGCSSHistogramName, kLegacyCSSHistogramName, CSSPropertyFont, - CSSPropertyZoom, + kSVGCSSHistogramName, CSSPropertyFont, CSSPropertyZoom, [&](CSSPropertyID property) -> bool { return use_counter.IsCounted(property); }, @@ -269,7 +229,7 @@ TEST_F(UseCounterTest, SVGImageContextAnimatedCSSProperties) { UseCounter use_counter(UseCounter::kSVGImageContext); HistogramBasicTest<CSSPropertyID>( - kSVGAnimatedCSSHistogramName, "", CSSPropertyOpacity, CSSPropertyVariable, + kSVGAnimatedCSSHistogramName, CSSPropertyOpacity, CSSPropertyVariable, [&](CSSPropertyID property) -> bool { return use_counter.IsCountedAnimatedCSS(property); },
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp index f12bc688..f34ffac 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
@@ -858,6 +858,7 @@ paint_flags &= ~kPaintLayerPaintingSkipRootBackground; // When painting a new root we are no longer painting overflow contents. paint_flags &= ~kPaintLayerPaintingOverflowContents; + paint_flags &= ~kPaintLayerPaintingCompositingScrollingPhase; } return PaintLayerContentsCompositingAllPhases(
diff --git a/third_party/webrtc_overrides/BUILD.gn b/third_party/webrtc_overrides/BUILD.gn index c15bd14..7c938eb 100644 --- a/third_party/webrtc_overrides/BUILD.gn +++ b/third_party/webrtc_overrides/BUILD.gn
@@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromecast_build.gni") + group("webrtc_overrides") { public_deps = [ ":webrtc", @@ -59,11 +61,14 @@ } if (is_nacl) { - # For NACL, we have to add a default implementation for field_trail. + # For NACL, we have to add a default implementation for field_trial. deps += [ "//native_client_sdk/src/libraries/nacl_io", "//third_party/webrtc/system_wrappers:field_trial_default", ] + } else if (is_chromecast) { + # Cast builds use the default implementation for field_trial. + deps += [ "//third_party/webrtc/system_wrappers:field_trial_default" ] } else { # Otherwise, we just add the field_trial which redirects to base. sources = [
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 5ff09a1..edcbfa4 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -68393,6 +68393,126 @@ </summary> </histogram> +<histogram name="RenderFrameObservers.DidChangeScrollOffset" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + Cumulative time spent by all RenderFrameObservers in + RenderFrameImpl.DidChangeScrollOffset. + </summary> +</histogram> + +<histogram name="RenderFrameObservers.DidClearWindowObject" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + Cumulative time spent by all RenderFrameObservers in + RenderFrameImpl.DidClearWindowObject. + </summary> +</histogram> + +<histogram name="RenderFrameObservers.DidCommitProvisionalLoad" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + Cumulative time spent by all RenderFrameObservers in + RenderFrameImpl.DidCommitProvisionalLoad. + </summary> +</histogram> + +<histogram name="RenderFrameObservers.DidCreateScriptContext" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + Cumulative time spent by all RenderFrameObservers in + RenderFrameImpl.DidCreateScriptContext. + </summary> +</histogram> + +<histogram name="RenderFrameObservers.DidFailProvisionalLoad" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + Cumulative time spent by all RenderFrameObservers in + RenderFrameImpl.DidFailProvisionalLoad. + </summary> +</histogram> + +<histogram name="RenderFrameObservers.DidFinishDocumentLoad" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + Cumulative time spent by all RenderFrameObservers in + RenderFrameImpl.DidFinishDocumentLoad. + </summary> +</histogram> + +<histogram name="RenderFrameObservers.DidFinishLoad" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + Cumulative time spent by all RenderFrameObservers in + RenderFrameImpl.DidFinishLoad. + </summary> +</histogram> + +<histogram name="RenderFrameObservers.DidMeaningfulLayout" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + Cumulative time spent by all RenderFrameObservers in + RenderFrameImpl.DidMeaningfulLayout. + </summary> +</histogram> + +<histogram name="RenderFrameObservers.DidStartProvisionalLoad" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + Cumulative time spent by all RenderFrameObservers in + RenderFrameImpl.DidStartProvisionalLoad. + </summary> +</histogram> + +<histogram name="RenderFrameObservers.FocusedNodeChanged" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + Cumulative time spent by all RenderFrameObservers in + RenderFrameImpl.FocusedNodeChanged. + </summary> +</histogram> + +<histogram name="RenderFrameObservers.OnMessageReceived" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + Cumulative time spent by all RenderFrameObservers in + RenderFrameImpl.OnMessageReceived. + </summary> +</histogram> + +<histogram name="RenderFrameObservers.ScriptedPrint" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + Cumulative time spent by all RenderFrameObservers in + RenderFrameImpl.ScriptedPrint. + </summary> +</histogram> + +<histogram name="RenderFrameObservers.WillCommitProvisionalLoad" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + Cumulative time spent by all RenderFrameObservers in + RenderFrameImpl.WillCommitProvisionalLoad. + </summary> +</histogram> + +<histogram name="RenderFrameObservers.WillSendSubmitEvent" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + Cumulative time spent by all RenderFrameObservers in + RenderFrameImpl.WillSendSubmitEvent. + </summary> +</histogram> + +<histogram name="RenderFrameObservers.WillSubmitForm" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + Cumulative time spent by all RenderFrameObservers in + RenderFrameImpl.WillSubmitForm. + </summary> +</histogram> + <histogram name="RenderViewContextMenu.OpenLinkAsUser" enum="OpenLinkAsUser"> <owner>jochen@chromium.org</owner> <summary> @@ -87634,6 +87754,14 @@ </summary> </histogram> +<histogram name="Translate.PageCaptured" units="ms"> + <owner>joelhockey@chromium.org</owner> + <summary> + The time spent capturing plain text from the DOM. This is reported by + ChromeRenderViewObserver when a page is loaded completely. + </summary> +</histogram> + <histogram name="Translate.PageScheme" enum="TranslateScheme"> <owner>kenjibaheux@google.com</owner> <summary>Counts translation target page schemes.</summary> @@ -92134,11 +92262,12 @@ </histogram> <histogram name="WebCore.FeatureObserver" enum="FeatureObserver"> + <obsolete> + As of M57 this has been superseded by Blink.UseCounter.Features which fixes + a number of issues. See https://crbug.com/676837. + </obsolete> <owner>rbyers@chromium.org</owner> <summary> - NOTE: As of M57 this has been superseded by Blink.UseCounter.Features which - fixes a number of issues. See https://crbug.com/676837. - Count of how many page loads use various features. The PageVisits bucket is incremented for each page load, and the other buckets incremented at most once per PageVisit via the WebCore::UseCounter class. @@ -92147,37 +92276,17 @@ <histogram name="WebCore.FeatureObserver.CSSProperties" enum="MappedCSSProperties"> + <obsolete> + As of M57 this has been superseded by Blink.UseCounter.CSSProperties which + fixes a number of issues. See https://crbug.com/676837. + </obsolete> <owner>mikelawther@chromium.org</owner> <summary> - NOTE: As of M57 this has been superseded by Blink.UseCounter.Features which - fixes a number of issues. See https://crbug.com/676837. - Records usage of CSS properties used on a page, either statically or dynamically, from the time the page is initialised to when it is closed or navigated away from. Each property is counted at most once per page per view. </summary> - <details> - Every time a CSS property is parsed on a page, that property is recorded as - having been used. The histogram is updated with this data whenever a page is - closed, or a page navigation happens. Each histogram bucket corresponds to a - CSS property (eg width, border-radius). The exception is the bucket numbered - '1' - this counts the number of pages that CSS properties were counted on. - - These numbers give the percentage of pages that use a CSS property. For - example, if the 'border-radius' histogram bucket has a count of 250, and the - page count bucket (i.e. bucket number 1) has a count of 1000 - this means - that 1000 pages were recorded, and border-radius was used on 25% of those - pages. - - Internally, each WebCore::Page has a WebCore::UseCounter instance, with - booleans recording use of each CSS property - one boolean per property. Upon - destruction of the WebCore::Page (e.g. by the user closing the tab), or a - page navigation happening, the histogram is updated. For each boolean that - is set to True, the corresponding histogram bucket for that CSS property is - incremented by 1. The page count bucket (i.e. bucket number 1) is always - incremented by 1 on each histogram update. - </details> </histogram> <histogram name="WebCore.Framebust" enum="FramebustPermissions">
diff --git a/ui/gl/gl_context_glx_unittest.cc b/ui/gl/gl_context_glx_unittest.cc index 3fe50e1..c9e1885 100644 --- a/ui/gl/gl_context_glx_unittest.cc +++ b/ui/gl/gl_context_glx_unittest.cc
@@ -16,7 +16,7 @@ namespace gl { -TEST(GLContextGLXTest, DoNotDesrtroyOnFailedMakeCurrent) { +TEST(GLContextGLXTest, DISABLED_DoNotDesrtroyOnFailedMakeCurrent) { auto* xdisplay = gfx::GetXDisplay(); ASSERT_TRUE(xdisplay);
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.html b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.html index 783160c8..9e3f9063 100644 --- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.html +++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.html
@@ -151,7 +151,7 @@ <div> <button is="paper-icon-button-light" id="switchMode" tabindex="2" title="[[switchModeLabel]]" on-tap="onTapSwitchMode_" - disabled="[[!cameraOnline_]]" hidden="[[!videomodeEnabled]]"> + disabled="[[!cameraOnline_]]" hidden="[[!videoModeEnabled]]"> </button> </div> </div>
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js index 93d4ec9..dcd91808 100644 --- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js +++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js
@@ -38,7 +38,7 @@ switchModeLabel: String, /** True if video mode is enabled. */ - videomodeEnabled: { + videoModeEnabled: { type: Boolean, value: false, },
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.html b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.html index a6c95a4..2ace7f7 100644 --- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.html +++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.html
@@ -76,7 +76,8 @@ <template is="dom-if" if="[[cameraActive_]]"> <cr-camera id="camera" take-photo-label="[[takePhotoLabel]]" - switch-mode-label="[[switchModeLabel]]"> + switch-mode-label="[[switchModeLabel]]" + video-mode-enabled="[[cameraVideoModeEnabled]]"> </cr-camera> </template> </template>
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.js b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.js index d8a830c..9f8a5fd 100644 --- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.js +++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_pane.js
@@ -45,6 +45,9 @@ takePhotoLabel: String, switchModeLabel: String, + /** Whether camera video mode is enabled */ + cameraVideoModeEnabled: Boolean, + /** Whether the camera should be shown and active (started). */ cameraActive_: { type: Boolean,
diff --git a/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.js b/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.js index eb4d0dff..e604c76 100644 --- a/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.js +++ b/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.js
@@ -50,6 +50,12 @@ reflectToAttribute: true, computed: 'getItemName_(item)', }, + + /** + * The cached ConnectionState for the network. + * @type {!CrOnc.ConnectionState|undefined} + */ + connectionState_: String, }, behaviors: [CrPolicyNetworkBehavior], @@ -66,10 +72,14 @@ /** @private */ networkStateChanged_: function() { - if (this.networkState && - this.networkState.ConnectionState == CrOnc.ConnectionState.CONNECTED) { + if (!this.networkState) + return; + var connectionState = this.networkState.ConnectionState; + if (connectionState == this.connectionState_) + return; + this.connectionState_ = connectionState; + if (connectionState == CrOnc.ConnectionState.CONNECTED) this.fire('network-connected', this.networkState); - } }, /**