1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <system_ability_definition.h>
16 #include "setting_datashare.h"
17 #include "touchpad_settings_handler.h"
18 #include "mmi_log.h"
19 #include "account_manager.h"
20
21 #undef MMI_LOG_TAG
22 #define MMI_LOG_TAG "TouchpadSettingsObserver"
23
24 #define TP_CHECK_FALSE_RETURN(cond, ret, fmt, ...) \
25 if (!(cond)) { \
26 MMI_HILOGE(fmt, ##__VA_ARGS__); \
27 return ret; \
28 }
29
30 namespace OHOS {
31 namespace MMI {
32 namespace {
33 const std::string g_pressureKey {"settings.trackpad.press_level"};
34 const std::string g_vibrationKey {"settings.trackpad.shock_level"};
35 const std::string g_touchpadSwitchesKey {"settings.trackpad.touchpad_switches"};
36 const std::string g_knuckleSwitchesKey {"settings.trackpad.touchpad_switches"};
37 const std::string g_datashareBaseUri =
38 "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_";
39 const std::string g_libthpPath {"/system/lib64/libthp_extra_innerapi.z.so"};
40 const std::map<std::string, int> g_keyToCmd = {
41 {g_pressureKey, 103}, // pressure cmd 103
42 {g_vibrationKey, 104}, // vibration cmd 104
43 {g_touchpadSwitchesKey, 108}, // touchpad switches cmd 108
44 {g_knuckleSwitchesKey, 109} // knuckle switches cmd 109
45 };
46 const std::map<std::string, std::string> g_defaultValue = {
47 {g_pressureKey, "2"}, // default pressure value 2
48 {g_vibrationKey, "2"}, // default vibration value 2
49 {g_touchpadSwitchesKey, "1"}, // tdefault touchpad on
50 {g_knuckleSwitchesKey, "0"} // default knuckle off
51 };
52 } // namespace
53
54 std::mutex TouchpadSettingsObserver::mutex_;
55 std::shared_ptr<TouchpadSettingsObserver> TouchpadSettingsObserver::instance_ = nullptr;
56
TouchpadSettingsObserver()57 TouchpadSettingsObserver::TouchpadSettingsObserver() {}
58
~TouchpadSettingsObserver()59 TouchpadSettingsObserver::~TouchpadSettingsObserver() {}
60
GetInstance()61 std::shared_ptr<TouchpadSettingsObserver> TouchpadSettingsObserver::GetInstance()
62 {
63 if (instance_ == nullptr) {
64 std::lock_guard<std::mutex> lock(mutex_);
65 if (instance_ == nullptr) {
66 instance_ = std::make_shared<TouchpadSettingsObserver>();
67 }
68 }
69 return instance_;
70 }
71
RegisterUpdateFunc()72 void TouchpadSettingsObserver::RegisterUpdateFunc()
73 {
74 updateFunc_ = nullptr;
75 const std::string datashareUri = datashareUri_;
76 const std::string libthpPath = g_libthpPath;
77 const std::map<std::string, int> keyToCmd = g_keyToCmd;
78 const std::map<std::string, std::string> defaultValue = g_defaultValue;
79
80 SettingObserver::UpdateFunc UpdateFunc =
81 [datashareUri, libthpPath, keyToCmd, defaultValue](const std::string& key) {
82 MMI_HILOGI("Touchpad settings change: %{public}s", key.c_str());
83 typedef const char* (*ThpExtraRunCommandFunc)(const char* command, const char* parameters);
84 const char* (*ThpExtraRunCommand)(const char* command, const char* parameters) {};
85 std::string value;
86
87 auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).GetStringValue(key, value, datashareUri);
88 if (ret != 0) {
89 auto valueIter = defaultValue.find(key);
90 if (valueIter == defaultValue.end()) {
91 MMI_HILOGE("Invalid value key");
92 return;
93 }
94 value = valueIter->second;
95 }
96 MMI_HILOGI("Get value: %{public}s", value.c_str());
97
98 auto cmdIter = keyToCmd.find(key);
99 if (cmdIter == keyToCmd.end()) {
100 MMI_HILOGE("Invalid command key");
101 return;
102 }
103
104 void *handle = nullptr;
105 handle = dlopen(libthpPath.c_str(), RTLD_LAZY);
106 if (handle == nullptr) {
107 MMI_HILOGE("Handle is null");
108 return;
109 }
110
111 ThpExtraRunCommand = reinterpret_cast<ThpExtraRunCommandFunc>(dlsym(handle, "ThpExtraRunCommand"));
112 if (ThpExtraRunCommand == nullptr) {
113 MMI_HILOGE("ThpExtraRunCommand is null");
114 dlclose(handle);
115 return;
116 }
117 const std::string param = std::string("#").append(std::to_string(cmdIter->second)).append("#").append(value);
118 ThpExtraRunCommand("THP_TouchpadStatusChange", param.c_str());
119 dlclose(handle);
120 };
121 MMI_HILOGI("Update function register end");
122 updateFunc_ = UpdateFunc;
123 return;
124 }
125
RegisterTpObserver(const int32_t accountId)126 bool TouchpadSettingsObserver::RegisterTpObserver(const int32_t accountId)
127 {
128 if (hasRegistered_) { return false; }
129 std::lock_guard<std::mutex> lock(lock_);
130 ErrCode ret = 0;
131
132 currentAccountId_ = accountId;
133 TP_CHECK_FALSE_RETURN(currentAccountId_ >= 0, false, "Get account info fail");
134
135 datashareUri_ = g_datashareBaseUri + std::to_string(currentAccountId_) + "?Proxy=true";
136 RegisterUpdateFunc();
137 TP_CHECK_FALSE_RETURN(updateFunc_ != nullptr, false, "Update function is null");
138
139 if (pressureObserver_ == nullptr) {
140 pressureObserver_ = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
141 .CreateObserver(g_pressureKey, updateFunc_);
142 TP_CHECK_FALSE_RETURN(pressureObserver_ != nullptr, false, "PressureObserver fail");
143 ret = ret || SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
144 .RegisterObserver(pressureObserver_, datashareUri_);
145 }
146 if (vibrationObserver_ == nullptr) {
147 vibrationObserver_ = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
148 .CreateObserver(g_vibrationKey, updateFunc_);
149 TP_CHECK_FALSE_RETURN(vibrationObserver_ != nullptr, false, "VibrationObserver fail");
150 ret = ret || SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
151 .RegisterObserver(vibrationObserver_, datashareUri_);
152 }
153 if (touchpadSwitchesObserver_ == nullptr) {
154 touchpadSwitchesObserver_ = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
155 .CreateObserver(g_touchpadSwitchesKey, updateFunc_);
156 TP_CHECK_FALSE_RETURN(touchpadSwitchesObserver_ != nullptr, false, "TouchpadSwitchesObserver fail");
157 ret = ret || SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
158 .RegisterObserver(touchpadSwitchesObserver_, datashareUri_);
159 }
160 if (knuckleSwitchesObserver_ == nullptr) {
161 knuckleSwitchesObserver_ = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
162 .CreateObserver(g_knuckleSwitchesKey, updateFunc_);
163 TP_CHECK_FALSE_RETURN(knuckleSwitchesObserver_ != nullptr, false, "KnuckleSwitchesObserver fail");
164 ret = ret || SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
165 .RegisterObserver(knuckleSwitchesObserver_, datashareUri_);
166 }
167 if (ret) {
168 pressureObserver_ = nullptr;
169 vibrationObserver_ = nullptr;
170 touchpadSwitchesObserver_ = nullptr;
171 knuckleSwitchesObserver_ = nullptr;
172 MMI_HILOGE("Register setting observer failed, ret = %{public}d", ret);
173 return false;
174 }
175 MMI_HILOGI("Register touchpad observer end");
176 hasRegistered_ = true;
177 return true;
178 }
179
UnregisterTpObserver(const int32_t accountId)180 bool TouchpadSettingsObserver::UnregisterTpObserver(const int32_t accountId)
181 {
182 if (!hasRegistered_ || accountId == currentAccountId_) {
183 return false;
184 }
185 std::lock_guard<std::mutex> lock { lock_ };
186 ErrCode ret = 0;
187
188 if (pressureObserver_ != nullptr) {
189 ret = ret || SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
190 .UnregisterObserver(pressureObserver_, datashareUri_);
191 TP_CHECK_FALSE_RETURN(ret == 0, false, "Unregister pressureObserver fail");
192 pressureObserver_ = nullptr;
193 }
194 if (vibrationObserver_ != nullptr) {
195 ret = ret || SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
196 .UnregisterObserver(vibrationObserver_, datashareUri_);
197 TP_CHECK_FALSE_RETURN(ret == 0, false, "Unregister vibrationObserver fail");
198 vibrationObserver_ = nullptr;
199 }
200 if (touchpadSwitchesObserver_ != nullptr) {
201 ret = ret || SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
202 .UnregisterObserver(touchpadSwitchesObserver_, datashareUri_);
203 TP_CHECK_FALSE_RETURN(ret == 0, false, "Unregister touchpadSwitchesObserver fail");
204 touchpadSwitchesObserver_ = nullptr;
205 }
206 if (knuckleSwitchesObserver_ != nullptr) {
207 ret = ret || SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
208 .UnregisterObserver(knuckleSwitchesObserver_, datashareUri_);
209 TP_CHECK_FALSE_RETURN(ret == 0, false, "Unregister knuckleSwitchesObserver fail");
210 knuckleSwitchesObserver_ = nullptr;
211 }
212
213 hasRegistered_ = false;
214 MMI_HILOGI("Unregister touchpad observer");
215 return true;
216 }
217
SyncTouchpadSettingsData()218 void TouchpadSettingsObserver::SyncTouchpadSettingsData()
219 {
220 if (!hasRegistered_ && !RegisterTpObserver(ACCOUNT_MGR->GetCurrentAccountSetting().GetAccountId())) {
221 return;
222 }
223 std::lock_guard<std::mutex> lock { lock_ };
224 if (updateFunc_ == nullptr) {
225 return;
226 }
227 updateFunc_(g_pressureKey);
228 updateFunc_(g_vibrationKey);
229 updateFunc_(g_touchpadSwitchesKey);
230 updateFunc_(g_knuckleSwitchesKey);
231 MMI_HILOGI("Sync touchpad settings end");
232 }
233 } // namespace MMI
234 } // namespace OHOS
235