19c6d7c21Sopenharmony_ci/* 29c6d7c21Sopenharmony_ci * Copyright (c) 2020 Huawei Device Co., Ltd. 39c6d7c21Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 49c6d7c21Sopenharmony_ci * you may not use this file except in compliance with the License. 59c6d7c21Sopenharmony_ci * You may obtain a copy of the License at 69c6d7c21Sopenharmony_ci * 79c6d7c21Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 89c6d7c21Sopenharmony_ci * 99c6d7c21Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 109c6d7c21Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 119c6d7c21Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 129c6d7c21Sopenharmony_ci * See the License for the specific language governing permissions and 139c6d7c21Sopenharmony_ci * limitations under the License. 149c6d7c21Sopenharmony_ci */ 159c6d7c21Sopenharmony_ci#include "client_factory.h" 169c6d7c21Sopenharmony_ci#include <ohos_errno.h> 179c6d7c21Sopenharmony_ci#include "registry.h" 189c6d7c21Sopenharmony_ci#include "memory_adapter.h" 199c6d7c21Sopenharmony_ci#include "thread_adapter.h" 209c6d7c21Sopenharmony_ci#include "default_client.h" 219c6d7c21Sopenharmony_ci 229c6d7c21Sopenharmony_citypedef struct Factory Factory; 239c6d7c21Sopenharmony_cistruct Factory { 249c6d7c21Sopenharmony_ci SaName key; 259c6d7c21Sopenharmony_ci Creator creator; 269c6d7c21Sopenharmony_ci Destroyer destroyer; 279c6d7c21Sopenharmony_ci}; 289c6d7c21Sopenharmony_ci 299c6d7c21Sopenharmony_cistatic Vector g_factories; 309c6d7c21Sopenharmony_cistatic MutexId g_mutex; 319c6d7c21Sopenharmony_cistatic Factory *GetFactory(const char *service, const char *feature); 329c6d7c21Sopenharmony_ci 339c6d7c21Sopenharmony_civoid *SAMGR_CreateIClient(const char *service, const char *feature, uint32 size) 349c6d7c21Sopenharmony_ci{ 359c6d7c21Sopenharmony_ci if (service == NULL) { 369c6d7c21Sopenharmony_ci return NULL; 379c6d7c21Sopenharmony_ci } 389c6d7c21Sopenharmony_ci 399c6d7c21Sopenharmony_ci if (g_mutex == NULL) { 409c6d7c21Sopenharmony_ci return NULL; 419c6d7c21Sopenharmony_ci } 429c6d7c21Sopenharmony_ci 439c6d7c21Sopenharmony_ci Factory *factory = GetFactory(service, feature); 449c6d7c21Sopenharmony_ci if (factory == NULL) { 459c6d7c21Sopenharmony_ci return NULL; 469c6d7c21Sopenharmony_ci } 479c6d7c21Sopenharmony_ci 489c6d7c21Sopenharmony_ci return factory->creator(service, feature, size); 499c6d7c21Sopenharmony_ci} 509c6d7c21Sopenharmony_ci 519c6d7c21Sopenharmony_ciint SAMGR_ReleaseIClient(const char *service, const char *feature, void *iClient) 529c6d7c21Sopenharmony_ci{ 539c6d7c21Sopenharmony_ci if (service == NULL || iClient == NULL) { 549c6d7c21Sopenharmony_ci return EC_INVALID; 559c6d7c21Sopenharmony_ci } 569c6d7c21Sopenharmony_ci 579c6d7c21Sopenharmony_ci if (g_mutex == NULL) { 589c6d7c21Sopenharmony_ci return EC_NOHANDLER; 599c6d7c21Sopenharmony_ci } 609c6d7c21Sopenharmony_ci 619c6d7c21Sopenharmony_ci Factory *factory = GetFactory(service, feature); 629c6d7c21Sopenharmony_ci if (factory == NULL) { 639c6d7c21Sopenharmony_ci return EC_NOHANDLER; 649c6d7c21Sopenharmony_ci } 659c6d7c21Sopenharmony_ci factory->destroyer(service, feature, iClient); 669c6d7c21Sopenharmony_ci return EC_SUCCESS; 679c6d7c21Sopenharmony_ci} 689c6d7c21Sopenharmony_ci 699c6d7c21Sopenharmony_ciint SAMGR_RegisterFactory(const char *service, const char *feature, Creator creator, Destroyer destroyer) 709c6d7c21Sopenharmony_ci{ 719c6d7c21Sopenharmony_ci if (service == NULL || creator == NULL || destroyer == NULL) { 729c6d7c21Sopenharmony_ci return EC_INVALID; 739c6d7c21Sopenharmony_ci } 749c6d7c21Sopenharmony_ci 759c6d7c21Sopenharmony_ci if (g_mutex == NULL) { 769c6d7c21Sopenharmony_ci g_factories = VECTOR_Make(NULL, (VECTOR_Compare)SAMGR_CompareSAName); 779c6d7c21Sopenharmony_ci g_mutex = MUTEX_InitValue(); 789c6d7c21Sopenharmony_ci if (g_mutex == NULL) { 799c6d7c21Sopenharmony_ci return EC_NOMEMORY; 809c6d7c21Sopenharmony_ci } 819c6d7c21Sopenharmony_ci } 829c6d7c21Sopenharmony_ci 839c6d7c21Sopenharmony_ci Factory *factory = GetFactory(service, feature); 849c6d7c21Sopenharmony_ci if (factory != NULL) { 859c6d7c21Sopenharmony_ci return EC_SUCCESS; 869c6d7c21Sopenharmony_ci } 879c6d7c21Sopenharmony_ci 889c6d7c21Sopenharmony_ci MUTEX_Lock(g_mutex); 899c6d7c21Sopenharmony_ci factory = SAMGR_Malloc(sizeof(Factory)); 909c6d7c21Sopenharmony_ci if (factory == NULL) { 919c6d7c21Sopenharmony_ci MUTEX_Unlock(g_mutex); 929c6d7c21Sopenharmony_ci return EC_NOMEMORY; 939c6d7c21Sopenharmony_ci } 949c6d7c21Sopenharmony_ci factory->key.service = service; 959c6d7c21Sopenharmony_ci factory->key.feature = feature; 969c6d7c21Sopenharmony_ci factory->creator = creator; 979c6d7c21Sopenharmony_ci factory->destroyer = destroyer; 989c6d7c21Sopenharmony_ci int ret = VECTOR_Add(&g_factories, factory); 999c6d7c21Sopenharmony_ci MUTEX_Unlock(g_mutex); 1009c6d7c21Sopenharmony_ci if (ret == INVALID_INDEX) { 1019c6d7c21Sopenharmony_ci SAMGR_Free(factory); 1029c6d7c21Sopenharmony_ci return EC_NOMEMORY; 1039c6d7c21Sopenharmony_ci } 1049c6d7c21Sopenharmony_ci return EC_SUCCESS; 1059c6d7c21Sopenharmony_ci} 1069c6d7c21Sopenharmony_ci 1079c6d7c21Sopenharmony_cistatic Factory *GetFactory(const char *service, const char *feature) 1089c6d7c21Sopenharmony_ci{ 1099c6d7c21Sopenharmony_ci SaName key = {service, feature}; 1109c6d7c21Sopenharmony_ci Factory *factory = NULL; 1119c6d7c21Sopenharmony_ci MUTEX_Lock(g_mutex); 1129c6d7c21Sopenharmony_ci int16 index = VECTOR_FindByKey(&g_factories, &key); 1139c6d7c21Sopenharmony_ci if (index != INVALID_INDEX) { 1149c6d7c21Sopenharmony_ci factory = VECTOR_At(&g_factories, index); 1159c6d7c21Sopenharmony_ci } 1169c6d7c21Sopenharmony_ci MUTEX_Unlock(g_mutex); 1179c6d7c21Sopenharmony_ci return factory; 1189c6d7c21Sopenharmony_ci} 119