Commit f24d0db6 authored by Min Chen's avatar Min Chen Committed by Commit Bot

Read side volume button location info from file into Accelerator.

Bug: 937907
Change-Id: I4341c58bc0f0dc22938d4e58711827b033ec1965
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1565627
Commit-Queue: Min Chen <minch@chromium.org>
Reviewed-by: default avatarDan Erat <derat@chromium.org>
Cr-Commit-Position: refs/heads/master@{#651779}
parent cc7e1e27
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
#include "ash/wm/wm_event.h" #include "ash/wm/wm_event.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics.h"
#include "base/optional.h" #include "base/optional.h"
...@@ -111,6 +112,10 @@ using message_center::SystemNotificationWarningLevel; ...@@ -111,6 +112,10 @@ using message_center::SystemNotificationWarningLevel;
const char kVoiceInteractionErrorToastId[] = "voice_interaction_error"; const char kVoiceInteractionErrorToastId[] = "voice_interaction_error";
const int kToastDurationMs = 2500; const int kToastDurationMs = 2500;
// Path of the json file that contains side volume button location info.
const char kSideVolumeButtonLocationFilePath[] =
"/usr/share/chromeos-assets/side_volume_button/location.json";
// Ensures that there are no word breaks at the "+"s in the shortcut texts such // Ensures that there are no word breaks at the "+"s in the shortcut texts such
// as "Ctrl+Shift+Space". // as "Ctrl+Shift+Space".
void EnsureNoWordBreaks(base::string16* shortcut_text) { void EnsureNoWordBreaks(base::string16* shortcut_text) {
...@@ -1020,13 +1025,26 @@ void HandleTouchHudModeChange() { ...@@ -1020,13 +1025,26 @@ void HandleTouchHudModeChange() {
} // namespace } // namespace
constexpr const char* AcceleratorController::kVolumeButtonRegion;
constexpr const char* AcceleratorController::kVolumeButtonSide;
constexpr const char* AcceleratorController::kVolumeButtonRegionKeyboard;
constexpr const char* AcceleratorController::kVolumeButtonRegionScreen;
constexpr const char* AcceleratorController::kVolumeButtonSideLeft;
constexpr const char* AcceleratorController::kVolumeButtonSideRight;
constexpr const char* AcceleratorController::kVolumeButtonSideTop;
constexpr const char* AcceleratorController::kVolumeButtonSideBottom;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// AcceleratorController, public: // AcceleratorController, public:
AcceleratorController::AcceleratorController() AcceleratorController::AcceleratorController()
: accelerator_manager_(std::make_unique<ui::AcceleratorManager>()), : accelerator_manager_(std::make_unique<ui::AcceleratorManager>()),
accelerator_history_(std::make_unique<ui::AcceleratorHistory>()) { accelerator_history_(std::make_unique<ui::AcceleratorHistory>()),
side_volume_button_location_file_path_(
base::FilePath(kSideVolumeButtonLocationFilePath)) {
Init(); Init();
ParseSideVolumeButtonLocationInfo();
} }
AcceleratorController::~AcceleratorController() = default; AcceleratorController::~AcceleratorController() = default;
...@@ -1408,11 +1426,12 @@ void AcceleratorController::PerformAction(AcceleratorAction action, ...@@ -1408,11 +1426,12 @@ void AcceleratorController::PerformAction(AcceleratorAction action,
if (restriction != RESTRICTION_NONE) if (restriction != RESTRICTION_NONE)
return; return;
// TODO(minch): For VOLUME_DOWN and VOLUME_UP. Do the calculation based on // TODO(minch): For VOLUME_DOWN and VOLUME_UP. Check whether the action is
// accelerator.source_device_id() and // from side volume button based on accelerator.source_device_id() and
// ui::InputDeviceManager::GetInstance()->GetOtherInputDevices() to see // ui::InputDeviceManager::GetInstance()->GetUncategorizedDevices(). Do the
// whether we need to flip its action on current screen orientation for side // calculation whether we need to flip its action on
// volume button. http://crbug.com/937907. // SideVolumeButtonLocation and current screen orientation.
// http://crbug.com/937907.
// If your accelerator invokes more than one line of code, please either // If your accelerator invokes more than one line of code, please either
// implement it in your module's controller code or pull it into a HandleFoo() // implement it in your module's controller code or pull it into a HandleFoo()
...@@ -1834,9 +1853,24 @@ void AcceleratorController::MaybeShowConfirmationDialog( ...@@ -1834,9 +1853,24 @@ void AcceleratorController::MaybeShowConfirmationDialog(
confirmation_dialog_ = dialog->GetWeakPtr(); confirmation_dialog_ = dialog->GetWeakPtr();
} }
AcceleratorConfirmationDialog* void AcceleratorController::ParseSideVolumeButtonLocationInfo() {
AcceleratorController::confirmation_dialog_for_testing() { if (!base::PathExists(side_volume_button_location_file_path_))
return confirmation_dialog_.get(); return;
std::string location_info;
if (!base::ReadFileToString(side_volume_button_location_file_path_,
&location_info) ||
location_info.empty()) {
return;
}
std::unique_ptr<base::DictionaryValue> info_in_dict =
base::DictionaryValue::From(
base::JSONReader::ReadDeprecated(location_info));
info_in_dict->GetString(kVolumeButtonRegion,
&side_volume_button_location_.region);
info_in_dict->GetString(kVolumeButtonSide,
&side_volume_button_location_.side);
} }
} // namespace ash } // namespace ash
...@@ -45,6 +45,19 @@ ASH_EXPORT extern const char kFullscreenMagnifierToggleAccelNotificationId[]; ...@@ -45,6 +45,19 @@ ASH_EXPORT extern const char kFullscreenMagnifierToggleAccelNotificationId[];
class ASH_EXPORT AcceleratorController : public ui::AcceleratorTarget, class ASH_EXPORT AcceleratorController : public ui::AcceleratorTarget,
public mojom::AcceleratorController { public mojom::AcceleratorController {
public: public:
// 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";
AcceleratorController(); AcceleratorController();
~AcceleratorController() override; ~AcceleratorController() override;
...@@ -63,6 +76,21 @@ class ASH_EXPORT AcceleratorController : public ui::AcceleratorTarget, ...@@ -63,6 +76,21 @@ class ASH_EXPORT AcceleratorController : public ui::AcceleratorTarget,
RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION
}; };
// 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;
};
// Registers global keyboard accelerators for the specified target. If // Registers global keyboard accelerators for the specified target. If
// multiple targets are registered for any given accelerator, a target // multiple targets are registered for any given accelerator, a target
// registered later has higher priority. // registered later has higher priority.
...@@ -148,8 +176,22 @@ class ASH_EXPORT AcceleratorController : public ui::AcceleratorTarget, ...@@ -148,8 +176,22 @@ class ASH_EXPORT AcceleratorController : public ui::AcceleratorTarget,
int dialog_text_id, int dialog_text_id,
base::OnceClosure on_accept_callback); base::OnceClosure on_accept_callback);
// Read the side volume button location info from local file under
// kSideVolumeButtonLocationFilePath, parse and write it into
// |side_volume_button_location_|.
void ParseSideVolumeButtonLocationInfo();
// Accessor to accelerator confirmation dialog. // Accessor to accelerator confirmation dialog.
AcceleratorConfirmationDialog* confirmation_dialog_for_testing(); AcceleratorConfirmationDialog* confirmation_dialog_for_testing() {
return confirmation_dialog_.get();
}
void set_side_volume_button_file_path_for_testing(base::FilePath path) {
side_volume_button_location_file_path_ = path;
}
SideVolumeButtonLocation side_volume_button_location_for_testing() {
return side_volume_button_location_;
}
private: private:
FRIEND_TEST_ALL_PREFIXES(AcceleratorControllerTest, GlobalAccelerators); FRIEND_TEST_ALL_PREFIXES(AcceleratorControllerTest, GlobalAccelerators);
...@@ -249,6 +291,14 @@ class ASH_EXPORT AcceleratorController : public ui::AcceleratorTarget, ...@@ -249,6 +291,14 @@ class ASH_EXPORT AcceleratorController : public ui::AcceleratorTarget,
// Holds a weak pointer to the accelerator confirmation dialog. // Holds a weak pointer to the accelerator confirmation dialog.
base::WeakPtr<AcceleratorConfirmationDialog> confirmation_dialog_; base::WeakPtr<AcceleratorConfirmationDialog> 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 button.
SideVolumeButtonLocation side_volume_button_location_;
DISALLOW_COPY_AND_ASSIGN(AcceleratorController); DISALLOW_COPY_AND_ASSIGN(AcceleratorController);
}; };
......
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
#include "ash/wm/wm_event.h" #include "ash/wm/wm_event.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/files/scoped_temp_dir.h"
#include "base/json/json_writer.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/stl_util.h" #include "base/stl_util.h"
...@@ -267,6 +269,22 @@ class AcceleratorControllerTest : public AshTestBase { ...@@ -267,6 +269,22 @@ class AcceleratorControllerTest : public AshTestBase {
Shell::Get()->keyboard_brightness_control_delegate_ = std::move(delegate); Shell::Get()->keyboard_brightness_control_delegate_ = std::move(delegate);
} }
bool WriteJsonFile(const base::FilePath& file_path,
const std::string& json_string) const {
if (!base::DirectoryExists(file_path.DirName()))
base::CreateDirectory(file_path.DirName());
int data_size = static_cast<int>(json_string.size());
int bytes_written =
base::WriteFile(file_path, json_string.data(), data_size);
if (bytes_written != data_size) {
LOG(ERROR) << " Wrote " << bytes_written << " byte(s) instead of "
<< data_size << " to " << file_path.value();
return false;
}
return true;
}
private: private:
DISALLOW_COPY_AND_ASSIGN(AcceleratorControllerTest); DISALLOW_COPY_AND_ASSIGN(AcceleratorControllerTest);
}; };
...@@ -1038,6 +1056,38 @@ TEST_F(AcceleratorControllerTest, PreferredReservedAccelerators) { ...@@ -1038,6 +1056,38 @@ TEST_F(AcceleratorControllerTest, PreferredReservedAccelerators) {
GetController()->IsPreferred(ui::Accelerator(ui::VKEY_A, ui::EF_NONE))); GetController()->IsPreferred(ui::Accelerator(ui::VKEY_A, ui::EF_NONE)));
} }
TEST_F(AcceleratorControllerTest, SideVolumeButtonLocation) {
// |side_volume_button_location_| should be empty when location info file
// doesn't exist.
EXPECT_TRUE(GetController()
->side_volume_button_location_for_testing()
.region.empty());
EXPECT_TRUE(
GetController()->side_volume_button_location_for_testing().side.empty());
// Tests that |side_volume_button_location_| is read correctly if the location
// file exists.
base::DictionaryValue location;
location.SetString(AcceleratorController::kVolumeButtonRegion,
AcceleratorController::kVolumeButtonRegionScreen);
location.SetString(AcceleratorController::kVolumeButtonSide,
AcceleratorController::kVolumeButtonSideLeft);
std::string json_location;
base::JSONWriter::Write(location, &json_location);
base::ScopedTempDir file_tmp_dir;
ASSERT_TRUE(file_tmp_dir.CreateUniqueTempDir());
base::FilePath file_path = file_tmp_dir.GetPath().Append("location.json");
ASSERT_TRUE(WriteJsonFile(file_path, json_location));
EXPECT_TRUE(base::PathExists(file_path));
GetController()->set_side_volume_button_file_path_for_testing(file_path);
GetController()->ParseSideVolumeButtonLocationInfo();
EXPECT_EQ(AcceleratorController::kVolumeButtonRegionScreen,
GetController()->side_volume_button_location_for_testing().region);
EXPECT_EQ(AcceleratorController::kVolumeButtonSideLeft,
GetController()->side_volume_button_location_for_testing().side);
base::DeleteFile(file_path, false);
}
namespace { namespace {
// Tests the TOGGLE_CAPS_LOCK accelerator. // Tests the TOGGLE_CAPS_LOCK accelerator.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment