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 "plugin_adapter.h"
24 #include "account_auth_plugin_proxy.h"
25
26 #define UNLOAD_DELAY_TIME 3
27
28 static bool g_isPluginLoaded = false;
29 static bool g_hasAccountAuthPlugin = false;
30 static HcMutex g_taskMutex = { 0 };
31 static bool g_isInit = false;
32 static bool g_isInUnloadStatus = false;
33 static uint32_t g_loadCount = 0;
34
LoadAccountAuthPlugin(void)35 static void LoadAccountAuthPlugin(void)
36 {
37 (void)LockHcMutex(&g_taskMutex);
38 g_loadCount++;
39 LOGI("[ACCOUNT_TASK_MGR]: load count increase to: %" LOG_PUB "d.", g_loadCount);
40 g_isInUnloadStatus = false;
41 if (g_isPluginLoaded) {
42 UnlockHcMutex(&g_taskMutex);
43 LOGI("[ACCOUNT_TASK_MGR]: plugin is loaded.");
44 return;
45 }
46 DEV_AUTH_LOAD_PLUGIN();
47 g_isPluginLoaded = true;
48 UnlockHcMutex(&g_taskMutex);
49 LOGI("[ACCOUNT_TASK_MGR]: load plugin successfully.");
50 }
51
ShouldUnloadPlugin(void)52 static bool ShouldUnloadPlugin(void)
53 {
54 (void)LockHcMutex(&g_taskMutex);
55 if (!g_isPluginLoaded) {
56 UnlockHcMutex(&g_taskMutex);
57 LOGI("[ACCOUNT_TASK_MGR]: plugin is not loaded.");
58 return false;
59 }
60 if (g_loadCount > 0) {
61 UnlockHcMutex(&g_taskMutex);
62 LOGI("[ACCOUNT_TASK_MGR]: plugin is in use.");
63 return false;
64 }
65 UnlockHcMutex(&g_taskMutex);
66 return true;
67 }
68
ExecuteUnload(void * arg)69 void *ExecuteUnload(void *arg)
70 {
71 LOGI("[ACCOUNT_TASK_MGR]: unload task execute.");
72 sleep(UNLOAD_DELAY_TIME);
73 LockHcMutex(&g_taskMutex);
74 if (ShouldUnloadPlugin() && g_isInUnloadStatus) {
75 g_isPluginLoaded = false;
76 g_isInUnloadStatus = false;
77 LOGI("[ACCOUNT_TASK_MGR]: unload plugin successfully.");
78 } else {
79 LOGI("[ACCOUNT_TASK_MGR]: no need to unload.");
80 }
81 UnlockHcMutex(&g_taskMutex);
82 return NULL;
83 }
84
UnloadAccountAuthPlugin(void)85 static void UnloadAccountAuthPlugin(void)
86 {
87 LockHcMutex(&g_taskMutex);
88 if (g_loadCount > 0) {
89 g_loadCount--;
90 }
91 LOGI("[ACCOUNT_TASK_MGR]: load count decrease to: %" LOG_PUB "d.", g_loadCount);
92 if (!ShouldUnloadPlugin() || g_isInUnloadStatus) {
93 UnlockHcMutex(&g_taskMutex);
94 return;
95 }
96 g_isInUnloadStatus = true;
97 pthread_t tid;
98 pthread_create(&tid, NULL, ExecuteUnload, NULL);
99 pthread_detach(tid);
100 UnlockHcMutex(&g_taskMutex);
101 }
102
InitAccountTaskManager(void)103 int32_t InitAccountTaskManager(void)
104 {
105 if (g_isInit) {
106 LOGI("[ACCOUNT_TASK_MGR]: has been initialized.");
107 return HC_SUCCESS;
108 }
109 int32_t res = InitHcMutex(&g_taskMutex, true);
110 if (res != HC_SUCCESS) {
111 LOGE("[ACCOUNT_TASK_MGR]: init account task mutex failed.");
112 return res;
113 }
114 DEV_AUTH_LOAD_PLUGIN();
115 g_hasAccountAuthPlugin = HasAccountAuthPlugin();
116 (void)LockHcMutex(&g_taskMutex);
117 g_isPluginLoaded = false;
118 g_isInUnloadStatus = false;
119 g_loadCount = 0;
120 UnlockHcMutex(&g_taskMutex);
121 g_isInit = true;
122 return HC_SUCCESS;
123 }
124
DestroyAccountTaskManager(void)125 void DestroyAccountTaskManager(void)
126 {
127 if (!g_isInit) {
128 LOGI("[ACCOUNT_TASK_MGR]: has not been initialized.");
129 return;
130 }
131 g_isInit = false;
132 (void)LockHcMutex(&g_taskMutex);
133 g_isInUnloadStatus = false;
134 g_isPluginLoaded = false;
135 g_loadCount = 0;
136 UnlockHcMutex(&g_taskMutex);
137 DestroyHcMutex(&g_taskMutex);
138 }
139
HasAccountPlugin(void)140 bool HasAccountPlugin(void)
141 {
142 return g_hasAccountAuthPlugin;
143 }
144
ExecuteAccountAuthCmd(int32_t osAccountId,int32_t cmdId,const CJson * in,CJson * out)145 int32_t ExecuteAccountAuthCmd(int32_t osAccountId, int32_t cmdId, const CJson *in, CJson *out)
146 {
147 if (!g_isInit) {
148 LOGE("[ACCOUNT_TASK_MGR]: has not been initialized!");
149 return HC_ERROR;
150 }
151 LoadAccountAuthPlugin();
152 int32_t res = ExcuteCredMgrCmd(osAccountId, cmdId, in, out);
153 UnloadAccountAuthPlugin();
154 return res;
155 }
156
CreateAccountAuthSession(int32_t * sessionId,const CJson * in,CJson * out)157 int32_t CreateAccountAuthSession(int32_t *sessionId, const CJson *in, CJson *out)
158 {
159 if (!g_isInit) {
160 LOGE("[ACCOUNT_TASK_MGR]: has not been initialized!");
161 return HC_ERROR;
162 }
163 LoadAccountAuthPlugin();
164 int32_t res = CreateAuthSession(sessionId, in, out);
165 if (res != HC_SUCCESS) {
166 LOGE("[ACCOUNT_TASK_MGR]: create auth session failed!");
167 UnloadAccountAuthPlugin();
168 }
169 return res;
170 }
171
ProcessAccountAuthSession(int32_t * sessionId,const CJson * in,CJson * out,int32_t * status)172 int32_t ProcessAccountAuthSession(int32_t *sessionId, const CJson *in, CJson *out, int32_t *status)
173 {
174 if (!g_isInit) {
175 LOGE("[ACCOUNT_TASK_MGR]: has not been initialized!");
176 return HC_ERROR;
177 }
178 return ProcessAuthSession(sessionId, in, out, status);
179 }
180
DestroyAccountAuthSession(int32_t sessionId)181 int32_t DestroyAccountAuthSession(int32_t sessionId)
182 {
183 if (!g_isInit) {
184 LOGE("[ACCOUNT_TASK_MGR]: has not been initialized!");
185 return HC_ERROR;
186 }
187 int32_t res = DestroyAuthSession(sessionId);
188 UnloadAccountAuthPlugin();
189 return res;
190 }
191
IncreaseLoadCount(void)192 void IncreaseLoadCount(void)
193 {
194 if (!g_isInit) {
195 LOGE("[ACCOUNT_TASK_MGR]: has not been initialized!");
196 return;
197 }
198 LoadAccountAuthPlugin();
199 }
200
DecreaseLoadCount(void)201 void DecreaseLoadCount(void)
202 {
203 if (!g_isInit) {
204 LOGE("[ACCOUNT_TASK_MGR]: has not been initialized!");
205 return;
206 }
207 UnloadAccountAuthPlugin();
208 }