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