blob: 2344463241950bbe4e4925e429d5590b1ad464dd [file] [log] [blame]
Siarhei Vishniakou257553c2019-02-21 14:37:06 -06001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Chris Yef59a2f42020-10-16 12:55:26 -070017#include <binder/Binder.h>
18#include <binder/Parcel.h>
Siarhei Vishniakou257553c2019-02-21 14:37:06 -060019#include <gtest/gtest.h>
20#include <input/InputDevice.h>
Chris Yef59a2f42020-10-16 12:55:26 -070021#include <input/KeyLayoutMap.h>
22#include <input/Keyboard.h>
Philip Junker90bc9492021-12-10 18:39:42 +010023#include "android-base/file.h"
Siarhei Vishniakou257553c2019-02-21 14:37:06 -060024
25namespace android {
26
27// --- InputDeviceIdentifierTest ---
28
29TEST(InputDeviceIdentifierTest, getCanonicalName) {
30 InputDeviceIdentifier identifier;
31 identifier.name = "test device";
32 ASSERT_EQ(std::string("test_device"), identifier.getCanonicalName());
33
34 identifier.name = "deviceName-123 version_C!";
35 ASSERT_EQ(std::string("deviceName-123_version_C_"), identifier.getCanonicalName());
36}
37
Chris Yef59a2f42020-10-16 12:55:26 -070038class InputDeviceKeyMapTest : public testing::Test {
39protected:
40 void loadKeyLayout(const char* name) {
41 std::string path =
42 getInputDeviceConfigurationFilePathByName(name,
43 InputDeviceConfigurationFileType::
44 KEY_LAYOUT);
45 ASSERT_FALSE(path.empty());
46 base::Result<std::shared_ptr<KeyLayoutMap>> ret = KeyLayoutMap::load(path);
Bernie Innocenti189c0f82020-12-22 19:45:18 +090047 ASSERT_TRUE(ret.ok()) << "Cannot load KeyLayout at " << path;
Chris Yef59a2f42020-10-16 12:55:26 -070048 mKeyMap.keyLayoutMap = std::move(*ret);
49 mKeyMap.keyLayoutFile = path;
50 }
51
52 void loadKeyCharacterMap(const char* name) {
53 InputDeviceIdentifier identifier;
54 identifier.name = name;
55 std::string path =
56 getInputDeviceConfigurationFilePathByName(identifier.getCanonicalName(),
57 InputDeviceConfigurationFileType::
58 KEY_CHARACTER_MAP);
59 ASSERT_FALSE(path.empty()) << "KeyCharacterMap for " << name << " not found";
60 base::Result<std::shared_ptr<KeyCharacterMap>> ret =
61 KeyCharacterMap::load(path, KeyCharacterMap::Format::BASE);
Bernie Innocenti189c0f82020-12-22 19:45:18 +090062 ASSERT_TRUE(ret.ok()) << "Cannot load KeyCharacterMap at " << path;
Chris Yef59a2f42020-10-16 12:55:26 -070063 mKeyMap.keyCharacterMap = *ret;
64 mKeyMap.keyCharacterMapFile = path;
65 }
66
Siarhei Vishniakou5ed8eaa2022-05-18 12:30:16 -070067 void SetUp() override {
Siarhei Vishniakou5e83dfe2022-09-28 17:04:42 -070068#if !defined(__ANDROID__)
69 GTEST_SKIP() << "b/253299089 Generic files are currently read directly from device.";
70#endif
Chris Yef59a2f42020-10-16 12:55:26 -070071 loadKeyLayout("Generic");
72 loadKeyCharacterMap("Generic");
73 }
74
Chris Yef59a2f42020-10-16 12:55:26 -070075 KeyMap mKeyMap;
76};
77
78TEST_F(InputDeviceKeyMapTest, keyCharacterMapParcelingTest) {
79 Parcel parcel;
80 mKeyMap.keyCharacterMap->writeToParcel(&parcel);
81 parcel.setDataPosition(0);
82 std::shared_ptr<KeyCharacterMap> map = KeyCharacterMap::readFromParcel(&parcel);
83 // Verify the key character map is the same as original
84 ASSERT_EQ(*map, *mKeyMap.keyCharacterMap);
85}
86
Philip Junker90bc9492021-12-10 18:39:42 +010087TEST_F(InputDeviceKeyMapTest, keyCharacterMapWithOverlayParcelingTest) {
88 Parcel parcel;
89 std::string overlayPath = base::GetExecutableDirectory() + "/data/german.kcm";
90 base::Result<std::shared_ptr<KeyCharacterMap>> overlay =
91 KeyCharacterMap::load(overlayPath, KeyCharacterMap::Format::OVERLAY);
92 ASSERT_TRUE(overlay.ok()) << "Cannot load KeyCharacterMap at " << overlayPath;
93 mKeyMap.keyCharacterMap->combine(*overlay->get());
94 mKeyMap.keyCharacterMap->writeToParcel(&parcel);
95 parcel.setDataPosition(0);
96 std::shared_ptr<KeyCharacterMap> map = KeyCharacterMap::readFromParcel(&parcel);
97 ASSERT_EQ(*map, *mKeyMap.keyCharacterMap);
98}
99
100TEST_F(InputDeviceKeyMapTest, keyCharacteMapApplyMultipleOverlaysTest) {
101 std::string frenchOverlayPath = base::GetExecutableDirectory() + "/data/french.kcm";
102 std::string englishOverlayPath = base::GetExecutableDirectory() + "/data/english_us.kcm";
103 std::string germanOverlayPath = base::GetExecutableDirectory() + "/data/german.kcm";
104 base::Result<std::shared_ptr<KeyCharacterMap>> frenchOverlay =
105 KeyCharacterMap::load(frenchOverlayPath, KeyCharacterMap::Format::OVERLAY);
106 ASSERT_TRUE(frenchOverlay.ok()) << "Cannot load KeyCharacterMap at " << frenchOverlayPath;
107 base::Result<std::shared_ptr<KeyCharacterMap>> englishOverlay =
108 KeyCharacterMap::load(englishOverlayPath, KeyCharacterMap::Format::OVERLAY);
109 ASSERT_TRUE(englishOverlay.ok()) << "Cannot load KeyCharacterMap at " << englishOverlayPath;
110 base::Result<std::shared_ptr<KeyCharacterMap>> germanOverlay =
111 KeyCharacterMap::load(germanOverlayPath, KeyCharacterMap::Format::OVERLAY);
112 ASSERT_TRUE(germanOverlay.ok()) << "Cannot load KeyCharacterMap at " << germanOverlayPath;
113
114 // Apply the French overlay
115 mKeyMap.keyCharacterMap->combine(*frenchOverlay->get());
116 // Copy the result for later
117 std::shared_ptr<KeyCharacterMap> frenchOverlaidKeyCharacterMap =
118 std::make_shared<KeyCharacterMap>(*mKeyMap.keyCharacterMap);
119
120 // Apply the English overlay
121 mKeyMap.keyCharacterMap->combine(*englishOverlay->get());
122 // Verify that the result is different from the French overlay result
123 ASSERT_NE(*mKeyMap.keyCharacterMap, *frenchOverlaidKeyCharacterMap);
124
125 // Apply the German overlay
126 mKeyMap.keyCharacterMap->combine(*germanOverlay->get());
127 // Verify that the result is different from the French overlay result
128 ASSERT_NE(*mKeyMap.keyCharacterMap, *frenchOverlaidKeyCharacterMap);
129
130 // Apply the French overlay
131 mKeyMap.keyCharacterMap->combine(*frenchOverlay->get());
132 // Verify that the result is the same like after applying it initially
133 ASSERT_EQ(*mKeyMap.keyCharacterMap, *frenchOverlaidKeyCharacterMap);
134}
135
Siarhei Vishniakoua9fd82c2022-05-18 09:42:52 -0700136TEST(InputDeviceKeyLayoutTest, DoesNotLoadWhenRequiredKernelConfigIsMissing) {
Siarhei Vishniakou5e83dfe2022-09-28 17:04:42 -0700137#if !defined(__ANDROID__)
138 GTEST_SKIP() << "Can't check kernel configs on host";
139#endif
Siarhei Vishniakoua9fd82c2022-05-18 09:42:52 -0700140 std::string klPath = base::GetExecutableDirectory() + "/data/kl_with_required_fake_config.kl";
141 base::Result<std::shared_ptr<KeyLayoutMap>> ret = KeyLayoutMap::load(klPath);
142 ASSERT_FALSE(ret.ok()) << "Should not be able to load KeyLayout at " << klPath;
143 // We assert error message here because it's used by 'validatekeymaps' tool
144 ASSERT_EQ("Missing kernel config", ret.error().message());
145}
146
147TEST(InputDeviceKeyLayoutTest, LoadsWhenRequiredKernelConfigIsPresent) {
Siarhei Vishniakou5e83dfe2022-09-28 17:04:42 -0700148#if !defined(__ANDROID__)
149 GTEST_SKIP() << "Can't check kernel configs on host";
150#endif
Siarhei Vishniakoua9fd82c2022-05-18 09:42:52 -0700151 std::string klPath = base::GetExecutableDirectory() + "/data/kl_with_required_real_config.kl";
152 base::Result<std::shared_ptr<KeyLayoutMap>> ret = KeyLayoutMap::load(klPath);
153 ASSERT_TRUE(ret.ok()) << "Cannot load KeyLayout at " << klPath;
154 const std::shared_ptr<KeyLayoutMap>& map = *ret;
155 ASSERT_NE(nullptr, map) << "Map should be valid because CONFIG_UHID should always be present";
156}
157
Bernie Innocenti189c0f82020-12-22 19:45:18 +0900158} // namespace android