1 /*
2  * Copyright (c) 2020 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 #include "samgr_lite_inner.h"
16 #include <string.h>
17 #include <securec.h>
18 #include <ohos_errno.h>
19 #include <log.h>
20 #include "memory_adapter.h"
21 #include "time_adapter.h"
22 #include "thread_adapter.h"
23 #include "service_impl.h"
24 #include "feature_impl.h"
25 #include "service_registry.h"
26 
27 #undef LOG_TAG
28 #undef LOG_DOMAIN
29 #define LOG_TAG "Samgr"
30 #define LOG_DOMAIN 0xD001800
31 
32 /* **************************************************************************************************
33  * Samgr Lite public interfaces
34  * ************************************************************************************************* */
35 static BOOL RegisterService(Service *service);
36 static Service *UnregisterService(const char *name);
37 static BOOL RegisterFeature(const char *serviceName, Feature *feature);
38 static Feature *UnregisterFeature(const char *serviceName, const char *featureName);
39 static BOOL RegisterFeatureApi(const char *serviceName, const char *feature, IUnknown *publicApi);
40 static IUnknown *UnregisterFeatureApi(const char *serviceName, const char *feature);
41 static BOOL RegisterDefaultFeatureApi(const char *serviceName, IUnknown *publicApi);
42 static IUnknown *UnregisterDefaultFeatureApi(const char *serviceName);
43 static IUnknown *GetDefaultFeatureApi(const char *serviceName);
44 static IUnknown *GetFeatureApi(const char *serviceName, const char *feature);
45 static int32 AddSystemCapability(const char *sysCap);
46 static BOOL HasSystemCapability(const char *sysCap);
47 static int32 GetSystemAvailableCapabilities(char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN], int32 *sysCapNum);
48 #ifdef MINI_SAMGR_LITE_RPC
49 static IUnknown *GetRemoteDefaultFeatureApi(char *deviceId, const char *serviceName);
50 #endif
51 /* **************************************************************************************************
52  * Samgr Lite location functions
53  * ************************************************************************************************* */
54 static void InitializeAllServices(Vector *services);
55 static void InitializeSingleService(ServiceImpl *service);
56 static int32 SendBootRequest(int msgId, uint32 msgValue);
57 static const char *GetServiceName(const ServiceImpl *serviceImpl);
58 static short GetUninitializedPos(void);
59 static void AddTaskPool(ServiceImpl *service, TaskConfig *cfg, const char *name);
60 static int32 InitCompleted(void);
61 static void HandleInitRequest(const Request *request, const Response *response);
62 static SamgrLiteImpl *GetImplement(void);
63 static ServiceImpl *GetService(const char *name);
64 static TaskPool *GetSpecifiedTaskPool(TaskConfig *config);
65 static void Init(void);
66 /* **************************************************************************************************
67  * Samgr Lite location structure and local variable
68  * ************************************************************************************************* */
69 static SamgrLiteImpl g_samgrImpl;
70 
71 #define TO_NEXT_STATUS(status) (BootStatus)((uint8)(status) | 0x1)
72 
SAMGR_GetInstance(void)73 SamgrLite *SAMGR_GetInstance(void)
74 {
75     if (g_samgrImpl.mutex == NULL) {
76         Init();
77     }
78     return &(GetImplement()->vtbl);
79 }
80 
GetImplement(void)81 static SamgrLiteImpl *GetImplement(void)
82 {
83     return &g_samgrImpl;
84 }
85 
Init(void)86 static void Init(void)
87 {
88     WDT_Start(WDG_SAMGR_INIT_TIME);
89     g_samgrImpl.vtbl.RegisterService = RegisterService;
90     g_samgrImpl.vtbl.UnregisterService = UnregisterService;
91     g_samgrImpl.vtbl.RegisterFeature = RegisterFeature;
92     g_samgrImpl.vtbl.UnregisterFeature = UnregisterFeature;
93     g_samgrImpl.vtbl.RegisterFeatureApi = RegisterFeatureApi;
94     g_samgrImpl.vtbl.UnregisterFeatureApi = UnregisterFeatureApi;
95     g_samgrImpl.vtbl.RegisterDefaultFeatureApi = RegisterDefaultFeatureApi;
96     g_samgrImpl.vtbl.UnregisterDefaultFeatureApi = UnregisterDefaultFeatureApi;
97     g_samgrImpl.vtbl.GetDefaultFeatureApi = GetDefaultFeatureApi;
98     g_samgrImpl.vtbl.GetFeatureApi = GetFeatureApi;
99 #ifdef MINI_SAMGR_LITE_RPC
100     g_samgrImpl.vtbl.GetRemoteDefaultFeatureApi = GetRemoteDefaultFeatureApi;
101 #endif
102     g_samgrImpl.vtbl.AddSystemCapability = AddSystemCapability;
103     g_samgrImpl.vtbl.HasSystemCapability = HasSystemCapability;
104     g_samgrImpl.vtbl.GetSystemAvailableCapabilities = GetSystemAvailableCapabilities;
105     g_samgrImpl.status = BOOT_SYS;
106     g_samgrImpl.services = VECTOR_Make((VECTOR_Key)GetServiceName, (VECTOR_Compare)strcmp);
107     g_samgrImpl.mutex = MUTEX_InitValue();
108     (void)memset_s(g_samgrImpl.sharedPool, sizeof(TaskPool *) * MAX_POOL_NUM, 0,
109                    sizeof(TaskPool *) * MAX_POOL_NUM);
110     WDT_Reset(WDG_SVC_REG_TIME);
111 }
112 
SAMGR_Bootstrap(void)113 void SAMGR_Bootstrap(void)
114 {
115     SamgrLiteImpl *samgr = GetImplement();
116     if (samgr->mutex == NULL) {
117         HILOG_INFO(HILOG_MODULE_SAMGR, "Samgr is not init, no service!");
118         return;
119     }
120     WDT_Reset(WDG_SVC_BOOT_TIME);
121     Vector initServices = VECTOR_Make(NULL, NULL);
122     MUTEX_Lock(samgr->mutex);
123     samgr->status = TO_NEXT_STATUS(samgr->status);
124     int16 size = VECTOR_Size(&(samgr->services));
125     int16 i;
126     for (i = 0; i < size; ++i) {
127         ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(&(samgr->services), i);
128         if (serviceImpl == NULL || serviceImpl->inited != SVC_INIT) {
129             continue;
130         }
131         VECTOR_Add(&initServices, serviceImpl);
132     }
133     MUTEX_Unlock(samgr->mutex);
134     HILOG_INFO(HILOG_MODULE_SAMGR, BOOT_FMT(samgr->status), VECTOR_Size(&initServices));
135     InitializeAllServices(&initServices);
136     VECTOR_Clear(&initServices);
137     int32 err = InitCompleted();
138     if (err != EC_SUCCESS) {
139         HILOG_INFO(HILOG_MODULE_SAMGR, "Goto next boot step return code:%d", err);
140     }
141 }
142 
SAMGR_GetServiceByID(int16 serviceId)143 ServiceImpl *SAMGR_GetServiceByID(int16 serviceId)
144 {
145     SamgrLiteImpl *manager = GetImplement();
146     MUTEX_Lock(manager->mutex);
147     int16 size = VECTOR_Size(&(manager->services));
148     if (serviceId < 0 || serviceId > size) {
149         MUTEX_Unlock(manager->mutex);
150         return NULL;
151     }
152     ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(&(manager->services), serviceId);
153     MUTEX_Unlock(manager->mutex);
154     return serviceImpl;
155 }
156 
InitCompleted(void)157 static int32 InitCompleted(void)
158 {
159     // Did all services be inited?
160     SamgrLiteImpl *manager = GetImplement();
161     int16 pos = GetUninitializedPos();
162     int16 size = VECTOR_Size(&(manager->services));
163     if (pos < size) {
164         return EC_SUCCESS;
165     }
166 
167     MUTEX_Lock(manager->mutex);
168     if (manager->status == BOOT_SYS_WAIT) {
169         manager->status = BOOT_APP;
170         MUTEX_Unlock(manager->mutex);
171         HILOG_INFO(HILOG_MODULE_SAMGR, "Initialized all core system services!");
172         WDT_Reset(WDG_SVC_REG_TIME);
173         return SendBootRequest(BOOT_SYS_COMPLETED, pos);
174     }
175 
176     if (manager->status == BOOT_APP_WAIT) {
177         manager->status = BOOT_DYNAMIC;
178         MUTEX_Unlock(manager->mutex);
179         HILOG_INFO(HILOG_MODULE_SAMGR, "Initialized all system and application services!");
180         WDT_Reset(WDG_SVC_TEST_TIME);
181         return SendBootRequest(BOOT_APP_COMPLETED, pos);
182     }
183     MUTEX_Unlock(manager->mutex);
184     WDT_Stop();
185     return EC_SUCCESS;
186 }
187 
InitializeAllServices(Vector * services)188 static void InitializeAllServices(Vector *services)
189 {
190     int16 size = VECTOR_Size(services);
191     int16 i;
192     for (i = 0; i < size; ++i) {
193         ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, i);
194         if (serviceImpl == NULL) {
195             continue;
196         }
197 
198         TaskConfig config = serviceImpl->service->GetTaskConfig(serviceImpl->service);
199         const char *name = serviceImpl->service->GetName(serviceImpl->service);
200         AddTaskPool(serviceImpl, &config, name);
201 
202         HILOG_INFO(HILOG_MODULE_SAMGR, "Init service:%s", name);
203         InitializeSingleService(serviceImpl);
204     }
205     SamgrLiteImpl *samgr = GetImplement();
206     MUTEX_Lock(samgr->mutex);
207     for (i = 0; i < size; ++i) {
208         ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, i);
209         if (serviceImpl == NULL) {
210             continue;
211         }
212         const char *name = serviceImpl->service->GetName(serviceImpl->service);
213         SAMGR_StartTaskPool(serviceImpl->taskPool, name);
214     }
215     MUTEX_Unlock(samgr->mutex);
216 }
217 
RegisterService(Service * service)218 static BOOL RegisterService(Service *service)
219 {
220     if (IsInvalidService(service)) {
221         return FALSE;
222     }
223 
224     SamgrLiteImpl *samgr = GetImplement();
225     MUTEX_Lock(samgr->mutex);
226     int16 pos = VECTOR_FindByKey(&(samgr->services), (void *)service->GetName(service));
227     if (pos >= 0) {
228         MUTEX_Unlock(samgr->mutex);
229         return FALSE;
230     }
231 
232     if (VECTOR_Num(&(samgr->services)) >= MAX_SERVICE_NUM) {
233         MUTEX_Unlock(samgr->mutex);
234         return FALSE;
235     }
236 
237     ServiceImpl *serviceImpl = SAMGR_CreateServiceImpl(service, samgr->status);
238     if (serviceImpl == NULL) {
239         MUTEX_Unlock(samgr->mutex);
240         return FALSE;
241     }
242     serviceImpl->serviceId = VECTOR_Add(&(samgr->services), serviceImpl);
243     MUTEX_Unlock(samgr->mutex);
244     if (serviceImpl->serviceId == INVALID_INDEX) {
245         SAMGR_Free(serviceImpl);
246         return FALSE;
247     }
248     return TRUE;
249 }
250 
UnregisterService(const char * name)251 static Service *UnregisterService(const char *name)
252 {
253     if (name == NULL) {
254         return NULL;
255     }
256 
257     SamgrLiteImpl *samgr = GetImplement();
258     MUTEX_Lock(samgr->mutex);
259     Vector *services = &(samgr->services);
260     int16 pos = VECTOR_FindByKey(services, (void *)name);
261     ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, pos);
262     if (serviceImpl == NULL || serviceImpl->defaultApi != NULL || VECTOR_Num(&serviceImpl->features) > 0) {
263         MUTEX_Unlock(samgr->mutex);
264         return NULL;
265     }
266 
267     VECTOR_Swap(services, pos, NULL);
268     // release task pool must be in the lock to keep atomicity of the reference
269     SAMGR_ReleaseTaskPool(serviceImpl->taskPool);
270     MUTEX_Unlock(samgr->mutex);
271 
272     Service *service = serviceImpl->service;
273     VECTOR_Clear(&serviceImpl->features);
274     SAMGR_Free(serviceImpl);
275     return service;
276 }
277 
RegisterFeature(const char * serviceName,Feature * feature)278 static BOOL RegisterFeature(const char *serviceName, Feature *feature)
279 {
280     if (IsInvalidFeature(feature)) {
281         return FALSE;
282     }
283 
284     ServiceImpl *serviceImpl = GetService(serviceName);
285     if (serviceImpl == NULL || serviceImpl->inited != SVC_INIT) {
286         return FALSE;
287     }
288 
289     if (DEFAULT_GetFeature(serviceImpl, feature->GetName(feature)) != NULL) {
290         return FALSE;
291     }
292 
293     int16 featureId = DEFAULT_AddFeature(serviceImpl, feature);
294     if (featureId < 0) {
295         return FALSE;
296     }
297     return TRUE;
298 }
299 
UnregisterFeature(const char * serviceName,const char * featureName)300 static Feature *UnregisterFeature(const char *serviceName, const char *featureName)
301 {
302     ServiceImpl *serviceImpl = GetService(serviceName);
303     if (serviceImpl == NULL) {
304         return NULL;
305     }
306     return DEFAULT_DeleteFeature(serviceImpl, featureName);
307 }
308 
RegisterFeatureApi(const char * serviceName,const char * feature,IUnknown * publicApi)309 static BOOL RegisterFeatureApi(const char *serviceName, const char *feature, IUnknown *publicApi)
310 {
311     if (IsInvalidIUnknown(publicApi)) {
312         return FALSE;
313     }
314 
315     ServiceImpl *serviceImpl = GetService(serviceName);
316     if (serviceImpl == NULL) {
317         return FALSE;
318     }
319 
320     if (feature == NULL) {
321         if (serviceImpl->defaultApi != NULL) {
322             return FALSE;
323         }
324         serviceImpl->defaultApi = publicApi;
325         return TRUE;
326     }
327 
328     FeatureImpl *featureImpl = DEFAULT_GetFeature(serviceImpl, feature);
329     if (featureImpl == NULL) {
330         return FALSE;
331     }
332     return SAMGR_AddInterface(featureImpl, publicApi);
333 }
334 
UnregisterFeatureApi(const char * serviceName,const char * feature)335 static IUnknown *UnregisterFeatureApi(const char *serviceName, const char *feature)
336 {
337     ServiceImpl *serviceImpl = GetService(serviceName);
338     if (serviceImpl == NULL) {
339         return NULL;
340     }
341 
342     if (feature == NULL) {
343         IUnknown *iUnknown = serviceImpl->defaultApi;
344         serviceImpl->defaultApi = NULL;
345         return iUnknown;
346     }
347 
348     return SAMGR_DelInterface(DEFAULT_GetFeature(serviceImpl, feature));
349 }
350 
RegisterDefaultFeatureApi(const char * serviceName,IUnknown * publicApi)351 static BOOL RegisterDefaultFeatureApi(const char *serviceName, IUnknown *publicApi)
352 {
353     return RegisterFeatureApi(serviceName, NULL, publicApi);
354 }
355 
UnregisterDefaultFeatureApi(const char * serviceName)356 static IUnknown *UnregisterDefaultFeatureApi(const char *serviceName)
357 {
358     return UnregisterFeatureApi(serviceName, NULL);
359 }
360 
GetDefaultFeatureApi(const char * serviceName)361 static IUnknown *GetDefaultFeatureApi(const char *serviceName)
362 {
363     return GetFeatureApi(serviceName, NULL);
364 }
365 
AddSystemCapability(const char * sysCap)366 static int32 AddSystemCapability(const char *sysCap)
367 {
368     if (sysCap == NULL || strlen(sysCap) == 0 || strlen(sysCap) > MAX_SYSCAP_NAME_LEN) {
369         return EC_INVALID;
370     }
371     return SAMGR_RegisterSystemCapabilityApi(sysCap, TRUE);
372 }
373 
HasSystemCapability(const char * sysCap)374 static BOOL HasSystemCapability(const char *sysCap)
375 {
376     if (sysCap == NULL || strlen(sysCap) == 0 || strlen(sysCap) > MAX_SYSCAP_NAME_LEN) {
377         return FALSE;
378     }
379     return SAMGR_QuerySystemCapabilityApi(sysCap);
380 }
381 
GetSystemAvailableCapabilities(char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN],int32 * sysCapNum)382 static int32 GetSystemAvailableCapabilities(char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN], int32 *sysCapNum)
383 {
384     if (sysCaps == NULL || sysCapNum == NULL) {
385         return EC_INVALID;
386     }
387     return SAMGR_GetSystemCapabilitiesApi(sysCaps, sysCapNum);
388 }
389 
GetFeatureApi(const char * serviceName,const char * feature)390 static IUnknown *GetFeatureApi(const char *serviceName, const char *feature)
391 {
392     ServiceImpl *serviceImpl = GetService(serviceName);
393     if (serviceImpl == NULL) {
394         return SAMGR_FindServiceApi(serviceName, feature);
395     }
396 
397     FeatureImpl *featureImpl = DEFAULT_GetFeature(serviceImpl, feature);
398     if (featureImpl == NULL && feature == NULL) {
399         return serviceImpl->defaultApi;
400     }
401 
402     return SAMGR_GetInterface(featureImpl);
403 }
404 
GetUninitializedPos()405 static short GetUninitializedPos()
406 {
407     SamgrLiteImpl *manager = GetImplement();
408     MUTEX_Lock(manager->mutex);
409     int16 size = VECTOR_Size(&(manager->services));
410     int16 i;
411     for (i = 0; i < size; ++i) {
412         ServiceImpl *service = (ServiceImpl *)VECTOR_At(&(manager->services), i);
413         if (service == NULL) {
414             continue;
415         }
416 
417         if (service->inited == SVC_INIT) {
418             MUTEX_Unlock(manager->mutex);
419             return i;
420         }
421     }
422     MUTEX_Unlock(manager->mutex);
423     return size;
424 }
425 
GetServiceName(const ServiceImpl * serviceImpl)426 static const char *GetServiceName(const ServiceImpl *serviceImpl)
427 {
428     if (serviceImpl == NULL) {
429         return NULL;
430     }
431     return serviceImpl->service->GetName(serviceImpl->service);
432 }
433 
AddTaskPool(ServiceImpl * service,TaskConfig * cfg,const char * name)434 static void AddTaskPool(ServiceImpl *service, TaskConfig *cfg, const char *name)
435 {
436     if (service->taskPool != NULL) {
437         return;
438     }
439 
440     if (cfg->priority < PRI_LOW || cfg->priority >= PRI_BUTT) {
441         HILOG_ERROR(HILOG_MODULE_SAMGR, "The %s service pri(%d) is out of range!", name, cfg->priority);
442         cfg->priority = PRI_LOW;
443     }
444 
445     switch (cfg->taskFlags) {
446         case SHARED_TASK: {
447             int pos = (int)cfg->priority / PROPERTY_STEP;
448             SamgrLiteImpl *samgr = GetImplement();
449             if (samgr->sharedPool[pos] == NULL) {
450                 TaskConfig shareCfg = {LEVEL_HIGH, (int16) ((pos) * PROPERTY_STEP + 1),
451                                        SHARED_TASK_STACK_SIZE, 25, SHARED_TASK};
452                 samgr->sharedPool[pos] = SAMGR_CreateFixedTaskPool(&shareCfg, name, DEFAULT_SIZE);
453             }
454             service->taskPool = samgr->sharedPool[pos];
455             if (SAMGR_ReferenceTaskPool(service->taskPool) == NULL) {
456                 HILOG_ERROR(HILOG_MODULE_SAMGR, "pri:%d ref is full", cfg->priority);
457                 samgr->sharedPool[pos] = NULL;
458             }
459         }
460             break;
461 
462         case SPECIFIED_TASK:
463             service->taskPool = GetSpecifiedTaskPool(cfg);
464             if (service->taskPool != NULL) {
465                 break;
466             }
467             // fallthrough
468         case SINGLE_TASK:
469             service->taskPool = SAMGR_CreateFixedTaskPool(cfg, name, SINGLE_SIZE);
470             break;
471         default:
472             break;
473     }
474 
475     if (service->taskPool == NULL) {
476         HILOG_ERROR(HILOG_MODULE_SAMGR, "Service<name:%s, flag:%hhu> create taskPool failed!", name, cfg->taskFlags);
477     }
478 }
479 
GetService(const char * name)480 static ServiceImpl *GetService(const char *name)
481 {
482     if (name == NULL) {
483         return NULL;
484     }
485 
486     SamgrLiteImpl *manager = GetImplement();
487     MUTEX_Lock(manager->mutex);
488     Vector *services = &(manager->services);
489     short pos = VECTOR_FindByKey(services, (void *)name);
490     if (pos < 0) {
491         MUTEX_Unlock(manager->mutex);
492         return NULL;
493     }
494     ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, pos);
495     MUTEX_Unlock(manager->mutex);
496     return serviceImpl;
497 }
498 
SendBootRequest(int msgId,uint32 msgValue)499 static int32 SendBootRequest(int msgId, uint32 msgValue)
500 {
501     Identity id = DEFAULT_GetFeatureId(GetService(BOOTSTRAP_SERVICE), NULL);
502     Request request = {msgId, 0, NULL, msgValue};
503     return SAMGR_SendRequest(&id, &request, (Handler)SAMGR_Bootstrap);
504 }
505 
HandleInitRequest(const Request * request,const Response * response)506 static void HandleInitRequest(const Request *request, const Response *response)
507 {
508     ServiceImpl *serviceImpl = (ServiceImpl *)request->data;
509     if (serviceImpl == NULL) {
510         HILOG_ERROR(HILOG_MODULE_SAMGR, "Init service Request:<%d,%u>, Response:<%d>!",
511             request->msgId, request->msgValue, response->len);
512         return;
513     }
514     uint32 lastTime = serviceImpl->ops.timestamp;
515 
516     DEFAULT_Initialize(serviceImpl);
517     serviceImpl->ops.timestamp = SAMGR_GetProcessTime();
518     serviceImpl->inited = SVC_IDLE;
519     HILOG_INFO(HILOG_MODULE_SAMGR, "Init service %s <time: %ums> success!",
520                serviceImpl->service->GetName(serviceImpl->service), serviceImpl->ops.timestamp - lastTime);
521     int32 err = InitCompleted();
522     if (err != EC_SUCCESS) {
523         HILOG_INFO(HILOG_MODULE_SAMGR, "Goto next boot step return code:%d", err);
524     }
525 }
526 
InitializeSingleService(ServiceImpl * service)527 static void InitializeSingleService(ServiceImpl *service)
528 {
529     // service is guaranteed not to be NULL by the caller; and it's a static function, won't have external call.
530     if (service->taskPool == NULL) {
531         DEFAULT_Initialize(service);
532         return;
533     }
534 
535     Identity identity = {service->serviceId, INVALID_INDEX, service->taskPool->queueId};
536     Request request = {0, 0, service, 0};
537     uint32 *ref = NULL;
538     (void)SAMGR_SendSharedDirectRequest(&identity, &request, NULL, &ref, HandleInitRequest);
539 }
540 
GetSpecifiedTaskPool(TaskConfig * config)541 static TaskPool *GetSpecifiedTaskPool(TaskConfig *config)
542 {
543     SamgrLiteImpl *samgr = GetImplement();
544     Vector *services = &(samgr->services);
545     MUTEX_Lock(samgr->mutex);
546     int16 serviceNum = VECTOR_Size(services);
547     int i;
548     for (i = 0; i < serviceNum; ++i) {
549         ServiceImpl *impl = VECTOR_At(services, i);
550         if (impl == NULL) {
551             continue;
552         }
553 
554         TaskConfig cfg = impl->service->GetTaskConfig(impl->service);
555         if (memcmp(&cfg, config, sizeof(TaskConfig)) != 0) {
556             continue;
557         }
558 
559         if (impl->taskPool == NULL) {
560             break;
561         }
562 
563         TaskPool *taskPool = SAMGR_ReferenceTaskPool(impl->taskPool);
564         if (taskPool != NULL) {
565             MUTEX_Unlock(samgr->mutex);
566             return taskPool;
567         }
568     }
569     MUTEX_Unlock(samgr->mutex);
570     return NULL;
571 }
572 
573 #ifdef MINI_SAMGR_LITE_RPC
GetRemoteDefaultFeatureApi(char * deviceId,const char * serviceName)574 static IUnknown *GetRemoteDefaultFeatureApi(char *deviceId, const char *serviceName)
575 {
576     return SAMGR_CreateIRemoteProxy(deviceId, serviceName, NULL);
577 }
578 #endif
579