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