• 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_task_manager.h"
17 
18 #include <pthread.h>
19 #include <unistd.h>
20 #include "device_auth_defines.h"
21 #include "hc_log.h"
22 #include "hc_mutex.h"
23 #include "hc_vector.h"
24 #include "plugin_adapter.h"
25 #include "account_auth_plugin_proxy.h"
26 
27 #define UNLOAD_DELAY_TIME 3
28 
29 typedef struct {
30     int32_t taskId;
31 } AccountTaskRecord;
32 
33 DECLARE_HC_VECTOR(AccountTaskRecordList, AccountTaskRecord)
34 IMPLEMENT_HC_VECTOR(AccountTaskRecordList, AccountTaskRecord, 1)
35 
36 static AccountTaskRecordList g_taskList;
37 static bool g_isPluginLoaded = false;
38 static bool g_isAsyncTaskRunning = false;
39 static bool g_hasAccountAuthPlugin = false;
40 static HcMutex g_taskMutex = { 0 };
41 static bool g_isInit = false;
42 static bool g_isUnloadState = false;
43 
LoadAccountAuthPlugin(void)44 static void LoadAccountAuthPlugin(void)
45 {
46     (void)LockHcMutex(&g_taskMutex);
47     g_isUnloadState = false;
48     if (g_isPluginLoaded) {
49         UnlockHcMutex(&g_taskMutex);
50         LOGI("[ACCOUNT_TASK_MGR]: plugin is loaded.");
51         return;
52     }
53     DEV_AUTH_LOAD_PLUGIN();
54     g_isPluginLoaded = true;
55     UnlockHcMutex(&g_taskMutex);
56     LOGI("[ACCOUNT_TASK_MGR]: load plugin successfully.");
57 }
58 
IsPluginUnloadNeeded(void)59 static bool IsPluginUnloadNeeded(void)
60 {
61     (void)LockHcMutex(&g_taskMutex);
62     if (!g_isPluginLoaded) {
63         UnlockHcMutex(&g_taskMutex);
64         LOGI("[ACCOUNT_TASK_MGR]: plugin is unloaded.");
65         return false;
66     }
67     if (g_isAsyncTaskRunning) {
68         UnlockHcMutex(&g_taskMutex);
69         LOGI("[ACCOUNT_TASK_MGR]: async task is running, can't unload plugin.");
70         return false;
71     }
72     if (g_taskList.size(&g_taskList) > 0) {
73         UnlockHcMutex(&g_taskMutex);
74         LOGI("[ACCOUNT_TASK_MGR]: task exist.");
75         return false;
76     }
77     UnlockHcMutex(&g_taskMutex);
78     return true;
79 }
80 
ExecuteUnload(void * arg)81 void *ExecuteUnload(void *arg)
82 {
83     LOGI("[ACCOUNT_TASK_MGR]: unload task execute.");
84     sleep(UNLOAD_DELAY_TIME);
85     LockHcMutex(&g_taskMutex);
86     if (IsPluginUnloadNeeded() && g_isUnloadState) {
87         DEV_AUTH_UNLOAD_PLUGIN();
88         g_isPluginLoaded = false;
89         g_isUnloadState = false;
90         LOGI("[ACCOUNT_TASK_MGR]: unload plugin successfully.");
91     } else {
92         LOGI("[ACCOUNT_TASK_MGR]: no need to unload.");
93     }
94     UnlockHcMutex(&g_taskMutex);
95     return NULL;
96 }
97 
UnloadAccountAuthPlugin(void)98 static void UnloadAccountAuthPlugin(void)
99 {
100     LockHcMutex(&g_taskMutex);
101     if (!IsPluginUnloadNeeded() || g_isUnloadState) {
102         UnlockHcMutex(&g_taskMutex);
103         return;
104     }
105     g_isUnloadState = true;
106     pthread_t tid;
107     pthread_create(&tid, NULL, ExecuteUnload, NULL);
108     pthread_detach(tid);
109     UnlockHcMutex(&g_taskMutex);
110 }
111 
AddAccountTaskRecord(int32_t taskId)112 static int32_t AddAccountTaskRecord(int32_t taskId)
113 {
114     LockHcMutex(&g_taskMutex);
115     AccountTaskRecord taskRecord;
116     taskRecord.taskId = taskId;
117     if (g_taskList.pushBackT(&g_taskList, taskRecord) == NULL) {
118         UnlockHcMutex(&g_taskMutex);
119         LOGE("[ACCOUNT_TASK_MGR]: push task record failed, taskId: %" LOG_PUB "d", taskId);
120         return HC_ERR_MEMORY_COPY;
121     }
122     UnlockHcMutex(&g_taskMutex);
123     LOGI("[ACCOUNT_TASK_MGR]: add task record succeeded, taskId: %" LOG_PUB "d", taskId);
124     return HC_SUCCESS;
125 }
126 
RemoveAccountTaskRecord(int32_t taskId)127 static void RemoveAccountTaskRecord(int32_t taskId)
128 {
129     LockHcMutex(&g_taskMutex);
130     uint32_t index;
131     AccountTaskRecord *ptr;
132     FOR_EACH_HC_VECTOR(g_taskList, index, ptr) {
133         if (ptr->taskId == taskId) {
134             HC_VECTOR_POPELEMENT(&g_taskList, ptr, index);
135             UnlockHcMutex(&g_taskMutex);
136             LOGI("[ACCOUNT_TASK_MGR]: remove task record succeeded, taskId: %" LOG_PUB "d", taskId);
137             return;
138         }
139     }
140     UnlockHcMutex(&g_taskMutex);
141     LOGI("[ACCOUNT_TASK_MGR]: task record not exist, taskId: %" LOG_PUB "d", taskId);
142 }
143 
InitAccountTaskManager(void)144 int32_t InitAccountTaskManager(void)
145 {
146     if (g_isInit) {
147         LOGI("[ACCOUNT_TASK_MGR]: has been initialized.");
148         return HC_SUCCESS;
149     }
150     int32_t res = InitHcMutex(&g_taskMutex, true);
151     if (res != HC_SUCCESS) {
152         LOGE("[ACCOUNT_TASK_MGR]: init account task mutex failed.");
153         return res;
154     }
155     DEV_AUTH_LOAD_PLUGIN();
156     g_hasAccountAuthPlugin = HasAccountAuthPlugin();
157     DEV_AUTH_UNLOAD_PLUGIN();
158     g_taskList = CREATE_HC_VECTOR(AccountTaskRecordList);
159     g_isInit = true;
160     return HC_SUCCESS;
161 }
162 
DestroyAccountTaskManager(void)163 void DestroyAccountTaskManager(void)
164 {
165     if (!g_isInit) {
166         LOGI("[ACCOUNT_TASK_MGR]: has not been initialized.");
167         return;
168     }
169     g_isInit = false;
170     (void)LockHcMutex(&g_taskMutex);
171     DESTROY_HC_VECTOR(AccountTaskRecordList, &g_taskList);
172     UnlockHcMutex(&g_taskMutex);
173     DestroyHcMutex(&g_taskMutex);
174 }
175 
HasAccountPlugin(void)176 bool HasAccountPlugin(void)
177 {
178     return g_hasAccountAuthPlugin;
179 }
180 
ExecuteAccountAuthCmd(int32_t osAccountId,int32_t cmdId,const CJson * in,CJson * out)181 int32_t ExecuteAccountAuthCmd(int32_t osAccountId, int32_t cmdId, const CJson *in, CJson *out)
182 {
183     if (!g_isInit) {
184         LOGE("[ACCOUNT_TASK_MGR]: has not been initialized!");
185         return HC_ERROR;
186     }
187     LoadAccountAuthPlugin();
188     int32_t res = ExcuteCredMgrCmd(osAccountId, cmdId, in, out);
189     UnloadAccountAuthPlugin();
190     return res;
191 }
192 
CreateAccountAuthSession(int32_t * sessionId,const CJson * in,CJson * out)193 int32_t CreateAccountAuthSession(int32_t *sessionId, const CJson *in, CJson *out)
194 {
195     if (!g_isInit) {
196         LOGE("[ACCOUNT_TASK_MGR]: has not been initialized!");
197         return HC_ERROR;
198     }
199     LoadAccountAuthPlugin();
200     int32_t res = CreateAuthSession(sessionId, in, out);
201     if (res != HC_SUCCESS) {
202         LOGE("[ACCOUNT_TASK_MGR]: create auth session failed!");
203         UnloadAccountAuthPlugin();
204         return res;
205     }
206     res = AddAccountTaskRecord(*sessionId);
207     if (res != HC_SUCCESS) {
208         DestroyAuthSession(*sessionId);
209         UnloadAccountAuthPlugin();
210     }
211     return res;
212 }
213 
ProcessAccountAuthSession(int32_t * sessionId,const CJson * in,CJson * out,int32_t * status)214 int32_t ProcessAccountAuthSession(int32_t *sessionId, const CJson *in, CJson *out, int32_t *status)
215 {
216     if (!g_isInit) {
217         LOGE("[ACCOUNT_TASK_MGR]: has not been initialized!");
218         return HC_ERROR;
219     }
220     LoadAccountAuthPlugin();
221     return ProcessAuthSession(sessionId, in, out, status);
222 }
223 
DestroyAccountAuthSession(int32_t sessionId)224 int32_t DestroyAccountAuthSession(int32_t sessionId)
225 {
226     if (!g_isInit) {
227         LOGE("[ACCOUNT_TASK_MGR]: has not been initialized!");
228         return HC_ERROR;
229     }
230     LoadAccountAuthPlugin();
231     int32_t res = DestroyAuthSession(sessionId);
232     RemoveAccountTaskRecord(sessionId);
233     UnloadAccountAuthPlugin();
234     return res;
235 }
236 
LoadAccountAndAddTaskRecord(int32_t taskId)237 int32_t LoadAccountAndAddTaskRecord(int32_t taskId)
238 {
239     if (!g_isInit) {
240         LOGE("[ACCOUNT_TASK_MGR]: has not been initialized!");
241         return HC_ERROR;
242     }
243     LoadAccountAuthPlugin();
244     int32_t res = AddAccountTaskRecord(taskId);
245     if (res != HC_SUCCESS) {
246         UnloadAccountAuthPlugin();
247     }
248     return res;
249 }
250 
RemoveAccountTaskRecordAndUnload(int32_t taskId)251 void RemoveAccountTaskRecordAndUnload(int32_t taskId)
252 {
253     if (!g_isInit) {
254         LOGE("[ACCOUNT_TASK_MGR]: has not been initialized!");
255         return;
256     }
257     RemoveAccountTaskRecord(taskId);
258     UnloadAccountAuthPlugin();
259 }
260 
NotifyAsyncTaskStart(void)261 void NotifyAsyncTaskStart(void)
262 {
263     if (!g_isInit) {
264         LOGE("[ACCOUNT_TASK_MGR]: has not been initialized!");
265         return;
266     }
267     (void)LockHcMutex(&g_taskMutex);
268     if (g_isAsyncTaskRunning) {
269         UnlockHcMutex(&g_taskMutex);
270         LOGI("[ACCOUNT_TASK_MGR]: async task is already started.");
271         return;
272     }
273     g_isAsyncTaskRunning = true;
274     UnlockHcMutex(&g_taskMutex);
275     LOGI("[ACCOUNT_TASK_MGR]: notify async task start successfully.");
276 }
277 
NotifyAsyncTaskStop(void)278 void NotifyAsyncTaskStop(void)
279 {
280     if (!g_isInit) {
281         LOGE("[ACCOUNT_TASK_MGR]: has not been initialized!");
282         return;
283     }
284     (void)LockHcMutex(&g_taskMutex);
285     if (!g_isAsyncTaskRunning) {
286         UnlockHcMutex(&g_taskMutex);
287         LOGI("[ACCOUNT_TASK_MGR]: async task is already stopped.");
288         return;
289     }
290     g_isAsyncTaskRunning = false;
291     UnlockHcMutex(&g_taskMutex);
292     UnloadAccountAuthPlugin();
293     LOGI("[ACCOUNT_TASK_MGR]: notify async task stop successfully.");
294 }