• 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_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