123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- // Copyright (c) 2012 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_ACCELERATORS_ACCELERATOR_CONTROLLER_IMPL_H_
- #define ASH_ACCELERATORS_ACCELERATOR_CONTROLLER_IMPL_H_
- #include <stddef.h>
- #include <map>
- #include <memory>
- #include <set>
- #include <vector>
- #include "ash/accelerators/accelerator_history_impl.h"
- #include "ash/accelerators/accelerator_table.h"
- #include "ash/accelerators/exit_warning_handler.h"
- #include "ash/accessibility/ui/accessibility_confirmation_dialog.h"
- #include "ash/ash_export.h"
- #include "ash/public/cpp/accelerators.h"
- #include "base/gtest_prod_util.h"
- #include "ui/base/accelerators/accelerator.h"
- #include "ui/base/accelerators/accelerator_map.h"
- #include "ui/base/ime/ash/input_method_manager.h"
- namespace ui {
- class AcceleratorManager;
- }
- namespace ash {
- struct AcceleratorData;
- class ExitWarningHandler;
- // See TabletModeVolumeAdjustType at tools/metrics/histograms/enums.xml.
- enum class TabletModeVolumeAdjustType {
- kAccidentalAdjustWithSwapEnabled = 0,
- kNormalAdjustWithSwapEnabled = 1,
- kAccidentalAdjustWithSwapDisabled = 2,
- kNormalAdjustWithSwapDisabled = 3,
- kMaxValue = kNormalAdjustWithSwapDisabled,
- };
- // These values are persisted to logs. Entries should not be renumbered and
- // numeric values should never be reused.
- // Captures usage of Alt+[ and Alt+].
- enum class WindowSnapAcceleratorAction {
- kCycleLeftSnapInClamshellNoOverview = 0,
- kCycleLeftSnapInClamshellOverview = 1,
- kCycleLeftSnapInTablet = 2,
- kCycleRightSnapInClamshellNoOverview = 3,
- kCycleRightSnapInClamshellOverview = 4,
- kCycleRightSnapInTablet = 5,
- kMaxValue = kCycleRightSnapInTablet,
- };
- // Histogram for volume adjustment in tablet mode.
- ASH_EXPORT extern const char kTabletCountOfVolumeAdjustType[];
- // UMA accessibility histogram names.
- ASH_EXPORT extern const char kAccessibilityHighContrastShortcut[];
- ASH_EXPORT extern const char kAccessibilitySpokenFeedbackShortcut[];
- ASH_EXPORT extern const char kAccessibilityScreenMagnifierShortcut[];
- ASH_EXPORT extern const char kAccessibilityDockedMagnifierShortcut[];
- // Name of histogram corresponding to |WindowSnapAcceleratorAction|.
- ASH_EXPORT extern const char kAccelWindowSnap[];
- // AcceleratorControllerImpl provides functions for registering or unregistering
- // global keyboard accelerators, which are handled earlier than any windows. It
- // also implements several handlers as an accelerator target.
- class ASH_EXPORT AcceleratorControllerImpl
- : public ui::AcceleratorTarget,
- public AcceleratorController,
- public input_method::InputMethodManager::Observer {
- public:
- // Some Chrome OS devices have volume up and volume down buttons on their
- // side. We want the button that's closer to the top/right to increase the
- // volume and the button that's closer to the bottom/left to decrease the
- // volume, so we use the buttons' location and the device orientation to
- // determine whether the buttons should be swapped.
- struct SideVolumeButtonLocation {
- // The button can be at the side of the keyboard or the display. Then value
- // of the region could be kVolumeButtonRegionKeyboard or
- // kVolumeButtonRegionScreen.
- std::string region;
- // Side info of region. The value could be kVolumeButtonSideLeft,
- // kVolumeButtonSideRight, kVolumeButtonSideTop or kVolumeButtonSideBottom.
- std::string side;
- };
- // TestApi is used for tests to get internal implementation details.
- class TestApi {
- public:
- explicit TestApi(AcceleratorControllerImpl* controller);
- TestApi(const TestApi&) = delete;
- TestApi& operator=(const TestApi&) = delete;
- ~TestApi() = default;
- // If |controller_->tablet_mode_volume_adjust_timer_| is running, stops it,
- // runs its task, and returns true. Otherwise returns false.
- [[nodiscard]] bool TriggerTabletModeVolumeAdjustTimer();
- // Registers the specified accelerators.
- void RegisterAccelerators(const AcceleratorData accelerators[],
- size_t accelerators_length);
- // Returns whether the action for this accelerator is enabled.
- bool IsActionForAcceleratorEnabled(const ui::Accelerator& accelerator);
- // Returns the corresponding accelerator data if |action| maps to a
- // deprecated accelerator, otherwise return nullptr.
- const DeprecatedAcceleratorData* GetDeprecatedAcceleratorData(
- AcceleratorAction action);
- // Accessor to accelerator confirmation dialog.
- AccessibilityConfirmationDialog* GetConfirmationDialog();
- // Provides access to the ExitWarningHandler.
- ExitWarningHandler* GetExitWarningHandler();
- AcceleratorControllerImpl::SideVolumeButtonLocation
- side_volume_button_location() {
- return controller_->side_volume_button_location_;
- }
- void SetSideVolumeButtonFilePath(base::FilePath path);
- void SetSideVolumeButtonLocation(const std::string& region,
- const std::string& side);
- private:
- AcceleratorControllerImpl* controller_; // Not owned.
- };
- // Fields of the side volume button location info.
- static constexpr const char* kVolumeButtonRegion = "region";
- static constexpr const char* kVolumeButtonSide = "side";
- // Values of kVolumeButtonRegion.
- static constexpr const char* kVolumeButtonRegionKeyboard = "keyboard";
- static constexpr const char* kVolumeButtonRegionScreen = "screen";
- // Values of kVolumeButtonSide.
- static constexpr const char* kVolumeButtonSideLeft = "left";
- static constexpr const char* kVolumeButtonSideRight = "right";
- static constexpr const char* kVolumeButtonSideTop = "top";
- static constexpr const char* kVolumeButtonSideBottom = "bottom";
- AcceleratorControllerImpl();
- AcceleratorControllerImpl(const AcceleratorControllerImpl&) = delete;
- AcceleratorControllerImpl& operator=(const AcceleratorControllerImpl&) =
- delete;
- ~AcceleratorControllerImpl() override;
- // A list of possible ways in which an accelerator should be restricted before
- // processing. Any target registered with this controller should respect
- // restrictions by calling GetAcceleratorProcessingRestriction() during
- // processing.
- enum AcceleratorProcessingRestriction {
- // Process the accelerator normally.
- RESTRICTION_NONE,
- // Don't process the accelerator.
- RESTRICTION_PREVENT_PROCESSING,
- // Don't process the accelerator and prevent propagation to other targets.
- RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION
- };
- // input_method::InputMethodManager::Observer overrides:
- void InputMethodChanged(input_method::InputMethodManager* manager,
- Profile* profile,
- bool show_message) override;
- // Registers global keyboard accelerators for the specified target. If
- // multiple targets are registered for any given accelerator, a target
- // registered later has higher priority.
- void Register(const std::vector<ui::Accelerator>& accelerators,
- ui::AcceleratorTarget* target);
- // Unregisters the specified keyboard accelerator for the specified target.
- void Unregister(const ui::Accelerator& accelerator,
- ui::AcceleratorTarget* target);
- // Unregisters all keyboard accelerators for the specified target.
- void UnregisterAll(ui::AcceleratorTarget* target);
- // AcceleratorControllerImpl:
- bool Process(const ui::Accelerator& accelerator) override;
- bool IsDeprecated(const ui::Accelerator& accelerator) const override;
- bool PerformActionIfEnabled(AcceleratorAction action,
- const ui::Accelerator& accelerator) override;
- bool OnMenuAccelerator(const ui::Accelerator& accelerator) override;
- bool IsRegistered(const ui::Accelerator& accelerator) const override;
- AcceleratorHistoryImpl* GetAcceleratorHistory() override;
- bool DoesAcceleratorMatchAction(const ui::Accelerator& accelerator,
- AcceleratorAction action) override;
- // Returns true if the |accelerator| is preferred. A preferred accelerator
- // is handled before being passed to an window/web contents, unless
- // the window is in fullscreen state.
- bool IsPreferred(const ui::Accelerator& accelerator) const;
- // Returns true if the |accelerator| is reserved. A reserved accelerator
- // is always handled and will never be passed to an window/web contents.
- bool IsReserved(const ui::Accelerator& accelerator) const;
- // Provides access to the ExitWarningHandler for testing.
- ExitWarningHandler* GetExitWarningHandlerForTest() {
- return &exit_warning_handler_;
- }
- // Overridden from ui::AcceleratorTarget:
- bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
- bool CanHandleAccelerators() const override;
- // A confirmation dialog will be shown the first time an accessibility feature
- // is enabled using the specified accelerator key sequence. Only one dialog
- // will be shown at a time, and will not be shown again if the user has
- // selected "accept" on a given dialog. The dialog was added to ensure that
- // users would be aware of the shortcut they have just enabled, and to prevent
- // users from accidentally triggering the feature. The dialog is currently
- // shown when enabling the following features: high contrast, full screen
- // magnifier, docked magnifier and screen rotation. The shown dialog is stored
- // as a weak pointer in the variable |confirmation_dialog_| below.
- void MaybeShowConfirmationDialog(int window_title_text_id,
- int dialog_text_id,
- base::OnceClosure on_accept_callback,
- base::OnceClosure on_cancel_callback);
- private:
- // A map for looking up actions from accelerators.
- using AcceleratorActionMap = ui::AcceleratorMap<AcceleratorAction>;
- // Initializes the accelerators this class handles as a target.
- void Init();
- // Registers the specified accelerators.
- void RegisterAccelerators(const AcceleratorData accelerators[],
- size_t accelerators_length);
- // Registers the deprecated accelerators and their replacing new ones.
- void RegisterDeprecatedAccelerators();
- // Returns true if there is an action for |accelerator| and it is enabled.
- bool IsActionForAcceleratorEnabled(const ui::Accelerator& accelerator) const;
- // Returns whether |action| can be performed. The |accelerator| may provide
- // additional data the action needs.
- bool CanPerformAction(AcceleratorAction action,
- const ui::Accelerator& accelerator) const;
- // Performs the specified action. The |accelerator| may provide additional
- // data the action needs.
- void PerformAction(AcceleratorAction action,
- const ui::Accelerator& accelerator);
- // Returns whether performing |action| should consume the key event.
- bool ShouldActionConsumeKeyEvent(AcceleratorAction action);
- // Get the accelerator restriction for the given action. Supply an |action|
- // of -1 to get restrictions that apply for the current context.
- AcceleratorProcessingRestriction GetAcceleratorProcessingRestriction(
- int action) const;
- // If |accelerator| is a deprecated accelerator, it performs the appropriate
- // deprecated accelerator pre-handling.
- // Returns PROCEED if the accelerator's action should be performed (i.e. if
- // |accelerator| is not a deprecated accelerator, or it's an enabled
- // deprecated accelerator), and STOP otherwise (if the accelerator is a
- // disabled deprecated accelerator).
- enum class AcceleratorProcessingStatus { PROCEED, STOP };
- AcceleratorProcessingStatus MaybeDeprecatedAcceleratorPressed(
- AcceleratorAction action,
- const ui::Accelerator& accelerator) const;
- // Returns true if |source_device_id| corresponds to the internal keyboard or
- // an internal uncategorized input device.
- bool IsInternalKeyboardOrUncategorizedDevice(int source_device_id) const;
- // Returns true if |side_volume_button_location_| is in agreed format and
- // values.
- bool IsValidSideVolumeButtonLocation() const;
- // Returns true if the side volume buttons should be swapped. See
- // SideVolumeButonLocation for the details.
- bool ShouldSwapSideVolumeButtons(int source_device_id) const;
- // Read the side volume button location info from local file under
- // kSideVolumeButtonLocationFilePath, parse and write it into
- // |side_volume_button_location_|.
- void ParseSideVolumeButtonLocationInfo();
- // The metrics recorded include accidental volume adjustments (defined as a
- // sequence of volume button events in close succession starting with a
- // volume-up event but ending with an overall-decreased volume, or vice versa)
- // or normal volume adjustments w/o SwapSideVolumeButtonsForOrientation
- // feature enabled.
- void UpdateTabletModeVolumeAdjustHistogram();
- // Starts |tablet_mode_volume_adjust_timer_| while see VOLUME_UP or
- // VOLUME_DOWN acceleration action when in tablet mode.
- void StartTabletModeVolumeAdjustTimer(AcceleratorAction action);
- std::unique_ptr<ui::AcceleratorManager> accelerator_manager_;
- // A tracker for the current and previous accelerators.
- std::unique_ptr<AcceleratorHistoryImpl> accelerator_history_;
- // Handles the exit accelerator which requires a double press to exit and
- // shows a popup with an explanation.
- ExitWarningHandler exit_warning_handler_;
- // A map from accelerators to the AcceleratorAction values, which are used in
- // the implementation.
- AcceleratorActionMap accelerators_;
- std::map<AcceleratorAction, const DeprecatedAcceleratorData*>
- actions_with_deprecations_;
- std::set<ui::Accelerator> deprecated_accelerators_;
- // Actions allowed when the user is not signed in.
- std::set<int> actions_allowed_at_login_screen_;
- // Actions allowed when the screen is locked.
- std::set<int> actions_allowed_at_lock_screen_;
- // Actions allowed when the power menu is opened.
- std::set<int> actions_allowed_at_power_menu_;
- // Actions allowed when a modal window is up.
- std::set<int> actions_allowed_at_modal_window_;
- // Preferred actions. See accelerator_table.h for details.
- std::set<int> preferred_actions_;
- // Reserved actions. See accelerator_table.h for details.
- std::set<int> reserved_actions_;
- // Actions which will be repeated while holding the accelerator key.
- std::set<int> repeatable_actions_;
- // Actions allowed in app mode.
- std::set<int> actions_allowed_in_app_mode_;
- // Actions allowed in pinned mode.
- std::set<int> actions_allowed_in_pinned_mode_;
- // Actions disallowed if there are no windows.
- std::set<int> actions_needing_window_;
- // Actions that can be performed without closing the menu (if one is present).
- std::set<int> actions_keeping_menu_open_;
- // Holds a weak pointer to the accessibility confirmation dialog.
- base::WeakPtr<AccessibilityConfirmationDialog> confirmation_dialog_;
- // Path of the file that contains the side volume button location info. It
- // should always be kSideVolumeButtonLocationFilePath. But it is allowed to be
- // set to different paths in test.
- base::FilePath side_volume_button_location_file_path_;
- // Stores the location info of side volume buttons.
- SideVolumeButtonLocation side_volume_button_location_;
- // Started when VOLUME_DOWN or VOLUME_UP accelerator action is seen while in
- // tablet mode. Runs UpdateTabletModeVolumeAdjustHistogram() to record
- // metrics.
- base::OneShotTimer tablet_mode_volume_adjust_timer_;
- // True if volume adjust starts with VOLUME_UP action.
- bool volume_adjust_starts_with_up_ = false;
- // The initial volume percentage when volume adjust starts.
- int initial_volume_percent_ = 0;
- };
- } // namespace ash
- #endif // ASH_ACCELERATORS_ACCELERATOR_CONTROLLER_IMPL_H_
|