1 /*
2 * Copyright (c) 2024 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
16 #include "account_manager.h"
17
18 #ifdef SCREENLOCK_MANAGER_ENABLED
19 #include <screenlock_manager.h>
20 #endif // SCREENLOCK_MANAGER_ENABLED
21 #include <system_ability_definition.h>
22
23 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
24 #include "display_event_monitor.h"
25 #endif // OHOS_BUILD_ENABLE_KEYBOARD
26 #include "setting_datashare.h"
27 #include "timer_manager.h"
28
29 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
30 #include "dfx_hisysevent.h"
31 #endif // OHOS_BUILD_ENABLE_DFX_RADAR
32
33 #ifdef OHOS_BUILD_ENABLE_POINTER
34 #include "touchpad_settings_handler.h"
35 #endif // OHOS_BUILD_ENABLE_POINTER
36
37 #undef MMI_LOG_DOMAIN
38 #define MMI_LOG_DOMAIN MMI_LOG_SERVER
39 #undef MMI_LOG_TAG
40 #define MMI_LOG_TAG "AccountManager"
41
42 namespace OHOS {
43 namespace MMI {
44 namespace {
45 constexpr int32_t MAIN_ACCOUNT_ID { 100 };
46 constexpr int32_t REPEAT_ONCE { 1 };
47 constexpr int32_t REPEAT_COOLING_TIME { 1000 };
48 constexpr size_t DEFAULT_BUFFER_LENGTH { 512 };
49 const std::string ACC_SHORTCUT_ENABLED { "accessibility_shortcut_enabled" };
50 const std::string ACC_SHORTCUT_ENABLED_ON_LOCK_SCREEN { "accessibility_shortcut_enabled_on_lock_screen" };
51 const std::string ACC_SHORTCUT_TIMEOUT { "accessibility_shortcut_timeout" };
52 const std::string SECURE_SETTING_URI_PROXY {
53 "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_SECURE_%d?Proxy=true" };
54 }
55
56 std::shared_ptr<AccountManager> AccountManager::instance_;
57 std::mutex AccountManager::mutex_;
58
GetInstance()59 std::shared_ptr<AccountManager> AccountManager::GetInstance()
60 {
61 if (instance_ == nullptr) {
62 std::lock_guard<std::mutex> lock(mutex_);
63 if (instance_ == nullptr) {
64 instance_ = std::make_shared<AccountManager>();
65 instance_->Initialize();
66 }
67 }
68 return instance_;
69 }
70
OnReceiveEvent(const EventFwk::CommonEventData & data)71 void AccountManager::CommonEventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &data)
72 {
73 AccountManager::GetInstance()->OnCommonEvent(data);
74 }
75
AccountSetting(int32_t accountId)76 AccountManager::AccountSetting::AccountSetting(int32_t accountId)
77 : accountId_(accountId)
78 {
79 InitializeSetting();
80 }
81
~AccountSetting()82 AccountManager::AccountSetting::~AccountSetting()
83 {
84 if (timerId_ >= 0) {
85 TimerMgr->RemoveTimer(timerId_);
86 timerId_ = -1;
87 }
88 auto &setting = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID);
89 if (switchObserver_ != nullptr) {
90 setting.UnregisterObserver(switchObserver_);
91 }
92 if (onScreenLockedSwitchObserver_ != nullptr) {
93 setting.UnregisterObserver(onScreenLockedSwitchObserver_);
94 }
95 if (configObserver_ != nullptr) {
96 setting.UnregisterObserver(configObserver_);
97 }
98 }
99
AccountSetting(const AccountSetting & other)100 AccountManager::AccountSetting::AccountSetting(const AccountSetting &other)
101 : accountId_(other.accountId_), accShortcutTimeout_(other.accShortcutTimeout_),
102 accShortcutEnabled_(other.accShortcutEnabled_),
103 accShortcutEnabledOnScreenLocked_(other.accShortcutEnabledOnScreenLocked_)
104 {}
105
operator =(const AccountSetting & other)106 AccountManager::AccountSetting& AccountManager::AccountSetting::operator=(const AccountSetting &other)
107 {
108 accountId_ = other.accountId_;
109 accShortcutTimeout_ = other.accShortcutTimeout_;
110 accShortcutEnabled_ = other.accShortcutEnabled_;
111 accShortcutEnabledOnScreenLocked_ = other.accShortcutEnabledOnScreenLocked_;
112 return *this;
113 }
114
AccShortcutTimeout(int32_t accountId,const std::string & key)115 void AccountManager::AccountSetting::AccShortcutTimeout(int32_t accountId, const std::string &key)
116 {
117 auto accountMgr = ACCOUNT_MGR;
118 std::lock_guard<std::mutex> guard { accountMgr->lock_ };
119 if (auto iter = accountMgr->accounts_.find(accountId); iter != accountMgr->accounts_.end()) {
120 iter->second->OnAccShortcutTimeoutChanged(key);
121 } else {
122 MMI_HILOGW("No account(%d)", accountId);
123 }
124 }
125
AccShortcutEnabled(int32_t accountId,const std::string & key)126 void AccountManager::AccountSetting::AccShortcutEnabled(int32_t accountId, const std::string &key)
127 {
128 auto accountMgr = ACCOUNT_MGR;
129 std::lock_guard<std::mutex> guard { accountMgr->lock_ };
130 if (auto iter = accountMgr->accounts_.find(accountId); iter != accountMgr->accounts_.end()) {
131 iter->second->OnAccShortcutEnabled(key);
132 } else {
133 MMI_HILOGW("No account(%{public}d)", accountId);
134 }
135 }
136
AccShortcutEnabledOnScreenLocked(int32_t accountId,const std::string & key)137 void AccountManager::AccountSetting::AccShortcutEnabledOnScreenLocked(int32_t accountId, const std::string &key)
138 {
139 auto accountMgr = ACCOUNT_MGR;
140 std::lock_guard<std::mutex> guard { accountMgr->lock_ };
141 if (auto iter = accountMgr->accounts_.find(accountId); iter != accountMgr->accounts_.end()) {
142 iter->second->OnAccShortcutEnabledOnScreenLocked(key);
143 } else {
144 MMI_HILOGW("No account(%{public}d)", accountId);
145 }
146 }
147
RegisterSettingObserver(const std::string & key,SettingObserver::UpdateFunc onUpdate)148 sptr<SettingObserver> AccountManager::AccountSetting::RegisterSettingObserver(
149 const std::string &key, SettingObserver::UpdateFunc onUpdate)
150 {
151 char buf[DEFAULT_BUFFER_LENGTH] {};
152 if (sprintf_s(buf, sizeof(buf), SECURE_SETTING_URI_PROXY.c_str(), accountId_) < 0) {
153 MMI_HILOGE("Failed to format URI");
154 return nullptr;
155 }
156 MMI_HILOGI("[AccountSetting] Registering observer of '%{public}s' in %{public}s", key.c_str(), buf);
157 auto &settingHelper = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID);
158 sptr<SettingObserver> settingObserver = settingHelper.CreateObserver(key, onUpdate);
159 ErrCode ret = settingHelper.RegisterObserver(settingObserver, std::string(buf));
160 if (ret != ERR_OK) {
161 MMI_HILOGE("[AccountSetting] Failed to register '%{public}s' observer, error:%{public}d",
162 key.c_str(), ret);
163 return nullptr;
164 }
165 return settingObserver;
166 }
167
InitializeSetting()168 void AccountManager::AccountSetting::InitializeSetting()
169 {
170 CALL_INFO_TRACE;
171 if (switchObserver_ == nullptr) {
172 switchObserver_ = RegisterSettingObserver(ACC_SHORTCUT_ENABLED,
173 [accountId = accountId_](const std::string &key) {
174 AccountManager::AccountSetting::AccShortcutEnabled(accountId, key);
175 });
176 }
177 if (onScreenLockedSwitchObserver_ == nullptr) {
178 onScreenLockedSwitchObserver_ = RegisterSettingObserver(ACC_SHORTCUT_ENABLED_ON_LOCK_SCREEN,
179 [accountId = accountId_](const std::string &key) {
180 AccountManager::AccountSetting::AccShortcutEnabledOnScreenLocked(accountId, key);
181 });
182 }
183 if (configObserver_ == nullptr) {
184 configObserver_ = RegisterSettingObserver(ACC_SHORTCUT_TIMEOUT,
185 [accountId = accountId_](const std::string &key) {
186 AccountManager::AccountSetting::AccShortcutTimeout(accountId, key);
187 });
188 }
189 if ((switchObserver_ == nullptr) || (onScreenLockedSwitchObserver_ == nullptr) || (configObserver_ == nullptr)) {
190 timerId_ = TimerMgr->AddTimer(REPEAT_COOLING_TIME, REPEAT_ONCE, [this]() {
191 InitializeSetting();
192 timerId_ = -1;
193 });
194 if (timerId_ < 0) {
195 MMI_HILOGE("AddTimer fail, setting will not work");
196 }
197 } else {
198 timerId_ = -1;
199 }
200 }
201
OnAccShortcutTimeoutChanged(const std::string & key)202 void AccountManager::AccountSetting::OnAccShortcutTimeoutChanged(const std::string &key)
203 {
204 MMI_HILOGI("[AccountSetting][%d] Setting '%s' has changed", GetAccountId(), key.c_str());
205 ReadLongPressTime();
206 }
207
OnAccShortcutEnabled(const std::string & key)208 void AccountManager::AccountSetting::OnAccShortcutEnabled(const std::string &key)
209 {
210 MMI_HILOGI("[AccountSetting][%d] Setting '%s' has changed", GetAccountId(), key.c_str());
211 accShortcutEnabled_ = ReadSwitchStatus(key, accShortcutEnabled_);
212 }
213
OnAccShortcutEnabledOnScreenLocked(const std::string & key)214 void AccountManager::AccountSetting::OnAccShortcutEnabledOnScreenLocked(const std::string &key)
215 {
216 MMI_HILOGI("[AccountSetting][%d] Setting '%{public}s' has changed", GetAccountId(), key.c_str());
217 accShortcutEnabledOnScreenLocked_ = ReadSwitchStatus(key, accShortcutEnabledOnScreenLocked_);
218 }
219
ReadSwitchStatus(const std::string & key,bool currentSwitchStatus)220 bool AccountManager::AccountSetting::ReadSwitchStatus(const std::string &key, bool currentSwitchStatus)
221 {
222 if (accountId_ < 0) {
223 return false;
224 }
225 char buf[DEFAULT_BUFFER_LENGTH] {};
226 if (sprintf_s(buf, sizeof(buf), SECURE_SETTING_URI_PROXY.c_str(), accountId_) < 0) {
227 MMI_HILOGE("Failed to format URI");
228 return currentSwitchStatus;
229 }
230 bool switchOn = true;
231 auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).GetBoolValue(
232 key, switchOn, std::string(buf));
233 if (ret != RET_OK) {
234 MMI_HILOGE("[AccountSetting] Failed to acquire '%{public}s', error:%{public}d", key.c_str(), ret);
235 return currentSwitchStatus;
236 }
237 MMI_HILOGI("[AccountSetting] '%{public}s' switch %{public}s", key.c_str(), switchOn ? "on" : "off");
238 return switchOn;
239 }
240
ReadLongPressTime()241 void AccountManager::AccountSetting::ReadLongPressTime()
242 {
243 if (accountId_ < 0) {
244 return;
245 }
246 char buf[DEFAULT_BUFFER_LENGTH] {};
247 if (sprintf_s(buf, sizeof(buf), SECURE_SETTING_URI_PROXY.c_str(), accountId_) < 0) {
248 MMI_HILOGE("Failed to format URI");
249 return;
250 }
251 int32_t longPressTime {};
252 auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).GetIntValue(
253 ACC_SHORTCUT_TIMEOUT, longPressTime, std::string(buf));
254 if (ret != RET_OK) {
255 MMI_HILOGE("[AccountSetting] Failed to acquire '%{public}s', error:%{public}d",
256 ACC_SHORTCUT_TIMEOUT.c_str(), ret);
257 return;
258 }
259 accShortcutTimeout_ = longPressTime;
260 MMI_HILOGI("[AccountSetting] '%{public}s' was set to %{public}d",
261 ACC_SHORTCUT_TIMEOUT.c_str(), accShortcutTimeout_);
262 }
263
AccountManager()264 AccountManager::AccountManager()
265 {
266 handlers_ = {
267 {
268 EventFwk::CommonEventSupport::COMMON_EVENT_USER_ADDED,
269 [this](const EventFwk::CommonEventData &data) {
270 OnAddUser(data);
271 },
272 }, {
273 EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED,
274 [this](const EventFwk::CommonEventData &data) {
275 OnRemoveUser(data);
276 },
277 }, {
278 EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED,
279 [this](const EventFwk::CommonEventData &data) {
280 OnSwitchUser(data);
281 #ifdef OHOS_BUILD_ENABLE_POINTER
282 std::shared_ptr<TouchpadSettingsObserver> touchpadMgr = TOUCHPAD_MGR;
283 touchpadMgr->UnregisterTpObserver(data.GetCode()) && touchpadMgr->RegisterTpObserver(data.GetCode());
284 #endif // OHOS_BUILD_ENABLE_POINTER
285 },
286 }, {
287 EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON,
288 [](const EventFwk::CommonEventData &data) {
289 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
290 DISPLAY_MONITOR->SetScreenStatus(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON);
291 #endif // OHOS_BUILD_ENABLE_KEYBOARD
292 },
293 }, {
294 EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF,
295 [](const EventFwk::CommonEventData &data) {
296 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
297 DISPLAY_MONITOR->SetScreenStatus(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF);
298 #endif // OHOS_BUILD_ENABLE_KEYBOARD
299 },
300 }, {
301 EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_LOCKED,
302 [](const EventFwk::CommonEventData &data) {
303 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
304 DISPLAY_MONITOR->SetScreenLocked(true);
305 #endif // OHOS_BUILD_ENABLE_KEYBOARD
306 },
307 }, {
308 EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED,
309 [](const EventFwk::CommonEventData &data) {
310 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
311 DISPLAY_MONITOR->SetScreenLocked(false);
312 #endif // OHOS_BUILD_ENABLE_KEYBOARD
313 },
314 }
315 };
316 }
317
~AccountManager()318 AccountManager::~AccountManager()
319 {
320 std::lock_guard<std::mutex> guard { lock_ };
321 UnsubscribeCommonEvent();
322 if (timerId_ >= 0) {
323 TimerMgr->RemoveTimer(timerId_);
324 timerId_ = -1;
325 }
326 accounts_.clear();
327 }
328
Initialize()329 void AccountManager::Initialize()
330 {
331 MMI_HILOGI("Initialize account manager");
332 std::lock_guard<std::mutex> guard { lock_ };
333 SetupMainAccount();
334 SubscribeCommonEvent();
335 #ifdef SCREENLOCK_MANAGER_ENABLED
336 InitializeScreenLockStatus();
337 #endif // SCREENLOCK_MANAGER_ENABLED
338 }
339
GetCurrentAccountSetting()340 AccountManager::AccountSetting AccountManager::GetCurrentAccountSetting()
341 {
342 std::lock_guard<std::mutex> guard { lock_ };
343 if (auto iter = accounts_.find(currentAccountId_); iter != accounts_.end()) {
344 return *iter->second;
345 }
346 auto [iter, _] = accounts_.emplace(currentAccountId_, std::make_unique<AccountSetting>(currentAccountId_));
347 return *iter->second;
348 }
349
350 #ifdef SCREENLOCK_MANAGER_ENABLED
InitializeScreenLockStatus()351 void AccountManager::InitializeScreenLockStatus()
352 {
353 MMI_HILOGI("Initialize screen lock status");
354 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
355 auto screenLockPtr = ScreenLock::ScreenLockManager::GetInstance();
356 CHKPV(screenLockPtr);
357 auto begin = std::chrono::high_resolution_clock::now();
358 DISPLAY_MONITOR->SetScreenLocked(screenLockPtr->IsScreenLocked());
359 auto durationMS = std::chrono::duration_cast<std::chrono::milliseconds>(
360 std::chrono::high_resolution_clock::now() - begin).count();
361 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
362 DfxHisysevent::ReportApiCallTimes(ApiDurationStatistics::Api::IS_SCREEN_LOCKED, durationMS);
363 #endif // OHOS_BUILD_ENABLE_DFX_RADAR
364 #endif // OHOS_BUILD_ENABLE_KEYBOARD
365 }
366 #endif // SCREENLOCK_MANAGER_ENABLED
367
SubscribeCommonEvent()368 void AccountManager::SubscribeCommonEvent()
369 {
370 CALL_INFO_TRACE;
371 EventFwk::MatchingSkills matchingSkills;
372
373 for (auto &item : handlers_) {
374 MMI_HILOGD("Add event:%{public}s", item.first.c_str());
375 matchingSkills.AddEvent(item.first);
376 }
377 EventFwk::CommonEventSubscribeInfo subscribeInfo { matchingSkills };
378 subscriber_ = std::make_shared<CommonEventSubscriber>(subscribeInfo);
379
380 if (EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber_)) {
381 timerId_ = -1;
382 MMI_HILOGI("SubscribeCommonEvent succeed");
383 return;
384 }
385 subscriber_ = nullptr;
386 MMI_HILOGI("SubscribeCommonEvent fail, retry later");
387 timerId_ = TimerMgr->AddTimer(REPEAT_COOLING_TIME, REPEAT_ONCE, [this]() {
388 SubscribeCommonEvent();
389 timerId_ = -1;
390 });
391 if (timerId_ < 0) {
392 MMI_HILOGE("AddTimer fail, SubscribeCommonEvent fail");
393 }
394 }
395
UnsubscribeCommonEvent()396 void AccountManager::UnsubscribeCommonEvent()
397 {
398 CALL_INFO_TRACE;
399 if (subscriber_ != nullptr) {
400 if (!EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriber_)) {
401 MMI_HILOGE("UnSubscribeCommonEvent fail");
402 }
403 subscriber_ = nullptr;
404 }
405 }
406
SetupMainAccount()407 void AccountManager::SetupMainAccount()
408 {
409 MMI_HILOGI("Setup main account(%{public}d)", MAIN_ACCOUNT_ID);
410 currentAccountId_ = MAIN_ACCOUNT_ID;
411 auto [_, isNew] = accounts_.emplace(MAIN_ACCOUNT_ID, std::make_unique<AccountSetting>(MAIN_ACCOUNT_ID));
412 if (!isNew) {
413 MMI_HILOGW("Account(%{public}d) has existed", MAIN_ACCOUNT_ID);
414 }
415 }
416
OnCommonEvent(const EventFwk::CommonEventData & data)417 void AccountManager::OnCommonEvent(const EventFwk::CommonEventData &data)
418 {
419 std::lock_guard<std::mutex> guard { lock_ };
420 std::string action = data.GetWant().GetAction();
421 MMI_HILOGI("Receive common event:%{public}s", action.c_str());
422 if (auto iter = handlers_.find(action); iter != handlers_.end()) {
423 iter->second(data);
424 } else {
425 MMI_HILOGW("Ignore event:%{public}s", action.c_str());
426 }
427 }
428
OnAddUser(const EventFwk::CommonEventData & data)429 void AccountManager::OnAddUser(const EventFwk::CommonEventData &data)
430 {
431 int32_t accountId = data.GetCode();
432 MMI_HILOGI("Add account(%d)", accountId);
433 auto [_, isNew] = accounts_.emplace(accountId, std::make_unique<AccountSetting>(accountId));
434 if (!isNew) {
435 MMI_HILOGW("Account(%d) has existed", accountId);
436 }
437 }
438
OnRemoveUser(const EventFwk::CommonEventData & data)439 void AccountManager::OnRemoveUser(const EventFwk::CommonEventData &data)
440 {
441 int32_t accountId = data.GetCode();
442 MMI_HILOGI("Remove account(%d)", accountId);
443 if (auto iter = accounts_.find(accountId); iter != accounts_.end()) {
444 accounts_.erase(iter);
445 MMI_HILOGI("Account(%d) has been removed", accountId);
446 } else {
447 MMI_HILOGW("No account(%d)", accountId);
448 }
449 }
450
OnSwitchUser(const EventFwk::CommonEventData & data)451 void AccountManager::OnSwitchUser(const EventFwk::CommonEventData &data)
452 {
453 int32_t accountId = data.GetCode();
454 MMI_HILOGI("Switch to account(%d)", accountId);
455 if (currentAccountId_ != accountId) {
456 if (auto iter = accounts_.find(accountId); iter == accounts_.end()) {
457 accounts_.emplace(accountId, std::make_unique<AccountSetting>(accountId));
458 }
459 currentAccountId_ = accountId;
460 MMI_HILOGI("Switched to account(%d)", currentAccountId_);
461 }
462 }
463 } // namespace MMI
464 } // namespace OHOS
465