• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, accountId:%{private}d", accountId_);
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         }, "AccountManager-AccountSetting-InitializeSetting");
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     AccountManagerUnregister();
321 }
322 
AccountManagerUnregister()323 void AccountManager::AccountManagerUnregister()
324 {
325     std::lock_guard<std::mutex> guard { lock_ };
326     UnsubscribeCommonEvent();
327     if (timerId_ >= 0) {
328         TimerMgr->RemoveTimer(timerId_);
329         timerId_ = -1;
330     }
331     accounts_.clear();
332 }
333 
Initialize()334 void AccountManager::Initialize()
335 {
336     MMI_HILOGI("Initialize account manager");
337     std::lock_guard<std::mutex> guard { lock_ };
338     SetupMainAccount();
339     SubscribeCommonEvent();
340 #ifdef SCREENLOCK_MANAGER_ENABLED
341     InitializeScreenLockStatus();
342 #endif // SCREENLOCK_MANAGER_ENABLED
343 }
344 
GetCurrentAccountSetting()345 AccountManager::AccountSetting AccountManager::GetCurrentAccountSetting()
346 {
347     std::lock_guard<std::mutex> guard { lock_ };
348     if (auto iter = accounts_.find(currentAccountId_); iter != accounts_.end()) {
349         return *iter->second;
350     }
351     auto [iter, _] = accounts_.emplace(currentAccountId_, std::make_unique<AccountSetting>(currentAccountId_));
352     return *iter->second;
353 }
354 
355 #ifdef SCREENLOCK_MANAGER_ENABLED
InitializeScreenLockStatus()356 void AccountManager::InitializeScreenLockStatus()
357 {
358     MMI_HILOGI("Initialize screen lock status");
359 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
360     auto screenLockPtr = ScreenLock::ScreenLockManager::GetInstance();
361     CHKPV(screenLockPtr);
362     auto begin = std::chrono::high_resolution_clock::now();
363     DISPLAY_MONITOR->SetScreenLocked(screenLockPtr->IsScreenLocked());
364     auto durationMS = std::chrono::duration_cast<std::chrono::milliseconds>(
365         std::chrono::high_resolution_clock::now() - begin).count();
366 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
367     DfxHisysevent::ReportApiCallTimes(ApiDurationStatistics::Api::IS_SCREEN_LOCKED, durationMS);
368 #endif // OHOS_BUILD_ENABLE_DFX_RADAR
369 #endif // OHOS_BUILD_ENABLE_KEYBOARD
370 }
371 #endif // SCREENLOCK_MANAGER_ENABLED
372 
SubscribeCommonEvent()373 void AccountManager::SubscribeCommonEvent()
374 {
375     CALL_INFO_TRACE;
376     EventFwk::MatchingSkills matchingSkills;
377 
378     for (auto &item : handlers_) {
379         MMI_HILOGD("Add event:%{public}s", item.first.c_str());
380         matchingSkills.AddEvent(item.first);
381     }
382     EventFwk::CommonEventSubscribeInfo subscribeInfo { matchingSkills };
383     subscriber_ = std::make_shared<CommonEventSubscriber>(subscribeInfo);
384 
385     if (EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber_)) {
386         timerId_ = -1;
387         MMI_HILOGI("SubscribeCommonEvent succeed");
388         return;
389     }
390     subscriber_ = nullptr;
391     MMI_HILOGI("SubscribeCommonEvent fail, retry later");
392     timerId_ = TimerMgr->AddTimer(REPEAT_COOLING_TIME, REPEAT_ONCE, [this]() {
393         SubscribeCommonEvent();
394         timerId_ = -1;
395     }, "AccountManager-SubscribeCommonEvent");
396     if (timerId_ < 0) {
397         MMI_HILOGE("AddTimer fail, SubscribeCommonEvent fail");
398     }
399 }
400 
UnsubscribeCommonEvent()401 void AccountManager::UnsubscribeCommonEvent()
402 {
403     CALL_INFO_TRACE;
404     if (subscriber_ != nullptr) {
405         if (!EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriber_)) {
406             MMI_HILOGE("UnSubscribeCommonEvent fail");
407         }
408         subscriber_ = nullptr;
409     }
410 }
411 
SetupMainAccount()412 void AccountManager::SetupMainAccount()
413 {
414     MMI_HILOGI("Setup main account(%{public}d)", MAIN_ACCOUNT_ID);
415     currentAccountId_ = MAIN_ACCOUNT_ID;
416     auto [_, isNew] = accounts_.emplace(MAIN_ACCOUNT_ID, std::make_unique<AccountSetting>(MAIN_ACCOUNT_ID));
417     if (!isNew) {
418         MMI_HILOGW("Account(%{public}d) has existed", MAIN_ACCOUNT_ID);
419     }
420 }
421 
OnCommonEvent(const EventFwk::CommonEventData & data)422 void AccountManager::OnCommonEvent(const EventFwk::CommonEventData &data)
423 {
424     std::lock_guard<std::mutex> guard { lock_ };
425     std::string action = data.GetWant().GetAction();
426     MMI_HILOGI("Receive common event:%{public}s", action.c_str());
427     if (auto iter = handlers_.find(action); iter != handlers_.end()) {
428         iter->second(data);
429     } else {
430         MMI_HILOGW("Ignore event:%{public}s", action.c_str());
431     }
432 }
433 
OnAddUser(const EventFwk::CommonEventData & data)434 void AccountManager::OnAddUser(const EventFwk::CommonEventData &data)
435 {
436     int32_t accountId = data.GetCode();
437     MMI_HILOGI("Add account(%d)", accountId);
438     auto [_, isNew] = accounts_.emplace(accountId, std::make_unique<AccountSetting>(accountId));
439     if (!isNew) {
440         MMI_HILOGW("Account(%d) has existed", accountId);
441     }
442 }
443 
OnRemoveUser(const EventFwk::CommonEventData & data)444 void AccountManager::OnRemoveUser(const EventFwk::CommonEventData &data)
445 {
446     int32_t accountId = data.GetCode();
447     MMI_HILOGI("Remove account(%d)", accountId);
448     if (auto iter = accounts_.find(accountId); iter != accounts_.end()) {
449         accounts_.erase(iter);
450         MMI_HILOGI("Account(%d) has been removed", accountId);
451     } else {
452         MMI_HILOGW("No account(%d)", accountId);
453     }
454 }
455 
OnSwitchUser(const EventFwk::CommonEventData & data)456 void AccountManager::OnSwitchUser(const EventFwk::CommonEventData &data)
457 {
458     int32_t accountId = data.GetCode();
459     MMI_HILOGI("Switch to account(%d)", accountId);
460     if (currentAccountId_ != accountId) {
461         if (auto iter = accounts_.find(accountId); iter == accounts_.end()) {
462             accounts_.emplace(accountId, std::make_unique<AccountSetting>(accountId));
463         }
464         currentAccountId_ = accountId;
465         MMI_HILOGI("Switched to account(%d)", currentAccountId_);
466     }
467 }
468 } // namespace MMI
469 } // namespace OHOS
470