1 /*
2  * Copyright (C) 2022-2023 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 "os_account_adapter.h"
17 
18 #include <vector>
19 #include "account_subscriber.h"
20 #include "common_defs.h"
21 #include "common_event_manager.h"
22 #include "common_event_support.h"
23 #include "device_auth.h"
24 #include "hc_log.h"
25 #include "iservice_registry.h"
26 #include "matching_skills.h"
27 #include "os_account_info.h"
28 #include "os_account_manager.h"
29 #include "sa_subscriber.h"
30 #include "system_ability_definition.h"
31 
32 typedef struct {
33     EventCallbackId callbackId;
34     OsAccountCallbackFunc onOsAccountUnlocked;
35     OsAccountCallbackFunc onOsAccountRemoved;
36 } OsAccountEventCallback;
37 DECLARE_HC_VECTOR(EventCallbackVec, OsAccountEventCallback)
38 IMPLEMENT_HC_VECTOR(EventCallbackVec, OsAccountEventCallback, 1)
39 
40 static std::shared_ptr<OHOS::DevAuth::AccountSubscriber> g_accountSubscriber = nullptr;
41 static OHOS::sptr<OHOS::DevAuth::SaSubscriber> g_saSubscriber = nullptr;
42 static EventCallbackVec g_callbackVec;
43 static bool g_isInitialized = false;
44 static bool g_isCommonEventSubscribed = false;
45 static bool g_isSaSubscribed = false;
46 static const int32_t SYSTEM_DEFAULT_USER = 100;
47 static OHOS::DevAuth::OsAccountEventNotifier g_accountEventNotifier;
48 static OHOS::DevAuth::SaEventNotifier g_saEventNotifier;
49 
NotifyOsAccountUnlocked(int32_t osAccountId)50 static void NotifyOsAccountUnlocked(int32_t osAccountId)
51 {
52     if (!g_isInitialized) {
53         return;
54     }
55     uint32_t index;
56     OsAccountEventCallback *callback;
57     FOR_EACH_HC_VECTOR(g_callbackVec, index, callback) {
58         callback->onOsAccountUnlocked(osAccountId);
59     }
60 }
61 
NotifyOsAccountRemoved(int32_t osAccountId)62 static void NotifyOsAccountRemoved(int32_t osAccountId)
63 {
64     if (!g_isInitialized) {
65         return;
66     }
67     uint32_t index;
68     OsAccountEventCallback *callback;
69     FOR_EACH_HC_VECTOR(g_callbackVec, index, callback) {
70         callback->onOsAccountRemoved(osAccountId);
71     }
72 }
73 
SubscribeCommonEvent(void)74 static void SubscribeCommonEvent(void)
75 {
76     if (g_isCommonEventSubscribed) {
77         return;
78     }
79     if (g_accountSubscriber == nullptr) {
80         g_accountEventNotifier.notifyOsAccountUnlocked = NotifyOsAccountUnlocked;
81         g_accountEventNotifier.notifyOsAccountRemoved = NotifyOsAccountRemoved;
82         OHOS::EventFwk::MatchingSkills matchingSkills;
83         matchingSkills.AddEvent(OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_USER_UNLOCKED);
84         matchingSkills.AddEvent(OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED);
85         OHOS::EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
86         g_accountSubscriber = std::make_shared<OHOS::DevAuth::AccountSubscriber>(subscribeInfo, g_accountEventNotifier);
87     }
88     if (OHOS::EventFwk::CommonEventManager::SubscribeCommonEvent(g_accountSubscriber)) {
89         LOGI("[OsAccountAdapter]: subscribe common event succeed!");
90         g_isCommonEventSubscribed = true;
91     } else {
92         LOGE("[OsAccountAdapter]: subscribe common event failed!");
93     }
94 }
95 
UnSubscribeCommonEvent(void)96 static void UnSubscribeCommonEvent(void)
97 {
98     if (!g_isCommonEventSubscribed) {
99         return;
100     }
101     if (OHOS::EventFwk::CommonEventManager::UnSubscribeCommonEvent(g_accountSubscriber)) {
102         g_isCommonEventSubscribed = false;
103         LOGI("[OsAccountAdapter]: unsubscribe common event succeed!");
104     } else {
105         LOGE("[OsAccountAdapter]: unsubscribe common event failed!");
106     }
107 }
108 
UnSubscribeSystemAbility(void)109 static void UnSubscribeSystemAbility(void)
110 {
111     if (!g_isSaSubscribed) {
112         return;
113     }
114     OHOS::sptr<OHOS::ISystemAbilityManager> sysMgr =
115         OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
116     if (sysMgr == nullptr) {
117         LOGE("[OsAccountAdapter]: system ability manager is null!");
118         return;
119     }
120     if (sysMgr->UnSubscribeSystemAbility(OHOS::COMMON_EVENT_SERVICE_ID, g_saSubscriber) == OHOS::ERR_OK) {
121         LOGI("[OsAccountAdapter]: unsubscribe common event sa succeed!");
122         g_isSaSubscribed = false;
123     } else {
124         LOGE("[OsAccountAdapter]: unsubscribe common event sa failed!");
125     }
126 }
127 
NotifySystemAbilityAdded(int32_t systemAbilityId)128 static void NotifySystemAbilityAdded(int32_t systemAbilityId)
129 {
130     if (systemAbilityId == OHOS::COMMON_EVENT_SERVICE_ID) {
131         LOGI("[OsAccountAdapter]: common event sa added, try to subscribe common event.");
132         SubscribeCommonEvent();
133         if (g_isCommonEventSubscribed) {
134             UnSubscribeSystemAbility();
135         }
136     } else {
137         LOGE("[OsAccountAdapter]: invalid system ability!");
138     }
139 }
140 
SubscribeSystemAbility(void)141 static void SubscribeSystemAbility(void)
142 {
143     if (g_isSaSubscribed) {
144         return;
145     }
146     OHOS::sptr<OHOS::ISystemAbilityManager> sysMgr =
147         OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
148     if (sysMgr == nullptr) {
149         LOGE("[OsAccountAdapter]: system ability manager is null!");
150         return;
151     }
152     if (g_saSubscriber == nullptr) {
153         g_saEventNotifier.notifySystemAbilityAdded = NotifySystemAbilityAdded;
154         g_saSubscriber = new OHOS::DevAuth::SaSubscriber(g_saEventNotifier);
155     }
156     if (sysMgr->SubscribeSystemAbility(OHOS::COMMON_EVENT_SERVICE_ID, g_saSubscriber) == OHOS::ERR_OK) {
157         LOGI("[OsAccountAdapter]: subscribe common event sa succeed!");
158         g_isSaSubscribed = true;
159     } else {
160         LOGE("[OsAccountAdapter]: subscribe common event sa failed!");
161     }
162 }
163 
IsCallbackExist(EventCallbackId callbackId)164 static bool IsCallbackExist(EventCallbackId callbackId)
165 {
166     uint32_t index;
167     OsAccountEventCallback *callback;
168     FOR_EACH_HC_VECTOR(g_callbackVec, index, callback) {
169         if (callback->callbackId == callbackId) {
170             return true;
171         }
172     }
173     return false;
174 }
175 
GetCurrentActiveOsAccountId(void)176 int32_t GetCurrentActiveOsAccountId(void)
177 {
178     std::vector<int> activatedOsAccountIds;
179     OHOS::ErrCode res = OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(activatedOsAccountIds);
180     if ((res != OHOS::ERR_OK) || (activatedOsAccountIds.size() <= 0)) {
181         LOGE("[OsAccountAdapter]: QueryActiveOsAccountIds fail. [Res]: %d", res);
182         return INVALID_OS_ACCOUNT;
183     }
184     int osAccountId = activatedOsAccountIds[0];
185     if (osAccountId != SYSTEM_DEFAULT_USER) {
186         LOGI("[OsAccountAdapter]: Current active os accountId: %d", osAccountId);
187     }
188     return osAccountId;
189 }
190 
InitOsAccountAdapter(void)191 void InitOsAccountAdapter(void)
192 {
193     if (g_isInitialized) {
194         return;
195     }
196     g_callbackVec = CREATE_HC_VECTOR(EventCallbackVec);
197     SubscribeSystemAbility();
198     g_isInitialized = true;
199 }
200 
DestroyOsAccountAdapter(void)201 void DestroyOsAccountAdapter(void)
202 {
203     if (!g_isInitialized) {
204         return;
205     }
206     g_isInitialized = false;
207     UnSubscribeSystemAbility();
208     UnSubscribeCommonEvent();
209     DESTROY_HC_VECTOR(EventCallbackVec, &g_callbackVec);
210 }
211 
IsOsAccountUnlocked(int32_t osAccountId)212 bool IsOsAccountUnlocked(int32_t osAccountId)
213 {
214     bool isUnlocked = false;
215     OHOS::ErrCode res = OHOS::AccountSA::OsAccountManager::IsOsAccountVerified(osAccountId, isUnlocked);
216     if (res != OHOS::ERR_OK) {
217         LOGE("[OsAccountAdapter]: Check account verify status failed, res: %d, accountId: %d", res, osAccountId);
218         return false;
219     }
220     return isUnlocked;
221 }
222 
GetAllOsAccountIds(int32_t ** osAccountIds,uint32_t * size)223 int32_t GetAllOsAccountIds(int32_t **osAccountIds, uint32_t *size)
224 {
225     if (osAccountIds == nullptr || size == nullptr) {
226         LOGE("[OsAccountAdapter]: invalid input params!");
227         return HC_ERR_INVALID_PARAMS;
228     }
229     std::vector<OHOS::AccountSA::OsAccountInfo> osAccountInfos;
230     OHOS::ErrCode res = OHOS::AccountSA::OsAccountManager::QueryAllCreatedOsAccounts(osAccountInfos);
231     uint32_t accountSize = osAccountInfos.size();
232     if ((res != OHOS::ERR_OK) || (accountSize <= 0)) {
233         LOGE("[OsAccountAdapter]: QueryAllCreatedOsAccounts failed. [Res]: %d", res);
234         return HC_ERROR;
235     }
236     *osAccountIds = (int32_t *)HcMalloc(accountSize * sizeof(int32_t), 0);
237     if (*osAccountIds == nullptr) {
238         LOGE("[OsAccountAdapter]: Failed to alloc memory for osAccountIds!");
239         return HC_ERR_ALLOC_MEMORY;
240     }
241     for (uint32_t index = 0; index < accountSize; index++) {
242         (*osAccountIds)[index] = osAccountInfos[index].GetLocalId();
243     }
244     *size = accountSize;
245     return HC_SUCCESS;
246 }
247 
DevAuthGetRealOsAccountLocalId(int32_t inputId)248 int32_t DevAuthGetRealOsAccountLocalId(int32_t inputId)
249 {
250     if (inputId == ANY_OS_ACCOUNT) {
251         return GetCurrentActiveOsAccountId();
252     } else if (inputId >= SYSTEM_DEFAULT_USER) {
253         if (inputId != SYSTEM_DEFAULT_USER) {
254             LOGI("[OsAccountAdapter]: Use input os account! [Id]: %d", inputId);
255         }
256         return inputId;
257     } else {
258         LOGE("[OsAccountAdapter]: The input os account is invalid! [Id]: %d", inputId);
259         return INVALID_OS_ACCOUNT;
260     }
261 }
262 
AddOsAccountEventCallback(EventCallbackId callbackId,OsAccountCallbackFunc unlockFunc,OsAccountCallbackFunc removeFunc)263 void AddOsAccountEventCallback(EventCallbackId callbackId, OsAccountCallbackFunc unlockFunc,
264     OsAccountCallbackFunc removeFunc)
265 {
266     if (!g_isInitialized) {
267         LOGE("[OsAccountAdapter]: Not initialized!");
268         return;
269     }
270     if (unlockFunc == nullptr || removeFunc == nullptr) {
271         LOGE("[OsAccountAdapter]: Invalid input param!");
272         return;
273     }
274     if (IsCallbackExist(callbackId)) {
275         LOGE("[OsAccountAdapter]: Callback already exist!");
276         return;
277     }
278     OsAccountEventCallback eventCallback;
279     eventCallback.callbackId = callbackId;
280     eventCallback.onOsAccountUnlocked = unlockFunc;
281     eventCallback.onOsAccountRemoved = removeFunc;
282     if (g_callbackVec.pushBackT(&g_callbackVec, eventCallback) == nullptr) {
283         LOGE("[OsAccountAdapter]: Failed to add event callback!");
284     }
285 }
286 
RemoveOsAccountEventCallback(EventCallbackId callbackId)287 void RemoveOsAccountEventCallback(EventCallbackId callbackId)
288 {
289     if (!g_isInitialized) {
290         return;
291     }
292     uint32_t index;
293     OsAccountEventCallback *callback;
294     FOR_EACH_HC_VECTOR(g_callbackVec, index, callback) {
295         if (callback->callbackId == callbackId) {
296             OsAccountEventCallback deleteCallback;
297             HC_VECTOR_POPELEMENT(&g_callbackVec, &deleteCallback, index);
298             return;
299         }
300     }
301 }
302 
IsOsAccountSupported(void)303 bool IsOsAccountSupported(void)
304 {
305     return true;
306 }