• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_volumeSwitchesKey {"settings.trackpad.right_volume_switches"};
34 const std::string g_brightnessSwitchesKey {"settings.trackpad.left_brightness_switches"};
35 const std::string g_pressureKey {"settings.trackpad.press_level"};
36 const std::string g_vibrationKey {"settings.trackpad.shock_level"};
37 const std::string g_touchpadSwitchesKey {"settings.trackpad.touchpad_switches"};
38 const std::string g_knuckleSwitchesKey {"settings.trackpad.touchpad_switches"};
39 const std::string g_datashareBaseUri =
40     "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_";
41 const std::string g_libthpPath {"/system/lib64/libthp_extra_innerapi.z.so"};
42 const std::map<std::string, int> g_keyToCmd = {
43     {g_volumeSwitchesKey, 111}, // right volume gesture cmd 111
44     {g_brightnessSwitchesKey, 110}, // left brightness gesture cmd 110
45     {g_pressureKey, 103}, // pressure cmd 103
46     {g_vibrationKey, 104}, // vibration cmd 104
47     {g_touchpadSwitchesKey, 108}, // touchpad switches cmd 108
48     {g_knuckleSwitchesKey, 109} // knuckle switches cmd 109
49 };
50 const std::map<std::string, std::string> g_defaultValue = {
51     {g_volumeSwitchesKey, "1"}, // default gesture on
52     {g_brightnessSwitchesKey, "1"}, // default gesture on
53     {g_pressureKey, "2"}, // default pressure value 2
54     {g_vibrationKey, "2"}, // default vibration value 2
55     {g_touchpadSwitchesKey, "1"}, // tdefault touchpad on
56     {g_knuckleSwitchesKey, "0"} // default knuckle off
57 };
58 } // namespace
59 
60 std::mutex TouchpadSettingsObserver::mutex_;
61 std::shared_ptr<TouchpadSettingsObserver> TouchpadSettingsObserver::instance_ = nullptr;
62 
TouchpadSettingsObserver()63 TouchpadSettingsObserver::TouchpadSettingsObserver() {}
64 
~TouchpadSettingsObserver()65 TouchpadSettingsObserver::~TouchpadSettingsObserver() {}
66 
GetInstance()67 std::shared_ptr<TouchpadSettingsObserver> TouchpadSettingsObserver::GetInstance()
68 {
69     if (instance_ == nullptr) {
70         std::lock_guard<std::mutex> lock(mutex_);
71         if (instance_ == nullptr) {
72             instance_ = std::make_shared<TouchpadSettingsObserver>();
73         }
74     }
75     return instance_;
76 }
77 
RegisterUpdateFunc()78 void TouchpadSettingsObserver::RegisterUpdateFunc()
79 {
80     updateFunc_ = nullptr;
81     const std::string datashareUri = datashareUri_;
82     const std::string libthpPath = g_libthpPath;
83     const std::map<std::string, int> keyToCmd = g_keyToCmd;
84     const std::map<std::string, std::string> defaultValue = g_defaultValue;
85 
86     SettingObserver::UpdateFunc UpdateFunc =
87         [datashareUri, libthpPath, keyToCmd, defaultValue](const std::string& key) {
88         MMI_HILOGI("Touchpad settings change: %{public}s", key.c_str());
89         typedef const char* (*ThpExtraRunCommandFunc)(const char* command, const char* parameters);
90         const char* (*ThpExtraRunCommand)(const char* command, const char* parameters) {};
91         std::string value;
92 
93         auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).GetStringValue(key, value, datashareUri);
94         if (ret != 0) {
95             auto valueIter = defaultValue.find(key);
96             if (valueIter == defaultValue.end()) {
97                 MMI_HILOGE("Invalid value key");
98                 return;
99             }
100             value = valueIter->second;
101         }
102         MMI_HILOGI("Get value: %{public}s", value.c_str());
103 
104         auto cmdIter = keyToCmd.find(key);
105         if (cmdIter == keyToCmd.end()) {
106             MMI_HILOGE("Invalid command key");
107             return;
108         }
109 
110         void *handle = nullptr;
111         handle = dlopen(libthpPath.c_str(), RTLD_LAZY);
112         if (handle == nullptr) {
113             MMI_HILOGE("Handle is null");
114             return;
115         }
116 
117         ThpExtraRunCommand = reinterpret_cast<ThpExtraRunCommandFunc>(dlsym(handle, "ThpExtraRunCommand"));
118         if (ThpExtraRunCommand == nullptr) {
119             MMI_HILOGE("ThpExtraRunCommand is null");
120             dlclose(handle);
121             return;
122         }
123         const std::string param = std::string("#").append(std::to_string(cmdIter->second)).append("#").append(value);
124         ThpExtraRunCommand("THP_TouchpadStatusChange", param.c_str());
125         dlclose(handle);
126     };
127     MMI_HILOGI("Update function register end");
128     updateFunc_ = UpdateFunc;
129     return;
130 }
131 
RegisterDatashareObserver(const std::string key,SettingObserver::UpdateFunc onUpdate)132 sptr<SettingObserver> TouchpadSettingsObserver::RegisterDatashareObserver(
133     const std::string key, SettingObserver::UpdateFunc onUpdate)
134 {
135     ErrCode ret = 0;
136     if (key.empty() || datashareUri_.empty() || onUpdate == nullptr) {
137         MMI_HILOGE("Invalid input parameter");
138         return nullptr;
139     }
140 
141     auto &settingHelper = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID);
142     sptr<SettingObserver> settingObserver = settingHelper.CreateObserver(key, onUpdate);
143     if (settingObserver == nullptr) {
144         MMI_HILOGE("CreateObserver fail");
145         return nullptr;
146     }
147 
148     ret = settingHelper.RegisterObserver(settingObserver, datashareUri_);
149     if (ret != ERR_OK) {
150         MMI_HILOGE("RegisterObserver failed");
151         return nullptr;
152     }
153     return settingObserver;
154 }
155 
RegisterTpObserver(const int32_t accountId)156 bool TouchpadSettingsObserver::RegisterTpObserver(const int32_t accountId)
157 {
158     if (!isCommonEventReady_.load() || hasRegistered_) { return false; }
159     std::lock_guard<std::mutex> lock(lock_);
160     ErrCode ret = 0;
161 
162     currentAccountId_ = accountId;
163     TP_CHECK_FALSE_RETURN(currentAccountId_ >= 0, false, "Get account info fail");
164 
165     datashareUri_ = g_datashareBaseUri + std::to_string(currentAccountId_) + "?Proxy=true";
166     RegisterUpdateFunc();
167     TP_CHECK_FALSE_RETURN(updateFunc_ != nullptr, false, "Update function is null");
168 
169     if (volumeSwitchesObserver_ == nullptr) {
170         volumeSwitchesObserver_ = RegisterDatashareObserver(g_volumeSwitchesKey, updateFunc_);
171     }
172     if (brightnessSwitchesObserver_ == nullptr) {
173         brightnessSwitchesObserver_ = RegisterDatashareObserver(g_brightnessSwitchesKey, updateFunc_);
174     }
175     if (pressureObserver_ == nullptr) {
176         pressureObserver_ = RegisterDatashareObserver(g_pressureKey, updateFunc_);
177     }
178     if (vibrationObserver_ == nullptr) {
179         vibrationObserver_ = RegisterDatashareObserver(g_vibrationKey, updateFunc_);
180     }
181     if (touchpadSwitchesObserver_ == nullptr) {
182         touchpadSwitchesObserver_ = RegisterDatashareObserver(g_touchpadSwitchesKey, updateFunc_);
183     }
184     if (knuckleSwitchesObserver_ == nullptr) {
185         knuckleSwitchesObserver_ = RegisterDatashareObserver(g_knuckleSwitchesKey, updateFunc_);
186     }
187     if (volumeSwitchesObserver_ == nullptr || brightnessSwitchesObserver_ == nullptr || pressureObserver_ == nullptr ||
188         vibrationObserver_ == nullptr ||touchpadSwitchesObserver_ == nullptr || knuckleSwitchesObserver_ == nullptr) {
189         MMI_HILOGE("Register setting observer fail");
190         return false;
191     }
192     MMI_HILOGI("Register touchpad observer");
193     hasRegistered_ = true;
194     return true;
195 }
196 
UnregisterTpObserver(const int32_t accountId)197 bool TouchpadSettingsObserver::UnregisterTpObserver(const int32_t accountId)
198 {
199     if (!hasRegistered_ || accountId == currentAccountId_) {
200         return false;
201     }
202     std::lock_guard<std::mutex> lock { lock_ };
203     ErrCode ret = 0;
204 
205     auto &settingHelper = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID);
206     if (volumeSwitchesObserver_ != nullptr) {
207         ret = settingHelper.UnregisterObserver(volumeSwitchesObserver_, datashareUri_);
208         TP_CHECK_FALSE_RETURN(ret == 0, false, "Unregister volumeSwitchesObserver fail");
209         volumeSwitchesObserver_ = nullptr;
210     }
211     if (brightnessSwitchesObserver_ != nullptr) {
212         ret = settingHelper.UnregisterObserver(brightnessSwitchesObserver_, datashareUri_);
213         TP_CHECK_FALSE_RETURN(ret == 0, false, "Unregister brightnessSwitchesObserver fail");
214         brightnessSwitchesObserver_ = nullptr;
215     }
216     if (pressureObserver_ != nullptr) {
217         ret = settingHelper.UnregisterObserver(pressureObserver_, datashareUri_);
218         TP_CHECK_FALSE_RETURN(ret == 0, false, "Unregister pressureObserver fail");
219         pressureObserver_ = nullptr;
220     }
221     if (vibrationObserver_ != nullptr) {
222         ret = settingHelper.UnregisterObserver(vibrationObserver_, datashareUri_);
223         TP_CHECK_FALSE_RETURN(ret == 0, false, "Unregister vibrationObserver fail");
224         vibrationObserver_ = nullptr;
225     }
226     if (touchpadSwitchesObserver_ != nullptr) {
227         ret = settingHelper.UnregisterObserver(touchpadSwitchesObserver_, datashareUri_);
228         TP_CHECK_FALSE_RETURN(ret == 0, false, "Unregister touchpadSwitchesObserver fail");
229         touchpadSwitchesObserver_ = nullptr;
230     }
231     if (knuckleSwitchesObserver_ != nullptr) {
232         ret = settingHelper.UnregisterObserver(knuckleSwitchesObserver_, datashareUri_);
233         TP_CHECK_FALSE_RETURN(ret == 0, false, "Unregister knuckleSwitchesObserver fail");
234         knuckleSwitchesObserver_ = nullptr;
235     }
236 
237     hasRegistered_ = false;
238     MMI_HILOGI("Unregister touchpad observer");
239     return true;
240 }
241 
SyncTouchpadSettingsData()242 void TouchpadSettingsObserver::SyncTouchpadSettingsData()
243 {
244     if (!isCommonEventReady_.load()) {
245         return;
246     }
247     if (!hasRegistered_) {
248         RegisterTpObserver(ACCOUNT_MGR->GetCurrentAccountSetting().GetAccountId());
249         return;
250     }
251     std::lock_guard<std::mutex> lock { lock_ };
252     if (updateFunc_ == nullptr) {
253         return;
254     }
255     updateFunc_(g_volumeSwitchesKey);
256     updateFunc_(g_brightnessSwitchesKey);
257     updateFunc_(g_pressureKey);
258     updateFunc_(g_vibrationKey);
259     updateFunc_(g_touchpadSwitchesKey);
260     updateFunc_(g_knuckleSwitchesKey);
261     MMI_HILOGI("Sync touchpad settings end");
262 }
263 
SetCommonEventReady()264 void TouchpadSettingsObserver::SetCommonEventReady()
265 {
266     isCommonEventReady_.store(true);
267 }
268 
GetCommonEventStatus()269 bool TouchpadSettingsObserver::GetCommonEventStatus()
270 {
271     return isCommonEventReady_.load();
272 }
273 } // namespace MMI
274 } // namespace OHOS
275