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 <dlfcn.h> 17#include <string.h> 18#include <unistd.h> 19 20#include "appspawn_server.h" 21#include "appspawn_silk.h" 22#include "appspawn_utils.h" 23#include "config_policy_utils.h" 24#include "cJSON.h" 25#include "json_utils.h" 26#include "securec.h" 27 28#define SILK_JSON_CONFIG_PATH "/vendor/etc/silk/silk.json" 29#define SILK_JSON_ENABLE_ITEM "enabled_app_list" 30#define SILK_JSON_LIBRARY_PATH "/vendor/lib64/chipsetsdk/libsilk.so.0.1" 31 32#define SILK_JSON_MAX 128 33#define SILK_JSON_NAME_MAX 256 34 35struct SilkConfig { 36 char **configItems; 37 int configCursor; 38}; 39 40static struct SilkConfig g_silkConfig = {0}; 41 42static void ParseSilkConfig(const cJSON *root, struct SilkConfig *config) 43{ 44 cJSON *silkJson = cJSON_GetObjectItemCaseSensitive(root, SILK_JSON_ENABLE_ITEM); 45 if (silkJson == NULL) { 46 return; 47 } 48 49 uint32_t configCount = (uint32_t)cJSON_GetArraySize(silkJson); 50 APPSPAWN_CHECK(configCount <= SILK_JSON_MAX, configCount = SILK_JSON_MAX, 51 "config count %{public}u is larger than %{public}d", configCount, SILK_JSON_MAX); 52 config->configItems = (char **)malloc(configCount * sizeof(char *)); 53 APPSPAWN_CHECK(config->configItems != NULL, return, "Alloc for silk config items failed"); 54 int ret = memset_s(config->configItems, configCount * sizeof(char *), 0, configCount * sizeof(char *)); 55 APPSPAWN_CHECK(ret == 0, free(config->configItems); 56 config->configItems = NULL; return, 57 "Memset silk config items failed"); 58 59 for (uint32_t i = 0; i < configCount; ++i) { 60 const char *appName = cJSON_GetStringValue(cJSON_GetArrayItem(silkJson, i)); 61 APPSPAWN_CHECK(appName != NULL, break, "appName is NULL"); 62 APPSPAWN_LOGI("Enable silk appName %{public}s", appName); 63 64 int len = strlen(appName) + 1; 65 APPSPAWN_CHECK(len <= SILK_JSON_NAME_MAX, continue, 66 "appName %{public}s is larger than the maximum limit", appName); 67 char **item = &config->configItems[config->configCursor]; 68 *item = (char *)malloc(len * sizeof(char)); 69 APPSPAWN_CHECK(*item != NULL, break, "Alloc for config item failed"); 70 71 ret = memset_s(*item, len * sizeof(char), 0, len * sizeof(char)); 72 APPSPAWN_CHECK(ret == 0, free(*item); 73 *item = NULL; break, 74 "Memset config item %{public}s failed", appName); 75 76 ret = strncpy_s(*item, len, appName, len - 1); 77 APPSPAWN_CHECK(ret == 0, free(*item); 78 *item = NULL; break, 79 "Copy config item %{public}s failed", appName); 80 config->configCursor++; 81 } 82} 83 84void LoadSilkConfig(void) 85{ 86 cJSON *root = GetJsonObjFromFile(SILK_JSON_CONFIG_PATH); 87 APPSPAWN_CHECK(root != NULL, return, "Failed to load silk config"); 88 ParseSilkConfig(root, &g_silkConfig); 89 cJSON_Delete(root); 90} 91 92static void FreeSilkConfigItems(void) 93{ 94 for (int i = 0; i < g_silkConfig.configCursor; i++) { 95 if (g_silkConfig.configItems[i] != NULL) { 96 free(g_silkConfig.configItems[i]); 97 g_silkConfig.configItems[i] = NULL; 98 } 99 } 100} 101 102static void FreeSilkConfig(void) 103{ 104 free(g_silkConfig.configItems); 105 g_silkConfig.configItems = NULL; 106 g_silkConfig.configCursor = 0; 107} 108 109static void FreeAllSilkConfig(void) 110{ 111 FreeSilkConfigItems(); 112 FreeSilkConfig(); 113} 114 115void LoadSilkLibrary(const char *packageName) 116{ 117 APPSPAWN_CHECK(g_silkConfig.configItems != NULL, return, 118 "Load silk library failed for configItems is NULL"); 119 APPSPAWN_CHECK(packageName != NULL, FreeAllSilkConfig(); return, 120 "Load silk library failed for packageName is NULL"); 121 char **appName = NULL; 122 void *handle = NULL; 123 for (int i = 0; i < g_silkConfig.configCursor; i++) { 124 appName = &g_silkConfig.configItems[i]; 125 if (*appName == NULL) { 126 break; 127 } 128 if (handle == NULL && strcmp(*appName, packageName) == 0) { 129 handle = dlopen(SILK_JSON_LIBRARY_PATH, RTLD_NOW); 130 APPSPAWN_LOGI("Enable Silk AppName %{public}s result:%{public}s", 131 *appName, handle ? "success" : "failed"); 132 } 133 free(*appName); 134 *appName = NULL; 135 } 136 FreeSilkConfig(); 137}