169570cc8Sopenharmony_ci/* 269570cc8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License. 569570cc8Sopenharmony_ci * You may obtain a copy of the License at 669570cc8Sopenharmony_ci * 769570cc8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 869570cc8Sopenharmony_ci * 969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and 1369570cc8Sopenharmony_ci * limitations under the License. 1469570cc8Sopenharmony_ci */ 1569570cc8Sopenharmony_ci 1669570cc8Sopenharmony_ci#include <dlfcn.h> 1769570cc8Sopenharmony_ci#include <string.h> 1869570cc8Sopenharmony_ci#include <unistd.h> 1969570cc8Sopenharmony_ci 2069570cc8Sopenharmony_ci#include "appspawn_server.h" 2169570cc8Sopenharmony_ci#include "appspawn_silk.h" 2269570cc8Sopenharmony_ci#include "appspawn_utils.h" 2369570cc8Sopenharmony_ci#include "config_policy_utils.h" 2469570cc8Sopenharmony_ci#include "cJSON.h" 2569570cc8Sopenharmony_ci#include "json_utils.h" 2669570cc8Sopenharmony_ci#include "securec.h" 2769570cc8Sopenharmony_ci 2869570cc8Sopenharmony_ci#define SILK_JSON_CONFIG_PATH "/vendor/etc/silk/silk.json" 2969570cc8Sopenharmony_ci#define SILK_JSON_ENABLE_ITEM "enabled_app_list" 3069570cc8Sopenharmony_ci#define SILK_JSON_LIBRARY_PATH "/vendor/lib64/chipsetsdk/libsilk.so.0.1" 3169570cc8Sopenharmony_ci 3269570cc8Sopenharmony_ci#define SILK_JSON_MAX 128 3369570cc8Sopenharmony_ci#define SILK_JSON_NAME_MAX 256 3469570cc8Sopenharmony_ci 3569570cc8Sopenharmony_cistruct SilkConfig { 3669570cc8Sopenharmony_ci char **configItems; 3769570cc8Sopenharmony_ci int configCursor; 3869570cc8Sopenharmony_ci}; 3969570cc8Sopenharmony_ci 4069570cc8Sopenharmony_cistatic struct SilkConfig g_silkConfig = {0}; 4169570cc8Sopenharmony_ci 4269570cc8Sopenharmony_cistatic void ParseSilkConfig(const cJSON *root, struct SilkConfig *config) 4369570cc8Sopenharmony_ci{ 4469570cc8Sopenharmony_ci cJSON *silkJson = cJSON_GetObjectItemCaseSensitive(root, SILK_JSON_ENABLE_ITEM); 4569570cc8Sopenharmony_ci if (silkJson == NULL) { 4669570cc8Sopenharmony_ci return; 4769570cc8Sopenharmony_ci } 4869570cc8Sopenharmony_ci 4969570cc8Sopenharmony_ci uint32_t configCount = (uint32_t)cJSON_GetArraySize(silkJson); 5069570cc8Sopenharmony_ci APPSPAWN_CHECK(configCount <= SILK_JSON_MAX, configCount = SILK_JSON_MAX, 5169570cc8Sopenharmony_ci "config count %{public}u is larger than %{public}d", configCount, SILK_JSON_MAX); 5269570cc8Sopenharmony_ci config->configItems = (char **)malloc(configCount * sizeof(char *)); 5369570cc8Sopenharmony_ci APPSPAWN_CHECK(config->configItems != NULL, return, "Alloc for silk config items failed"); 5469570cc8Sopenharmony_ci int ret = memset_s(config->configItems, configCount * sizeof(char *), 0, configCount * sizeof(char *)); 5569570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, free(config->configItems); 5669570cc8Sopenharmony_ci config->configItems = NULL; return, 5769570cc8Sopenharmony_ci "Memset silk config items failed"); 5869570cc8Sopenharmony_ci 5969570cc8Sopenharmony_ci for (uint32_t i = 0; i < configCount; ++i) { 6069570cc8Sopenharmony_ci const char *appName = cJSON_GetStringValue(cJSON_GetArrayItem(silkJson, i)); 6169570cc8Sopenharmony_ci APPSPAWN_CHECK(appName != NULL, break, "appName is NULL"); 6269570cc8Sopenharmony_ci APPSPAWN_LOGI("Enable silk appName %{public}s", appName); 6369570cc8Sopenharmony_ci 6469570cc8Sopenharmony_ci int len = strlen(appName) + 1; 6569570cc8Sopenharmony_ci APPSPAWN_CHECK(len <= SILK_JSON_NAME_MAX, continue, 6669570cc8Sopenharmony_ci "appName %{public}s is larger than the maximum limit", appName); 6769570cc8Sopenharmony_ci char **item = &config->configItems[config->configCursor]; 6869570cc8Sopenharmony_ci *item = (char *)malloc(len * sizeof(char)); 6969570cc8Sopenharmony_ci APPSPAWN_CHECK(*item != NULL, break, "Alloc for config item failed"); 7069570cc8Sopenharmony_ci 7169570cc8Sopenharmony_ci ret = memset_s(*item, len * sizeof(char), 0, len * sizeof(char)); 7269570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, free(*item); 7369570cc8Sopenharmony_ci *item = NULL; break, 7469570cc8Sopenharmony_ci "Memset config item %{public}s failed", appName); 7569570cc8Sopenharmony_ci 7669570cc8Sopenharmony_ci ret = strncpy_s(*item, len, appName, len - 1); 7769570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, free(*item); 7869570cc8Sopenharmony_ci *item = NULL; break, 7969570cc8Sopenharmony_ci "Copy config item %{public}s failed", appName); 8069570cc8Sopenharmony_ci config->configCursor++; 8169570cc8Sopenharmony_ci } 8269570cc8Sopenharmony_ci} 8369570cc8Sopenharmony_ci 8469570cc8Sopenharmony_civoid LoadSilkConfig(void) 8569570cc8Sopenharmony_ci{ 8669570cc8Sopenharmony_ci cJSON *root = GetJsonObjFromFile(SILK_JSON_CONFIG_PATH); 8769570cc8Sopenharmony_ci APPSPAWN_CHECK(root != NULL, return, "Failed to load silk config"); 8869570cc8Sopenharmony_ci ParseSilkConfig(root, &g_silkConfig); 8969570cc8Sopenharmony_ci cJSON_Delete(root); 9069570cc8Sopenharmony_ci} 9169570cc8Sopenharmony_ci 9269570cc8Sopenharmony_cistatic void FreeSilkConfigItems(void) 9369570cc8Sopenharmony_ci{ 9469570cc8Sopenharmony_ci for (int i = 0; i < g_silkConfig.configCursor; i++) { 9569570cc8Sopenharmony_ci if (g_silkConfig.configItems[i] != NULL) { 9669570cc8Sopenharmony_ci free(g_silkConfig.configItems[i]); 9769570cc8Sopenharmony_ci g_silkConfig.configItems[i] = NULL; 9869570cc8Sopenharmony_ci } 9969570cc8Sopenharmony_ci } 10069570cc8Sopenharmony_ci} 10169570cc8Sopenharmony_ci 10269570cc8Sopenharmony_cistatic void FreeSilkConfig(void) 10369570cc8Sopenharmony_ci{ 10469570cc8Sopenharmony_ci free(g_silkConfig.configItems); 10569570cc8Sopenharmony_ci g_silkConfig.configItems = NULL; 10669570cc8Sopenharmony_ci g_silkConfig.configCursor = 0; 10769570cc8Sopenharmony_ci} 10869570cc8Sopenharmony_ci 10969570cc8Sopenharmony_cistatic void FreeAllSilkConfig(void) 11069570cc8Sopenharmony_ci{ 11169570cc8Sopenharmony_ci FreeSilkConfigItems(); 11269570cc8Sopenharmony_ci FreeSilkConfig(); 11369570cc8Sopenharmony_ci} 11469570cc8Sopenharmony_ci 11569570cc8Sopenharmony_civoid LoadSilkLibrary(const char *packageName) 11669570cc8Sopenharmony_ci{ 11769570cc8Sopenharmony_ci APPSPAWN_CHECK(g_silkConfig.configItems != NULL, return, 11869570cc8Sopenharmony_ci "Load silk library failed for configItems is NULL"); 11969570cc8Sopenharmony_ci APPSPAWN_CHECK(packageName != NULL, FreeAllSilkConfig(); return, 12069570cc8Sopenharmony_ci "Load silk library failed for packageName is NULL"); 12169570cc8Sopenharmony_ci char **appName = NULL; 12269570cc8Sopenharmony_ci void *handle = NULL; 12369570cc8Sopenharmony_ci for (int i = 0; i < g_silkConfig.configCursor; i++) { 12469570cc8Sopenharmony_ci appName = &g_silkConfig.configItems[i]; 12569570cc8Sopenharmony_ci if (*appName == NULL) { 12669570cc8Sopenharmony_ci break; 12769570cc8Sopenharmony_ci } 12869570cc8Sopenharmony_ci if (handle == NULL && strcmp(*appName, packageName) == 0) { 12969570cc8Sopenharmony_ci handle = dlopen(SILK_JSON_LIBRARY_PATH, RTLD_NOW); 13069570cc8Sopenharmony_ci APPSPAWN_LOGI("Enable Silk AppName %{public}s result:%{public}s", 13169570cc8Sopenharmony_ci *appName, handle ? "success" : "failed"); 13269570cc8Sopenharmony_ci } 13369570cc8Sopenharmony_ci free(*appName); 13469570cc8Sopenharmony_ci *appName = NULL; 13569570cc8Sopenharmony_ci } 13669570cc8Sopenharmony_ci FreeSilkConfig(); 13769570cc8Sopenharmony_ci}