提交 dbe2d9bb 编写于 作者: C cheng_jinsong 提交者: Gitee

Merge branch 'master' of gitee.com:openharmony/startup_init_lite into codex

Signed-off-by: Ncheng_jinsong <chengjinsong2@huawei.com>
...@@ -33,11 +33,13 @@ enum INIT_BOOTSTAGE { ...@@ -33,11 +33,13 @@ enum INIT_BOOTSTAGE {
INIT_SERVICE_PARSE = 35, INIT_SERVICE_PARSE = 35,
INIT_POST_PERSIST_PARAM_LOAD = 40, INIT_POST_PERSIST_PARAM_LOAD = 40,
INIT_POST_CFG_LOAD = 50, INIT_POST_CFG_LOAD = 50,
INIT_CMD_RECORD = 51,
INIT_REBOOT = 55, INIT_REBOOT = 55,
INIT_SERVICE_CLEAR = 56, INIT_SERVICE_CLEAR = 56,
INIT_SERVICE_DUMP = 57, INIT_SERVICE_DUMP = 57,
INIT_SERVICE_FORK_BEFORE = 58, INIT_SERVICE_FORK_BEFORE = 58,
INIT_SERVICE_SET_PERMS = 59, INIT_SERVICE_SET_PERMS = 59,
INIT_SERVICE_FORK_AFTER = 60,
INIT_JOB_PARSE = 70, INIT_JOB_PARSE = 70,
}; };
...@@ -97,6 +99,15 @@ typedef struct tagSERVICE_INFO_CTX { ...@@ -97,6 +99,15 @@ typedef struct tagSERVICE_INFO_CTX {
const char *reserved; /* reserved info */ const char *reserved; /* reserved info */
} SERVICE_INFO_CTX; } SERVICE_INFO_CTX;
/**
* @brief init cmd info
*/
typedef struct InitCmdInfo {
const char *cmdName; /* cmd name */
const char *cmdContent; /* cmd content */
const char *reserved; /* reserved info */
} INIT_CMD_INFO;
/** /**
* @brief service config parse hook function prototype * @brief service config parse hook function prototype
* *
......
...@@ -137,9 +137,9 @@ static int GetSha256Value(const char *input, char *udid, int udidSize) ...@@ -137,9 +137,9 @@ static int GetSha256Value(const char *input, char *udid, int udidSize)
mbedtls_sha256_context context; mbedtls_sha256_context context;
mbedtls_sha256_init(&context); mbedtls_sha256_init(&context);
mbedtls_sha256_starts_ret(&context, 0); mbedtls_sha256_starts(&context, 0);
mbedtls_sha256_update_ret(&context, (const unsigned char *)input, strlen(input)); mbedtls_sha256_update(&context, (const unsigned char *)input, strlen(input));
mbedtls_sha256_finish_ret(&context, hash); mbedtls_sha256_finish(&context, hash);
for (size_t i = 0; i < HASH_LENGTH; i++) { for (size_t i = 0; i < HASH_LENGTH; i++) {
unsigned char value = hash[i]; unsigned char value = hash[i];
...@@ -216,4 +216,4 @@ INIT_LOCAL_API const char *GetFullName_(void) ...@@ -216,4 +216,4 @@ INIT_LOCAL_API const char *GetFullName_(void)
{ {
static const char *fillname = NULL; static const char *fillname = NULL;
return GetProperty("const.ohos.fullname", &fillname); return GetProperty("const.ohos.fullname", &fillname);
} }
\ No newline at end of file
...@@ -30,9 +30,7 @@ static int main_cmd(BShellHandle shell, int argc, char **argv) ...@@ -30,9 +30,7 @@ static int main_cmd(BShellHandle shell, int argc, char **argv)
printf("dump service info \n"); printf("dump service info \n");
CmdClientInit(INIT_CONTROL_FD_SOCKET_PATH, ACTION_DUMP, argv[1]); CmdClientInit(INIT_CONTROL_FD_SOCKET_PATH, ACTION_DUMP, argv[1]);
} else if (argc == DUMP_SERVICE_BOOTEVENT_CMD_ARGS) { } else if (argc == DUMP_SERVICE_BOOTEVENT_CMD_ARGS) {
if (strcmp(argv[1], "bootevent") == 0) { if (strcmp(argv[1], "parameter_service") == 0) {
printf("dump service bootevent info \n");
} else if (strcmp(argv[1], "parameter_service") == 0) {
printf("dump parameter service info \n"); printf("dump parameter service info \n");
} }
size_t serviceNameLen = strlen(argv[1]) + strlen(argv[2]) + 2; // 2 is \0 and # size_t serviceNameLen = strlen(argv[1]) + strlen(argv[2]) + 2; // 2 is \0 and #
...@@ -48,29 +46,32 @@ static int main_cmd(BShellHandle shell, int argc, char **argv) ...@@ -48,29 +46,32 @@ static int main_cmd(BShellHandle shell, int argc, char **argv)
return 0; return 0;
} }
static int ClearBootEvent(BShellHandle shell, int argc, char **argv) static int BootEventEnable(BShellHandle shell, int argc, char **argv)
{ {
return SystemSetParameter("ohos.servicectrl.clear", "bootevent"); if (SystemSetParameter("persist.init.bootevent.enable", "true") == 0) {
printf("bootevent enabled\n");
}
return 0;
} }
static int BootEventDisable(BShellHandle shell, int argc, char **argv)
static int SaveBootEvent(BShellHandle shell, int argc, char **argv)
{ {
return SystemSetParameter("ohos.servicectrl.save", "bootevent"); if (SystemSetParameter("persist.init.bootevent.enable", "false") == 0) {
printf("bootevent disabled\n");
}
return 0;
} }
MODULE_CONSTRUCTOR(void) MODULE_CONSTRUCTOR(void)
{ {
const CmdInfo infos[] = { const CmdInfo infos[] = {
{"dump_service", main_cmd, "dump one service info by serviceName", "dump_service serviceName", NULL}, {"dump_service", main_cmd, "dump one service info by serviceName", "dump_service serviceName", NULL},
{"dump_service", main_cmd, "dump one service bootevent", "dump_service serviceName bootevent", NULL},
{"dump_service", main_cmd, "dump all services info", "dump_service all", NULL}, {"dump_service", main_cmd, "dump all services info", "dump_service all", NULL},
{"dump_service", main_cmd, "dump parameter-service trigger", {"dump_service", main_cmd, "dump parameter-service trigger",
"dump_service parameter_service trigger", "dump_service parameter_service trigger"}, "dump_service parameter_service trigger", NULL},
{"dump_service", main_cmd, "dump all services bootevent", "dump_service all bootevent", NULL}, {"bootevent", BootEventEnable, "bootevent enable", "bootevent enable",
{"service", ClearBootEvent, "Clear all services bootevent", "service clear bootevent", "bootevent enable"},
"service clear bootevent"}, {"bootevent", BootEventDisable, "bootevent disable", "bootevent disable",
{"service", SaveBootEvent, "Save all services bootevent", "service save bootevent", "bootevent disable"},
"service save bootevent"},
}; };
for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) { for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) {
BShellEnvRegisterCmd(GetShellHandle(), &infos[i]); BShellEnvRegisterCmd(GetShellHandle(), &infos[i]);
......
...@@ -21,6 +21,7 @@ const.build.characteristics=default ...@@ -21,6 +21,7 @@ const.build.characteristics=default
const.product.model=ohos const.product.model=ohos
const.product.name="OpenHarmony 3.2" const.product.name="OpenHarmony 3.2"
persist.sys.usb.config=hdc persist.sys.usb.config=hdc
persist.init.bootevent.enable=true
const.sandbox=enable const.sandbox=enable
const.product.devicetype=default const.product.devicetype=default
const.software.model=default const.software.model=default
......
...@@ -28,6 +28,7 @@ startup.appspawn. = root:root:0750 ...@@ -28,6 +28,7 @@ startup.appspawn. = root:root:0750
startup.uevent. = ueventd:ueventd:0775 startup.uevent. = ueventd:ueventd:0775
persist.init.debug. = root:root:0775:int persist.init.debug. = root:root:0775:int
persist.init.bootevent.enable = root:root:0775:bool
persist.appspawn. = root:root:0775 persist.appspawn. = root:root:0775
#udid and sn, only read #udid and sn, only read
......
...@@ -38,6 +38,25 @@ ...@@ -38,6 +38,25 @@
#include "init_utils.h" #include "init_utils.h"
#include "securec.h" #include "securec.h"
#ifndef OHOS_LITE
#include "hookmgr.h"
#include "bootstage.h"
/**
* init cmd hooking execute
*/
static void InitCmdHookExecute(const char *cmdName, const char *cmdContent, INIT_TIMING_STAT *cmdTimer)
{
INIT_CMD_INFO context;
context.cmdName = cmdName;
context.cmdContent = cmdContent;
context.reserved = (const char *)cmdTimer;
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_CMD_RECORD, (void *)(&context), NULL);
}
#endif
static char *AddOneArg(const char *param, size_t paramLen) static char *AddOneArg(const char *param, size_t paramLen)
{ {
int valueCount = 1; int valueCount = 1;
...@@ -719,6 +738,9 @@ void DoCmdByName(const char *name, const char *cmdContent) ...@@ -719,6 +738,9 @@ void DoCmdByName(const char *name, const char *cmdContent)
} }
(void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.endTime); (void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.endTime);
long long diff = InitDiffTime(&cmdTimer); long long diff = InitDiffTime(&cmdTimer);
#ifndef OHOS_LITE
InitCmdHookExecute(name, cmdContent, &cmdTimer);
#endif
INIT_LOGV("Execute command \"%s %s\" took %lld ms", name, cmdContent, diff / 1000); // 1000 is convert us to ms INIT_LOGV("Execute command \"%s %s\" took %lld ms", name, cmdContent, diff / 1000); // 1000 is convert us to ms
} }
...@@ -751,5 +773,8 @@ void DoCmdByIndex(int index, const char *cmdContent) ...@@ -751,5 +773,8 @@ void DoCmdByIndex(int index, const char *cmdContent)
} }
(void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.endTime); (void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.endTime);
long long diff = InitDiffTime(&cmdTimer); long long diff = InitDiffTime(&cmdTimer);
#ifndef OHOS_LITE
InitCmdHookExecute(cmdName, cmdContent, &cmdTimer);
#endif
INIT_LOGV("Execute command \"%s %s\" took %lld ms", cmdName, cmdContent, diff / 1000); // 1000 is convert us to ms INIT_LOGV("Execute command \"%s %s\" took %lld ms", cmdName, cmdContent, diff / 1000); // 1000 is convert us to ms
} }
...@@ -385,6 +385,12 @@ int ServiceStart(Service *service) ...@@ -385,6 +385,12 @@ int ServiceStart(Service *service)
INIT_LOGI("Service %s(pid %d) started", service->name, pid); INIT_LOGI("Service %s(pid %d) started", service->name, pid);
service->pid = pid; service->pid = pid;
NotifyServiceChange(service, SERVICE_STARTED); NotifyServiceChange(service, SERVICE_STARTED);
#ifndef OHOS_LITE
/*
* after service fork hooks
*/
ServiceHookExecute(service->name, (const char *)&pid, INIT_SERVICE_FORK_AFTER);
#endif
return SERVICE_SUCCESS; return SERVICE_SUCCESS;
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "init_module_engine.h" #include "init_module_engine.h"
#include "init_cmdexecutor.h"
#include "trigger_manager.h" #include "trigger_manager.h"
#include "init_log.h" #include "init_log.h"
#include "plugin_adapter.h" #include "plugin_adapter.h"
...@@ -23,17 +24,23 @@ ...@@ -23,17 +24,23 @@
#include "bootstage.h" #include "bootstage.h"
#include "securec.h" #include "securec.h"
#include "init_utils.h" #include "init_utils.h"
#include "init_cmds.h"
#define BOOT_EVENT_PARA_PREFIX "bootevent." #define BOOT_EVENT_PARA_PREFIX "bootevent."
#define BOOT_EVENT_PARA_PREFIX_LEN 10 #define BOOT_EVENT_PARA_PREFIX_LEN 10
#define BOOT_EVENT_TIMESTAMP_MAX_LEN 50 #define BOOT_EVENT_TIMESTAMP_MAX_LEN 50
#define BOOT_EVENT_FILEPATH_MAX_LEN 60 #define BOOT_EVENT_FILEPATH_MAX_LEN 60
#define BOOT_EVENT_FINISH 2
#define SECTOMSEC 1000000 #define SECTOMSEC 1000000
#define SECTONSEC 1000000000 #define SECTONSEC 1000000000
#define MSECTONSEC 1000 #define MSECTONSEC 1000
#define SAVEINITBOOTEVENTMSEC 100000
#define BOOTEVENT_OUTPUT_PATH "/data/service/el0/startup/init/" #define BOOTEVENT_OUTPUT_PATH "/data/service/el0/startup/init/"
static int g_bootEventNum = 0; static int g_bootEventNum = 0;
// check bootevent enable
static int g_bootEventEnable = 1;
enum { enum {
BOOTEVENT_FORK, BOOTEVENT_FORK,
BOOTEVENT_READY, BOOTEVENT_READY,
...@@ -43,6 +50,7 @@ enum { ...@@ -43,6 +50,7 @@ enum {
typedef struct tagBOOT_EVENT_PARAM_ITEM { typedef struct tagBOOT_EVENT_PARAM_ITEM {
ListNode node; ListNode node;
char *paramName; char *paramName;
int pid;
struct timespec timestamp[BOOTEVENT_MAX]; struct timespec timestamp[BOOTEVENT_MAX];
} BOOT_EVENT_PARAM_ITEM; } BOOT_EVENT_PARAM_ITEM;
...@@ -112,7 +120,7 @@ static void AddInitBootEvent(const char *bootEventName) ...@@ -112,7 +120,7 @@ static void AddInitBootEvent(const char *bootEventName)
return; return;
} }
BOOT_EVENT_PARAM_ITEM *item = malloc(sizeof(BOOT_EVENT_PARAM_ITEM)); BOOT_EVENT_PARAM_ITEM *item = calloc(1, sizeof(BOOT_EVENT_PARAM_ITEM));
if (item == NULL) { if (item == NULL) {
return; return;
} }
...@@ -132,6 +140,15 @@ static void AddInitBootEvent(const char *bootEventName) ...@@ -132,6 +140,15 @@ static void AddInitBootEvent(const char *bootEventName)
#define BOOT_EVENT_BOOT_COMPLETED "bootevent.boot.completed" #define BOOT_EVENT_BOOT_COMPLETED "bootevent.boot.completed"
static void BootEventDestroy(ListNode *node)
{
BOOT_EVENT_PARAM_ITEM *bootEvent = (BOOT_EVENT_PARAM_ITEM *)node;
INIT_CHECK(bootEvent->paramName == NULL, free((void *)bootEvent->paramName));
free((void *)bootEvent);
}
static int SaveServiceBootEvent();
static void BootEventParaFireByName(const char *paramName) static void BootEventParaFireByName(const char *paramName)
{ {
ListNode *found = NULL; ListNode *found = NULL;
...@@ -158,12 +175,20 @@ static void BootEventParaFireByName(const char *paramName) ...@@ -158,12 +175,20 @@ static void BootEventParaFireByName(const char *paramName)
// All parameters are fired, set boot completed now ... // All parameters are fired, set boot completed now ...
INIT_LOGI("All boot events are fired, boot complete now ..."); INIT_LOGI("All boot events are fired, boot complete now ...");
SystemWriteParam(BOOT_EVENT_BOOT_COMPLETED, "true"); SystemWriteParam(BOOT_EVENT_BOOT_COMPLETED, "true");
g_bootEventEnable = BOOT_EVENT_FINISH;
SaveServiceBootEvent();
const char *clearBootEventArgv[] = {"bootevent"};
// clear servie extra data
PluginExecCmd("clear", ARRAY_LENGTH(clearBootEventArgv), clearBootEventArgv);
return; return;
} }
#define BOOT_EVENT_FIELD_NAME "bootevents" #define BOOT_EVENT_FIELD_NAME "bootevents"
static void ServiceParseBootEventHook(SERVICE_PARSE_CTX *serviceParseCtx) static void ServiceParseBootEventHook(SERVICE_PARSE_CTX *serviceParseCtx)
{ {
if (g_bootEventEnable == 0) {
return;
}
int cnt; int cnt;
cJSON *bootEvents = cJSON_GetObjectItem(serviceParseCtx->serviceNode, BOOT_EVENT_FIELD_NAME); cJSON *bootEvents = cJSON_GetObjectItem(serviceParseCtx->serviceNode, BOOT_EVENT_FIELD_NAME);
...@@ -198,11 +223,54 @@ static void ServiceParseBootEventHook(SERVICE_PARSE_CTX *serviceParseCtx) ...@@ -198,11 +223,54 @@ static void ServiceParseBootEventHook(SERVICE_PARSE_CTX *serviceParseCtx)
} }
} }
static void AddCmdBootEvent(int argc, const char **argv)
{
if (argc < 4) { // 4 is min args cmd boot event required
return;
}
BOOT_EVENT_PARAM_ITEM *item = calloc(1, sizeof(BOOT_EVENT_PARAM_ITEM));
if (item == NULL) {
return;
}
OH_ListInit(&item->node);
item->timestamp[BOOTEVENT_FORK] = ((INIT_TIMING_STAT *)argv[3])->startTime; // 3 args
item->timestamp[BOOTEVENT_READY] = ((INIT_TIMING_STAT *)argv[3])->endTime; // 3 args
int cmdLen = strlen(argv[1]) + strlen(argv[2]) + 1; // 2 args 1 '\0'
item->paramName = calloc(1, cmdLen);
if (item->paramName == NULL) {
free(item);
return;
}
for (int i = 1; i < 3; i++) { // 3 cmd content end
INIT_CHECK_ONLY_ELOG(strcat_s(item->paramName, cmdLen, argv[i]) >= 0, "combine cmd args failed");
}
OH_ListAddTail(&bootEventList, (ListNode *)&item->node);
return;
}
static int DoBootEventCmd(int id, const char *name, int argc, const char **argv) static int DoBootEventCmd(int id, const char *name, int argc, const char **argv)
{ {
if (g_bootEventEnable == BOOT_EVENT_FINISH) {
return 0;
}
// clear init boot events that recorded before persist param read
if (g_bootEventEnable == 0) {
const char *clearBootEventArgv[] = {"bootevent"};
PluginExecCmd("clear", ARRAY_LENGTH(clearBootEventArgv), clearBootEventArgv);
OH_ListRemoveAll(&bootEventList, BootEventDestroy);
g_bootEventEnable = BOOT_EVENT_FINISH;
return 0;
}
PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter"); PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
if (strcmp(argv[0], "init") == 0) { if (strcmp(argv[0], "init") == 0) {
if (argc < 2) { // 2 args
return 0;
}
AddInitBootEvent(argv[1]); AddInitBootEvent(argv[1]);
} else if (strcmp(argv[0], "cmd") == 0) {
AddCmdBootEvent(argc, argv);
} else { } else {
// argv[0] samgr.ready.true // argv[0] samgr.ready.true
BootEventParaFireByName(argv[0]); BootEventParaFireByName(argv[0]);
...@@ -210,15 +278,15 @@ static int DoBootEventCmd(int id, const char *name, int argc, const char **argv) ...@@ -210,15 +278,15 @@ static int DoBootEventCmd(int id, const char *name, int argc, const char **argv)
return 0; return 0;
} }
static int AddItemToJson(cJSON *root, const char *name, double startTime, int tid, double durTime) static int AddItemToJson(cJSON *root, const char *name, double startTime, int pid, double durTime)
{ {
cJSON *obj = cJSON_CreateObject(); // release obj at traverse done cJSON *obj = cJSON_CreateObject(); // release obj at traverse done
INIT_CHECK_RETURN_VALUE(obj != NULL, -1); INIT_CHECK_RETURN_VALUE(obj != NULL, -1);
cJSON_AddStringToObject(obj, "name", name); cJSON_AddStringToObject(obj, "name", name);
cJSON_AddNumberToObject(obj, "ts", startTime); cJSON_AddNumberToObject(obj, "ts", startTime);
cJSON_AddStringToObject(obj, "ph", "X"); cJSON_AddStringToObject(obj, "ph", "X");
cJSON_AddNumberToObject(obj, "pid", 0); cJSON_AddNumberToObject(obj, "pid", pid);
cJSON_AddNumberToObject(obj, "tid", tid); cJSON_AddNumberToObject(obj, "tid", pid);
cJSON_AddNumberToObject(obj, "dur", durTime); cJSON_AddNumberToObject(obj, "dur", durTime);
cJSON_AddItemToArray(root, obj); cJSON_AddItemToArray(root, obj);
return 0; return 0;
...@@ -226,25 +294,35 @@ static int AddItemToJson(cJSON *root, const char *name, double startTime, int ti ...@@ -226,25 +294,35 @@ static int AddItemToJson(cJSON *root, const char *name, double startTime, int ti
static int BootEventTraversal(ListNode *node, void *root) static int BootEventTraversal(ListNode *node, void *root)
{ {
static int tid = 1; // 1 boot event start num static int start = 0;
BOOT_EVENT_PARAM_ITEM *item = (BOOT_EVENT_PARAM_ITEM *)node; BOOT_EVENT_PARAM_ITEM *item = (BOOT_EVENT_PARAM_ITEM *)node;
double forkTime = item->timestamp[BOOTEVENT_FORK].tv_sec * SECTOMSEC + double forkTime = item->timestamp[BOOTEVENT_FORK].tv_sec * SECTOMSEC +
(double)item->timestamp[BOOTEVENT_FORK].tv_nsec / MSECTONSEC; (double)item->timestamp[BOOTEVENT_FORK].tv_nsec / MSECTONSEC;
double readyTime = item->timestamp[BOOTEVENT_READY].tv_sec * SECTOMSEC + double readyTime = item->timestamp[BOOTEVENT_READY].tv_sec * SECTOMSEC +
(double)item->timestamp[BOOTEVENT_READY].tv_nsec / MSECTONSEC; (double)item->timestamp[BOOTEVENT_READY].tv_nsec / MSECTONSEC;
double durTime = readyTime - forkTime; double durTime = readyTime - forkTime;
if (tid == 1) { if (item->pid == 0) {
// set time datum is 0 if (durTime < SAVEINITBOOTEVENTMSEC) {
return 0;
}
item->pid = 1; // 1 is init pid
}
if (start == 0) {
// set trace start time 0
INIT_CHECK_RETURN_VALUE(AddItemToJson((cJSON *)root, item->paramName, 0, INIT_CHECK_RETURN_VALUE(AddItemToJson((cJSON *)root, item->paramName, 0,
1, 0) == 0, -1); 1, 0) == 0, -1);
start++;
} }
INIT_CHECK_RETURN_VALUE(AddItemToJson((cJSON *)root, item->paramName, forkTime, INIT_CHECK_RETURN_VALUE(AddItemToJson((cJSON *)root, item->paramName, forkTime,
tid++, durTime > 0 ? durTime : 0) == 0, -1); item->pid, durTime > 0 ? durTime : 0) == 0, -1);
return 0; return 0;
} }
static int SaveServiceBootEvent(int id, const char *name, int argc, const char **argv) static int SaveServiceBootEvent()
{ {
if (g_bootEventEnable == 0) {
return 0;
}
time_t nowTime = time(NULL); time_t nowTime = time(NULL);
INIT_CHECK_RETURN_VALUE(nowTime > 0, -1); INIT_CHECK_RETURN_VALUE(nowTime > 0, -1);
struct tm *p = localtime(&nowTime); struct tm *p = localtime(&nowTime);
...@@ -281,36 +359,10 @@ static int ParamSetBootEventHook(const HOOK_INFO *hookInfo, void *cookie) ...@@ -281,36 +359,10 @@ static int ParamSetBootEventHook(const HOOK_INFO *hookInfo, void *cookie)
{ {
if (g_executorId == -1) { if (g_executorId == -1) {
g_executorId = AddCmdExecutor("bootevent", DoBootEventCmd); g_executorId = AddCmdExecutor("bootevent", DoBootEventCmd);
AddCmdExecutor("save.bootevent", SaveServiceBootEvent);
} }
return 0; return 0;
} }
static void DumpServiceBootEvent(SERVICE_INFO_CTX *serviceCtx)
{
if (serviceCtx->reserved != NULL && strcmp(serviceCtx->reserved, "bootevent") != 0) {
return;
}
for (int i = HOOK_ID_BOOTEVENT; i < HOOK_ID_BOOTEVENT_MAX; i++) {
ServiceExtData *serviceExtData = GetServiceExtData(serviceCtx->serviceName, i);
if (serviceExtData == NULL) {
return;
}
BOOT_EVENT_PARAM_ITEM *item = (BOOT_EVENT_PARAM_ITEM *)serviceExtData->data;
char bootEventForkTimeStamp[BOOT_EVENT_TIMESTAMP_MAX_LEN] = "";
char bootEventReadyTimeStamp[BOOT_EVENT_TIMESTAMP_MAX_LEN] = "";
INIT_CHECK_ONLY_RETURN(sprintf_s(bootEventForkTimeStamp, BOOT_EVENT_TIMESTAMP_MAX_LEN, "%f",
item->timestamp[BOOTEVENT_FORK].tv_sec +
(double)item->timestamp[BOOTEVENT_FORK].tv_nsec / SECTONSEC) >= 0);
INIT_CHECK_ONLY_RETURN(sprintf_s(bootEventReadyTimeStamp, BOOT_EVENT_TIMESTAMP_MAX_LEN, "%f",
(long)item->timestamp[BOOTEVENT_READY].tv_sec +
(double)item->timestamp[BOOTEVENT_READY].tv_nsec / SECTONSEC) >= 0);
printf("\t%-20.20s\t%-50s\t%-20.20s\t%-20.20s\n", serviceCtx->serviceName, item->paramName,
bootEventForkTimeStamp, bootEventReadyTimeStamp);
}
return;
}
static void ClearServiceBootEvent(SERVICE_INFO_CTX *serviceCtx) static void ClearServiceBootEvent(SERVICE_INFO_CTX *serviceCtx)
{ {
if (serviceCtx->reserved == NULL || strcmp(serviceCtx->reserved, "bootevent") == 0) { if (serviceCtx->reserved == NULL || strcmp(serviceCtx->reserved, "bootevent") == 0) {
...@@ -322,29 +374,65 @@ static void ClearServiceBootEvent(SERVICE_INFO_CTX *serviceCtx) ...@@ -322,29 +374,65 @@ static void ClearServiceBootEvent(SERVICE_INFO_CTX *serviceCtx)
free(((BOOT_EVENT_PARAM_ITEM *)extData->data)->paramName); free(((BOOT_EVENT_PARAM_ITEM *)extData->data)->paramName);
OH_ListRemove(&((BOOT_EVENT_PARAM_ITEM *)extData->data)->node); OH_ListRemove(&((BOOT_EVENT_PARAM_ITEM *)extData->data)->node);
DelServiceExtData(serviceCtx->serviceName, i); DelServiceExtData(serviceCtx->serviceName, i);
g_bootEventNum--;
} }
// clear service extra data first
return;
}
if (strcmp(serviceCtx->reserved, "clearInitBootevent") == 0) {
// clear init boot event
OH_ListRemoveAll(&bootEventList, BootEventDestroy);
g_bootEventNum = 0;
} }
return; return;
} }
static void SetServiceBootEventFork(SERVICE_INFO_CTX *serviceCtx) static void SetServiceBootEventFork(SERVICE_INFO_CTX *serviceCtx)
{ {
if (g_bootEventEnable == 0) {
return;
}
for (int i = HOOK_ID_BOOTEVENT; i < HOOK_ID_BOOTEVENT_MAX; i++) { for (int i = HOOK_ID_BOOTEVENT; i < HOOK_ID_BOOTEVENT_MAX; i++) {
ServiceExtData *extData = GetServiceExtData(serviceCtx->serviceName, i); ServiceExtData *extData = GetServiceExtData(serviceCtx->serviceName, i);
if (extData == NULL || ((BOOT_EVENT_PARAM_ITEM *)extData->data)->timestamp[BOOTEVENT_FORK].tv_sec != 0) { if (extData == NULL) {
return; return;
} }
if (serviceCtx->reserved != NULL) {
((BOOT_EVENT_PARAM_ITEM *)extData->data)->pid = *((int *)serviceCtx->reserved);
continue;
}
INIT_CHECK_ONLY_RETURN(clock_gettime(CLOCK_MONOTONIC, INIT_CHECK_ONLY_RETURN(clock_gettime(CLOCK_MONOTONIC,
&(((BOOT_EVENT_PARAM_ITEM *)extData->data)->timestamp[BOOTEVENT_FORK])) == 0); &(((BOOT_EVENT_PARAM_ITEM *)extData->data)->timestamp[BOOTEVENT_FORK])) == 0);
} }
return; return;
} }
static int GetBootEventFlag(const HOOK_INFO *info, void *cookie)
{
char BootEventOpen[6] = ""; // 6 is length of bool value
uint32_t len = sizeof(BootEventOpen);
SystemReadParam("persist.init.bootevent.enable", BootEventOpen, &len);
if (strcmp(BootEventOpen, "true") != 0) {
g_bootEventEnable = 0;
}
return 0;
}
static int RecordInitCmd(const HOOK_INFO *info, void *cookie)
{
INIT_CMD_INFO *cmdCtx = (INIT_CMD_INFO *)cookie;
const char *bootEventArgv[] = {"cmd", cmdCtx->cmdName, cmdCtx->cmdContent, cmdCtx->reserved};
return DoBootEventCmd(0, NULL, ARRAY_LENGTH(bootEventArgv), bootEventArgv);
}
MODULE_CONSTRUCTOR(void) MODULE_CONSTRUCTOR(void)
{ {
HOOK_INFO info = {INIT_CMD_RECORD, 0, RecordInitCmd, NULL};
HookMgrAddEx(GetBootStageHookMgr(), &info);
InitAddServiceHook(SetServiceBootEventFork, INIT_SERVICE_FORK_BEFORE); InitAddServiceHook(SetServiceBootEventFork, INIT_SERVICE_FORK_BEFORE);
InitAddServiceHook(SetServiceBootEventFork, INIT_SERVICE_FORK_AFTER);
InitAddServiceHook(ClearServiceBootEvent, INIT_SERVICE_CLEAR); InitAddServiceHook(ClearServiceBootEvent, INIT_SERVICE_CLEAR);
InitAddServiceHook(DumpServiceBootEvent, INIT_SERVICE_DUMP);
InitAddServiceParseHook(ServiceParseBootEventHook); InitAddServiceParseHook(ServiceParseBootEventHook);
InitAddGlobalInitHook(0, ParamSetBootEventHook); InitAddGlobalInitHook(0, ParamSetBootEventHook);
InitAddPostPersistParamLoadHook(0, GetBootEventFlag);
} }
...@@ -119,6 +119,8 @@ static int CmdClear(int id, const char *name, int argc, const char **argv) ...@@ -119,6 +119,8 @@ static int CmdClear(int id, const char *name, int argc, const char **argv)
HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_CLEAR, (void *)&ctx, NULL); HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_CLEAR, (void *)&ctx, NULL);
node = GetNextGroupNode(NODE_TYPE_SERVICES, node); node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
} }
ctx.reserved = "clearInitBootevent";
HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_CLEAR, (void *)&ctx, NULL);
return 0; return 0;
} }
......
...@@ -35,7 +35,6 @@ const ParamCmdInfo *GetServiceCtl(size_t *size) ...@@ -35,7 +35,6 @@ const ParamCmdInfo *GetServiceCtl(size_t *size)
{"ohos.servicectrl.install", "install", "install" }, {"ohos.servicectrl.install", "install", "install" },
{"ohos.servicectrl.uninstall", "uninstall", "uninstall" }, {"ohos.servicectrl.uninstall", "uninstall", "uninstall" },
{"ohos.servicectrl.clear", "clear", "clear" }, {"ohos.servicectrl.clear", "clear", "clear" },
{"ohos.servicectrl.save", "save.bootevent", "save.bootevent" },
{"ohos.servicectrl.bootchart", "bootchart", "bootchart" }, {"ohos.servicectrl.bootchart", "bootchart", "bootchart" },
{"ohos.servicectrl.timer_start", "timer_start", "timer_start " }, {"ohos.servicectrl.timer_start", "timer_start", "timer_start " },
{"ohos.servicectrl.timer_stop", "timer_stop", "timer_stop" }, {"ohos.servicectrl.timer_stop", "timer_stop", "timer_stop" },
......
...@@ -68,7 +68,7 @@ ohos_prebuilt_seccomp("system_filter") { ...@@ -68,7 +68,7 @@ ohos_prebuilt_seccomp("system_filter") {
sources = [] sources = []
if (target_cpu == "arm") { if (target_cpu == "arm") {
sources += [ "seccomp_policy/system_arm.seccomp.policy" ] sources += [ "seccomp_policy/system_arm.seccomp.policy" ]
} else if (target_cpu == "arm64") { } else if (target_cpu == "arm64" || target_cpu == "x86_64") {
sources += [ sources += [
# 64-bit machine also need check use 32-bit syscall # 64-bit machine also need check use 32-bit syscall
"seccomp_policy/system_arm.seccomp.policy", "seccomp_policy/system_arm.seccomp.policy",
...@@ -88,7 +88,7 @@ ohos_prebuilt_seccomp("appspawn_filter") { ...@@ -88,7 +88,7 @@ ohos_prebuilt_seccomp("appspawn_filter") {
sources = [] sources = []
if (target_cpu == "arm") { if (target_cpu == "arm") {
sources += [ "seccomp_policy/spawn_arm.seccomp.policy" ] sources += [ "seccomp_policy/spawn_arm.seccomp.policy" ]
} else if (target_cpu == "arm64") { } else if (target_cpu == "arm64" || target_cpu == "x86_64") {
sources += [ sources += [
# 64-bit machine also need check use 32-bit syscall # 64-bit machine also need check use 32-bit syscall
"seccomp_policy/spawn_arm.seccomp.policy", "seccomp_policy/spawn_arm.seccomp.policy",
...@@ -107,7 +107,7 @@ ohos_prebuilt_seccomp("appspawn_filter") { ...@@ -107,7 +107,7 @@ ohos_prebuilt_seccomp("appspawn_filter") {
ohos_prebuilt_seccomp("nwebspawn_filter") { ohos_prebuilt_seccomp("nwebspawn_filter") {
if (target_cpu == "arm") { if (target_cpu == "arm") {
sources = [ "seccomp_policy/renderer_arm.seccomp.policy" ] sources = [ "seccomp_policy/renderer_arm.seccomp.policy" ]
} else if (target_cpu == "arm64") { } else if (target_cpu == "arm64" || target_cpu == "x86_64") {
sources = [ "seccomp_policy/renderer_arm64.seccomp.policy" ] sources = [ "seccomp_policy/renderer_arm64.seccomp.policy" ]
} }
...@@ -123,7 +123,7 @@ ohos_prebuilt_seccomp("app_filter") { ...@@ -123,7 +123,7 @@ ohos_prebuilt_seccomp("app_filter") {
sources = [] sources = []
if (target_cpu == "arm") { if (target_cpu == "arm") {
sources += [ "seccomp_policy/app_arm.seccomp.policy" ] sources += [ "seccomp_policy/app_arm.seccomp.policy" ]
} else if (target_cpu == "arm64") { } else if (target_cpu == "arm64" || target_cpu == "x86_64") {
sources += [ sources += [
# 64-bit machine also need check use 32-bit syscall # 64-bit machine also need check use 32-bit syscall
"seccomp_policy/app_arm.seccomp.policy", "seccomp_policy/app_arm.seccomp.policy",
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
namespace OHOS { namespace OHOS {
namespace init_param { namespace init_param {
void Watcher::OnParameterChange(const std::string &name, const std::string &value) void Watcher::OnParameterChange(const std::string &prefix, const std::string &name, const std::string &value)
{ {
UNUSED(name); UNUSED(name);
UNUSED(value); UNUSED(value);
......
...@@ -26,7 +26,7 @@ public: ...@@ -26,7 +26,7 @@ public:
Watcher() = default; Watcher() = default;
virtual ~Watcher() = default; virtual ~Watcher() = default;
void OnParameterChange(const std::string &name, const std::string &value) override; void OnParameterChange(const std::string &prefix, const std::string &name, const std::string &value) override;
}; };
} // namespace init_param } // namespace init_param
} // namespace OHOS } // namespace OHOS
......
...@@ -25,36 +25,40 @@ ...@@ -25,36 +25,40 @@
namespace OHOS { namespace OHOS {
namespace init_param { namespace init_param {
WatcherManagerKits &WatcherManagerKits::GetInstance() WatcherManagerKits &WatcherManagerKits::GetInstance(void)
{ {
return DelayedRefSingleton<WatcherManagerKits>::GetInstance(); return DelayedRefSingleton<WatcherManagerKits>::GetInstance();
} }
WatcherManagerKits::WatcherManagerKits() {} WatcherManagerKits::WatcherManagerKits(void) {}
WatcherManagerKits::~WatcherManagerKits() {} WatcherManagerKits::~WatcherManagerKits(void) {}
void WatcherManagerKits::ResetService(const wptr<IRemoteObject> &remote) void WatcherManagerKits::ResetService(const wptr<IRemoteObject> &remote)
{ {
WATCHER_LOGI("Remote is dead, reset service instance"); WATCHER_LOGI("Remote is dead, reset service instance");
bool resetService = false; std::lock_guard<std::mutex> lock(lock_);
{ if (watcherManager_ != nullptr) {
std::lock_guard<std::mutex> lock(lock_); sptr<IRemoteObject> object = watcherManager_->AsObject();
if (watcherManager_ != nullptr) { if ((object != nullptr) && (remote == object)) {
sptr<IRemoteObject> object = watcherManager_->AsObject(); object->RemoveDeathRecipient(deathRecipient_);
if ((object != nullptr) && (remote == object)) { watcherManager_ = nullptr;
object->RemoveDeathRecipient(deathRecipient_); remoteWatcherId_ = 0;
watcherManager_ = nullptr; remoteWatcher_ = nullptr;
resetService = true; if (threadForReWatch_ != nullptr) {
WATCHER_LOGI("Thead exist, delete thread");
stop_ = true;
threadForReWatch_->join();
delete threadForReWatch_;
} }
stop_ = false;
threadForReWatch_ = new (std::nothrow)std::thread(&WatcherManagerKits::ReAddWatcher, this);
WATCHER_CHECK(threadForReWatch_ != nullptr, return, "Failed to create thread");
} }
} }
if (resetService) {
ReAddWatcher();
}
} }
sptr<IWatcherManager> WatcherManagerKits::GetService() sptr<IWatcherManager> WatcherManagerKits::GetService(void)
{ {
std::lock_guard<std::mutex> lock(lock_); std::lock_guard<std::mutex> lock(lock_);
if (watcherManager_ != nullptr) { if (watcherManager_ != nullptr) {
...@@ -84,92 +88,125 @@ void WatcherManagerKits::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject> ...@@ -84,92 +88,125 @@ void WatcherManagerKits::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject>
DelayedRefSingleton<WatcherManagerKits>::GetInstance().ResetService(remote); DelayedRefSingleton<WatcherManagerKits>::GetInstance().ResetService(remote);
} }
WatcherManagerKits::ParamWatcherKitPtr WatcherManagerKits::GetParamWatcher(const std::string &keyPrefix) void WatcherManagerKits::ReAddWatcher(void)
{
std::lock_guard<std::mutex> lock(mutex_);
if (watchers_.find(keyPrefix) == watchers_.end()) {
return nullptr;
}
return watchers_[keyPrefix];
}
void WatcherManagerKits::ReAddWatcher()
{ {
WATCHER_LOGV("ReAddWatcher "); WATCHER_LOGV("ReAddWatcher");
int count = 0; int count = 0;
const int maxRetryCount = 100; const int maxRetryCount = 100;
const int sleepTime = 100; const int sleepTime = 100;
auto watcherManager = GetService(); auto watcherManager = GetService();
while (watcherManager == nullptr && count < maxRetryCount) { while (watcherManager == nullptr && count < maxRetryCount) {
if (stop_) {
return;
}
watcherManager = GetService(); watcherManager = GetService();
usleep(sleepTime); usleep(sleepTime);
count++; count++;
} }
WATCHER_LOGV("ReAddWatcher count %d ", count);
WATCHER_CHECK(watcherManager != nullptr, return, "Failed to get watcher manager"); WATCHER_CHECK(watcherManager != nullptr, return, "Failed to get watcher manager");
// add or get remote agent
uint32_t remoteWatcherId = GetRemoteWatcher();
WATCHER_CHECK(remoteWatcherId > 0, return, "Failed to get remote agent");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
for (auto iter = watchers_.begin(); iter != watchers_.end(); iter++) { for (auto iter = watchers_.begin(); iter != watchers_.end(); iter++) {
if (stop_) {
return;
}
if (iter->second == nullptr) { if (iter->second == nullptr) {
continue; continue;
} }
WATCHER_LOGV("ReAddWatcher keyPrefix %s ", iter->first.c_str()); WATCHER_LOGI("Add old watcher keyPrefix %s ", iter->first.c_str());
uint32_t watcherId = watcherManager->AddWatcher(iter->first, iter->second); int ret = watcherManager->AddWatcher(iter->first, remoteWatcherId);
WATCHER_CHECK(watcherId != 0, continue, "Failed to add watcher for %s", iter->first.c_str()); WATCHER_CHECK(ret == 0, continue, "Failed to add watcher for %s", iter->first.c_str());
iter->second->SetWatcherId(watcherId); }
}
WatcherManagerKits::ParamWatcher *WatcherManagerKits::GetParamWatcher(const std::string &keyPrefix)
{
std::lock_guard<std::mutex> lock(mutex_);
auto iter = watchers_.find(keyPrefix);
if (iter != watchers_.end()) {
return iter->second.get();
} }
return nullptr;
}
uint32_t WatcherManagerKits::GetRemoteWatcher(void)
{
std::lock_guard<std::mutex> lock(mutex_);
if (remoteWatcher_ != nullptr) {
return remoteWatcherId_;
}
auto watcherManager = GetService();
WATCHER_CHECK(watcherManager != nullptr, return 0, "Failed to get watcher manager");
remoteWatcher_ = new RemoteWatcher(this);
WATCHER_CHECK(remoteWatcher_ != nullptr, return 0, "Failed to create watcher");
remoteWatcherId_ = watcherManager->AddRemoteWatcher(getpid(), remoteWatcher_);
WATCHER_CHECK(remoteWatcherId_ != 0, return 0, "Failed to add watcher");
return remoteWatcherId_;
} }
int32_t WatcherManagerKits::AddWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context) int32_t WatcherManagerKits::AddWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context)
{ {
WATCHER_LOGV("AddWatcher keyPrefix %s", keyPrefix.c_str());
auto watcherManager = GetService(); auto watcherManager = GetService();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get watcher manager"); WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get watcher manager");
bool newWatcher = false; // add or get remote agent
uint32_t remoteWatcherId = GetRemoteWatcher();
WATCHER_CHECK(remoteWatcherId > 0, return -1, "Failed to get remote agent");
ParamWatcherKitPtr watcher = nullptr; ParamWatcherKitPtr watcher = nullptr;
{ {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
// must check
WATCHER_CHECK(remoteWatcherId > 0, return -1, "Failed to get remote agent");
if (watchers_.find(keyPrefix) == watchers_.end()) { if (watchers_.find(keyPrefix) == watchers_.end()) {
watcher = new ParamWatcher(keyPrefix); watcher = std::make_shared<ParamWatcher>(keyPrefix);
WATCHER_CHECK(watcher != nullptr, return -1, "Failed to create watcher for %s", keyPrefix.c_str()); WATCHER_CHECK(watcher != nullptr, return -1, "Failed to create watcher for %s", keyPrefix.c_str());
watchers_[keyPrefix] = watcher;
newWatcher = true;
int ret = watcher->AddParameterListener(callback, context); int ret = watcher->AddParameterListener(callback, context);
WATCHER_CHECK(ret == 0, return -1, "Failed to add callback for %s ", keyPrefix.c_str()); WATCHER_CHECK(ret == 0, return -1, "Failed to add callback for %s ", keyPrefix.c_str());
uint32_t watcherId = watcherManager->AddWatcher(keyPrefix, watcher); ret = watcherManager->AddWatcher(keyPrefix, remoteWatcherId);
WATCHER_CHECK(watcherId != 0, return -1, "Failed to add watcher for %s", keyPrefix.c_str()); WATCHER_CHECK(ret == 0, return -1, "Failed to add watcher for %s", keyPrefix.c_str());
watcher->SetWatcherId(watcherId); watchers_[keyPrefix] = watcher;
} else { } else {
watcher = watchers_[keyPrefix]; watcher = watchers_[keyPrefix];
int ret = watcher->AddParameterListener(callback, context);
WATCHER_CHECK(ret == 0, return -1, "Failed to add callback for %s ", keyPrefix.c_str());
ret = watcherManager->RefreshWatcher(keyPrefix, remoteWatcherId);
WATCHER_CHECK(ret == 0, return -1,
"Failed to refresh watcher for %s %d", keyPrefix.c_str(), remoteWatcherId);
} }
} }
// save callback WATCHER_LOGI("Add watcher keyPrefix %s remoteWatcherId %u success", keyPrefix.c_str(), remoteWatcherId);
if (!newWatcher) { // refresh
int ret = watcher->AddParameterListener(callback, context);
WATCHER_CHECK(ret == 0, return -1, "Failed to add callback for %s ", keyPrefix.c_str());
ret = watcherManager->RefreshWatcher(keyPrefix, watcher->GetWatcherId());
WATCHER_CHECK(ret == 0, return -1, "Failed to refresh watcher for %s", keyPrefix.c_str());
}
WATCHER_LOGI("AddWatcher keyPrefix %s watcherId %u success", keyPrefix.c_str(), watcher->GetWatcherId());
return 0; return 0;
} }
int32_t WatcherManagerKits::DelWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context) int32_t WatcherManagerKits::DelWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context)
{ {
ParamWatcherKitPtr watcher = GetParamWatcher(keyPrefix);
WATCHER_CHECK(watcher != nullptr, return 0, "Can not find watcher for keyPrefix %s", keyPrefix.c_str());
auto watcherManager = GetService(); auto watcherManager = GetService();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get watcher manager"); WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get watcher manager");
WatcherManagerKits::ParamWatcher *watcher = GetParamWatcher(keyPrefix);
WATCHER_CHECK(watcher != nullptr, return -1, "Failed to get watcher");
int count = watcher->DelParameterListener(callback, context); int count = watcher->DelParameterListener(callback, context);
WATCHER_LOGI("DelWatcher keyPrefix_ %s count %d", keyPrefix.c_str(), count); WATCHER_LOGI("DelWatcher keyPrefix_ %s count %d", keyPrefix.c_str(), count);
if (count == 0) { if (count != 0) {
int ret = watcherManager->DelWatcher(keyPrefix, watcher->GetWatcherId()); return 0;
WATCHER_CHECK(ret == 0, return -1, "Failed to delete watcher for %s", keyPrefix.c_str()); }
{ // delete watcher
std::lock_guard<std::mutex> lock(mutex_); int ret = watcherManager->DelWatcher(keyPrefix, remoteWatcherId_);
auto iter = watchers_.find(keyPrefix); WATCHER_CHECK(ret == 0, return -1, "Failed to delete watcher for %s", keyPrefix.c_str());
if (iter != watchers_.end()) { {
watchers_.erase(iter); std::lock_guard<std::mutex> lock(mutex_);
} auto it = watchers_.find(keyPrefix); // delete watcher
if (it != watchers_.end()) {
watchers_.erase(it);
}
if (watchers_.empty()) { // no watcher, so delete remote agent
watcherManager->DelRemoteWatcher(remoteWatcherId_);
remoteWatcherId_ = 0;
remoteWatcher_ = nullptr;
} }
} }
return 0; return 0;
...@@ -179,7 +216,10 @@ WatcherManagerKits::ParameterChangeListener *WatcherManagerKits::ParamWatcher::G ...@@ -179,7 +216,10 @@ WatcherManagerKits::ParameterChangeListener *WatcherManagerKits::ParamWatcher::G
{ {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
uint32_t index = *idx; uint32_t index = *idx;
while (index < static_cast<uint32_t>(parameterChangeListeners.size())) { if (parameterChangeListeners.empty()) {
return nullptr;
}
while (index < listenerId_) {
auto it = parameterChangeListeners.find(index); auto it = parameterChangeListeners.find(index);
if (it != parameterChangeListeners.end()) { if (it != parameterChangeListeners.end()) {
*idx = index; *idx = index;
...@@ -193,32 +233,17 @@ WatcherManagerKits::ParameterChangeListener *WatcherManagerKits::ParamWatcher::G ...@@ -193,32 +233,17 @@ WatcherManagerKits::ParameterChangeListener *WatcherManagerKits::ParamWatcher::G
void WatcherManagerKits::ParamWatcher::RemoveParameterListener(uint32_t idx) void WatcherManagerKits::ParamWatcher::RemoveParameterListener(uint32_t idx)
{ {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
if (idx >= static_cast<uint32_t>(parameterChangeListeners.size())) { auto it = parameterChangeListeners.find(idx);
return; if (it != parameterChangeListeners.end()) {
} parameterChangeListeners.erase(it);
parameterChangeListeners.erase(idx);
}
void WatcherManagerKits::ParamWatcher::OnParameterChange(const std::string &name, const std::string &value)
{
Watcher::OnParameterChange(name, value);
WATCHER_LOGI("OnParameterChange name %s value %s", name.c_str(), value.c_str());
uint32_t index = 0;
ParameterChangeListener *listener = GetParameterListener(&index);
while (listener != nullptr) {
if (!listener->CheckValueChange(value)) {
listener->OnParameterChange(name, value);
}
index++;
listener = GetParameterListener(&index);
} }
} }
int WatcherManagerKits::ParamWatcher::AddParameterListener(ParameterChangePtr callback, void *context) int WatcherManagerKits::ParamWatcher::AddParameterListener(ParameterChangePtr callback, void *context)
{ {
WATCHER_CHECK(callback != nullptr, return -1, "Invalid callback "); WATCHER_CHECK(callback != nullptr, return -1, "Invalid callback ");
WATCHER_LOGV("AddParameterListener listenerId_ %d callback %p context %p", listenerId_, callback, context); WATCHER_LOGV("AddParameterListener %s listenerId_ %d callback %p context %p",
std::lock_guard<std::mutex> lock(mutex_); keyPrefix_.c_str(), listenerId_, callback, context);
for (auto it = parameterChangeListeners.begin(); it != parameterChangeListeners.end(); it++) { for (auto it = parameterChangeListeners.begin(); it != parameterChangeListeners.end(); it++) {
if (it->second == nullptr) { if (it->second == nullptr) {
continue; continue;
...@@ -237,12 +262,15 @@ int WatcherManagerKits::ParamWatcher::AddParameterListener(ParameterChangePtr ca ...@@ -237,12 +262,15 @@ int WatcherManagerKits::ParamWatcher::AddParameterListener(ParameterChangePtr ca
int WatcherManagerKits::ParamWatcher::DelParameterListener(ParameterChangePtr callback, void *context) int WatcherManagerKits::ParamWatcher::DelParameterListener(ParameterChangePtr callback, void *context)
{ {
if (callback == nullptr) {
parameterChangeListeners.clear();
return 0;
}
uint32_t index = 0; uint32_t index = 0;
ParameterChangeListener *listener = GetParameterListener(&index); ParameterChangeListener *listener = GetParameterListener(&index);
while (listener != nullptr) { while (listener != nullptr) {
if ((callback == nullptr && context == nullptr)) { if (listener->IsEqual(callback, context)) {
RemoveParameterListener(index); WATCHER_LOGV("DelParameterListener listenerId_ %d callback %p context %p", index, callback, context);
} else if (listener->IsEqual(callback, context)) {
RemoveParameterListener(index); RemoveParameterListener(index);
break; break;
} }
...@@ -252,6 +280,31 @@ int WatcherManagerKits::ParamWatcher::DelParameterListener(ParameterChangePtr ca ...@@ -252,6 +280,31 @@ int WatcherManagerKits::ParamWatcher::DelParameterListener(ParameterChangePtr ca
return static_cast<int>(parameterChangeListeners.size()); return static_cast<int>(parameterChangeListeners.size());
} }
void WatcherManagerKits::RemoteWatcher::OnParameterChange(
const std::string &prefix, const std::string &name, const std::string &value)
{
// get param watcher
WatcherManagerKits::ParamWatcher *watcher = watcherManager_->GetParamWatcher(prefix);
WATCHER_CHECK(watcher != nullptr, return, "Failed to get watcher '%s'", prefix.c_str());
if (watcher != nullptr) {
watcher->OnParameterChange(name, value);
}
}
void WatcherManagerKits::ParamWatcher::OnParameterChange(const std::string &name, const std::string &value)
{
WATCHER_LOGI("OnParameterChange name %s value %s", name.c_str(), value.c_str());
uint32_t index = 0;
ParameterChangeListener *listener = GetParameterListener(&index);
while (listener != nullptr) {
if (!listener->CheckValueChange(value)) {
listener->OnParameterChange(name, value);
}
index++;
listener = GetParameterListener(&index);
}
}
void WatcherManagerKits::ParameterChangeListener::OnParameterChange(const std::string &name, const std::string &value) void WatcherManagerKits::ParameterChangeListener::OnParameterChange(const std::string &name, const std::string &value)
{ {
if (callback_ != nullptr) { if (callback_ != nullptr) {
...@@ -261,20 +314,30 @@ void WatcherManagerKits::ParameterChangeListener::OnParameterChange(const std::s ...@@ -261,20 +314,30 @@ void WatcherManagerKits::ParameterChangeListener::OnParameterChange(const std::s
} // namespace init_param } // namespace init_param
} // namespace OHOS } // namespace OHOS
static int ParameterWatcherCheck(const char *keyPrefix) static int PreHandleWatchParam(std::string &prefix)
{ {
std::string key(keyPrefix); // clear space in head or tail
if (key.rfind("*") == key.length() - 1) { prefix.erase(0, prefix.find_first_not_of(" "));
return WatchParamCheck(key.substr(0, key.length() - 1).c_str()); prefix.erase(prefix.find_last_not_of(" ") + 1);
WATCHER_CHECK(!prefix.empty(), return PARAM_CODE_INVALID_PARAM, "Invalid prefix");
int ret = 0;
if (prefix.rfind(".*") == prefix.length() - 2) { // 2 last index
ret = WatchParamCheck(prefix.substr(0, prefix.length() - 2).c_str()); // 2 last index
} else if (prefix.rfind("*") == prefix.length() - 1) {
ret = WatchParamCheck(prefix.substr(0, prefix.length() - 1).c_str());
} else if (prefix.rfind(".") == prefix.length() - 1) {
ret = WatchParamCheck(prefix.substr(0, prefix.length() - 1).c_str());
} else { } else {
return WatchParamCheck(keyPrefix); ret = WatchParamCheck(prefix.c_str());
} }
return ret;
} }
int SystemWatchParameter(const char *keyPrefix, ParameterChangePtr callback, void *context) int SystemWatchParameter(const char *keyPrefix, ParameterChangePtr callback, void *context)
{ {
WATCHER_CHECK(keyPrefix != nullptr, return PARAM_CODE_INVALID_PARAM, "Invalid prefix"); WATCHER_CHECK(keyPrefix != nullptr, return PARAM_CODE_INVALID_PARAM, "Invalid prefix");
int ret = ParameterWatcherCheck(keyPrefix); std::string key(keyPrefix);
int ret = PreHandleWatchParam(key);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
...@@ -290,7 +353,8 @@ int SystemWatchParameter(const char *keyPrefix, ParameterChangePtr callback, voi ...@@ -290,7 +353,8 @@ int SystemWatchParameter(const char *keyPrefix, ParameterChangePtr callback, voi
int RemoveParameterWatcher(const char *keyPrefix, ParameterChgPtr callback, void *context) int RemoveParameterWatcher(const char *keyPrefix, ParameterChgPtr callback, void *context)
{ {
WATCHER_CHECK(keyPrefix != nullptr, return PARAM_CODE_INVALID_PARAM, "Invalid prefix"); WATCHER_CHECK(keyPrefix != nullptr, return PARAM_CODE_INVALID_PARAM, "Invalid prefix");
int ret = ParameterWatcherCheck(keyPrefix); std::string key(keyPrefix);
int ret = PreHandleWatchParam(key);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <functional> #include <functional>
#include <map> #include <map>
#include <mutex> #include <mutex>
#include <thread>
#include "iwatcher.h" #include "iwatcher.h"
#include "iwatcher_manager.h" #include "iwatcher_manager.h"
...@@ -33,10 +34,11 @@ class WatcherManagerKits final : public DelayedRefSingleton<WatcherManagerKits> ...@@ -33,10 +34,11 @@ class WatcherManagerKits final : public DelayedRefSingleton<WatcherManagerKits>
public: public:
DISALLOW_COPY_AND_MOVE(WatcherManagerKits); DISALLOW_COPY_AND_MOVE(WatcherManagerKits);
static WatcherManagerKits &GetInstance(); static WatcherManagerKits &GetInstance(void);
int32_t AddWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context); int32_t AddWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context);
int32_t DelWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context); int32_t DelWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context);
void ReAddWatcher(); void ReAddWatcher(void);
#ifndef STARTUP_INIT_TEST #ifndef STARTUP_INIT_TEST
private: private:
#endif #endif
...@@ -44,7 +46,7 @@ private: ...@@ -44,7 +46,7 @@ private:
public: public:
ParameterChangeListener(ParameterChangePtr callback, void *context) ParameterChangeListener(ParameterChangePtr callback, void *context)
: callback_(callback), context_(context) {} : callback_(callback), context_(context) {}
~ParameterChangeListener() = default; ~ParameterChangeListener(void) = default;
bool IsEqual(ParameterChangePtr callback, const void *context) const bool IsEqual(ParameterChangePtr callback, const void *context) const
{ {
...@@ -63,61 +65,63 @@ private: ...@@ -63,61 +65,63 @@ private:
void *context_ { nullptr }; void *context_ { nullptr };
}; };
class ParamWatcher final : public Watcher { class ParamWatcher {
public: public:
explicit ParamWatcher(const std::string &key) : keyPrefix_(key) {} explicit ParamWatcher(const std::string &key) : keyPrefix_(key) {}
~ParamWatcher() override ~ParamWatcher(void)
{ {
parameterChangeListeners.clear(); parameterChangeListeners.clear();
}; };
void OnParameterChange(const std::string &name, const std::string &value);
void OnParameterChange(const std::string &name, const std::string &value) override;
void SetWatcherId(uint32_t watcherId)
{
watcherId_ = watcherId;
}
uint32_t GetWatcherId()
{
return watcherId_;
}
int AddParameterListener(ParameterChangePtr callback, void *context); int AddParameterListener(ParameterChangePtr callback, void *context);
int DelParameterListener(ParameterChangePtr callback, void *context); int DelParameterListener(ParameterChangePtr callback, void *context);
private: private:
ParameterChangeListener *GetParameterListener(uint32_t *idx); ParameterChangeListener *GetParameterListener(uint32_t *idx);
void RemoveParameterListener(uint32_t idx); void RemoveParameterListener(uint32_t idx);
uint32_t watcherId_ { 0 };
std::string keyPrefix_ {}; std::string keyPrefix_ {};
std::mutex mutex_; std::mutex mutex_;
uint32_t listenerId_ { 0 }; uint32_t listenerId_ { 0 };
std::map<uint32_t, std::shared_ptr<ParameterChangeListener>> parameterChangeListeners; std::map<uint32_t, std::shared_ptr<ParameterChangeListener>> parameterChangeListeners;
}; };
using ParamWatcherKitPtr = sptr<WatcherManagerKits::ParamWatcher>;
ParamWatcherKitPtr GetParamWatcher(const std::string &keyPrefix);
class RemoteWatcher final : public Watcher {
public:
RemoteWatcher(WatcherManagerKits *watcherManager) : watcherManager_(watcherManager) {}
~RemoteWatcher(void) override {}
void OnParameterChange(const std::string &prefix, const std::string &name, const std::string &value) final;
private:
WatcherManagerKits *watcherManager_ = { nullptr };
};
using ParamWatcherKitPtr = std::shared_ptr<WatcherManagerKits::ParamWatcher>;
// For death event procession // For death event procession
class DeathRecipient final : public IRemoteObject::DeathRecipient { class DeathRecipient final : public IRemoteObject::DeathRecipient {
public: public:
DeathRecipient() = default; DeathRecipient(void) = default;
~DeathRecipient() final = default; ~DeathRecipient(void) final = default;
DISALLOW_COPY_AND_MOVE(DeathRecipient); DISALLOW_COPY_AND_MOVE(DeathRecipient);
void OnRemoteDied(const wptr<IRemoteObject> &remote) final; void OnRemoteDied(const wptr<IRemoteObject> &remote) final;
}; };
sptr<IRemoteObject::DeathRecipient> GetDeathRecipient() sptr<IRemoteObject::DeathRecipient> GetDeathRecipient(void)
{ {
return deathRecipient_; return deathRecipient_;
} }
private: uint32_t GetRemoteWatcher(void);
ParamWatcher *GetParamWatcher(const std::string &keyPrefix);
void ResetService(const wptr<IRemoteObject> &remote); void ResetService(const wptr<IRemoteObject> &remote);
sptr<IWatcherManager> GetService(); sptr<IWatcherManager> GetService(void);
std::mutex lock_; std::mutex lock_;
sptr<IWatcherManager> watcherManager_ {}; sptr<IWatcherManager> watcherManager_ {};
sptr<IRemoteObject::DeathRecipient> deathRecipient_ {}; sptr<IRemoteObject::DeathRecipient> deathRecipient_ {};
std::mutex mutex_; std::mutex mutex_;
uint32_t remoteWatcherId_ = { 0 };
sptr<Watcher> remoteWatcher_ = { nullptr };
std::map<std::string, ParamWatcherKitPtr> watchers_; std::map<std::string, ParamWatcherKitPtr> watchers_;
std::atomic<bool> stop_ { false };
std::thread *threadForReWatch_ { nullptr };
}; };
} // namespace init_param } // namespace init_param
} // namespace OHOS } // namespace OHOS
......
...@@ -17,55 +17,69 @@ ...@@ -17,55 +17,69 @@
namespace OHOS { namespace OHOS {
namespace init_param { namespace init_param {
uint32_t WatcherManagerProxy::AddWatcher(const std::string &keyPrefix, const sptr<IWatcher> &watcher) uint32_t WatcherManagerProxy::AddRemoteWatcher(uint32_t id, const sptr<IWatcher> &watcher)
{ {
WATCHER_CHECK(watcher != nullptr, return ERR_INVALID_VALUE, "Invalid param"); WATCHER_CHECK(watcher != nullptr, return ERR_INVALID_VALUE, "Invalid param");
WATCHER_LOGV("WatcherManagerProxy::AddWatcher %s", keyPrefix.c_str());
auto remote = Remote(); auto remote = Remote();
WATCHER_CHECK(remote != nullptr, return 0, "Can not get remote"); WATCHER_CHECK(remote != nullptr, return 0, "Can not get remote");
MessageParcel data; MessageParcel data;
data.WriteInterfaceToken(WatcherManagerProxy::GetDescriptor()); data.WriteInterfaceToken(WatcherManagerProxy::GetDescriptor());
data.WriteString(keyPrefix);
bool ret = data.WriteRemoteObject(watcher->AsObject()); bool ret = data.WriteRemoteObject(watcher->AsObject());
WATCHER_CHECK(ret, return 0, "Can not get remote"); WATCHER_CHECK(ret, return 0, "Can not get remote");
data.WriteUint32(id);
MessageParcel reply; MessageParcel reply;
MessageOption option { MessageOption::TF_SYNC }; MessageOption option { MessageOption::TF_SYNC };
int32_t res = remote->SendRequest(ADD_WATCHER, data, reply, option); int32_t res = remote->SendRequest(ADD_REMOTE_AGENT, data, reply, option);
WATCHER_CHECK(res == ERR_OK, return 0, "Transact error"); WATCHER_CHECK(res == ERR_OK, return 0, "Transact error %d", res);
return reply.ReadUint32(); return reply.ReadUint32();
} }
int32_t WatcherManagerProxy::DelWatcher(const std::string &keyPrefix, uint32_t watcherId)
int32_t WatcherManagerProxy::DelRemoteWatcher(uint32_t remoteWatcherId)
{ {
WATCHER_LOGV("WatcherManagerProxy::DelWatcher %s", keyPrefix.c_str());
auto remote = Remote(); auto remote = Remote();
WATCHER_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote"); WATCHER_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote");
MessageParcel data; MessageParcel data;
data.WriteInterfaceToken(WatcherManagerProxy::GetDescriptor()); data.WriteInterfaceToken(WatcherManagerProxy::GetDescriptor());
data.WriteString(keyPrefix); data.WriteUint32(remoteWatcherId);
data.WriteUint32(watcherId);
MessageParcel reply; MessageParcel reply;
MessageOption option { MessageOption::TF_SYNC }; MessageOption option { MessageOption::TF_SYNC };
int32_t res = remote->SendRequest(DEL_WATCHER, data, reply, option); int32_t res = remote->SendRequest(DEL_REMOTE_AGENT, data, reply, option);
WATCHER_CHECK(res == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error"); WATCHER_CHECK(res == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error");
return reply.ReadInt32(); return reply.ReadInt32();
} }
int32_t WatcherManagerProxy::RefreshWatcher(const std::string &keyPrefix, uint32_t watcherId)
int32_t WatcherManagerProxy::SendMsg(int op, const std::string &keyPrefix, uint32_t remoteWatcherId)
{ {
auto remote = Remote(); auto remote = Remote();
WATCHER_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote"); WATCHER_CHECK(remote != nullptr, return 0, "Can not get remote");
MessageParcel data; MessageParcel data;
data.WriteInterfaceToken(WatcherManagerProxy::GetDescriptor()); data.WriteInterfaceToken(WatcherManagerProxy::GetDescriptor());
data.WriteString(keyPrefix); data.WriteString(keyPrefix);
data.WriteUint32(watcherId); data.WriteUint32(remoteWatcherId);
MessageParcel reply; MessageParcel reply;
MessageOption option { MessageOption::TF_SYNC }; MessageOption option { MessageOption::TF_SYNC };
int32_t res = remote->SendRequest(REFRESH_WATCHER, data, reply, option); int32_t res = remote->SendRequest(op, data, reply, option);
WATCHER_CHECK(res == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error"); WATCHER_CHECK(res == ERR_OK, return 0, "Transact error");
return 0; return reply.ReadInt32();
}
int32_t WatcherManagerProxy::AddWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId)
{
return SendMsg(ADD_WATCHER, keyPrefix, remoteWatcherId);
}
int32_t WatcherManagerProxy::DelWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId)
{
return SendMsg(DEL_WATCHER, keyPrefix, remoteWatcherId);
}
int32_t WatcherManagerProxy::RefreshWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId)
{
return SendMsg(REFRESH_WATCHER, keyPrefix, remoteWatcherId);
} }
} }
} // namespace OHOS } // namespace OHOS
...@@ -25,10 +25,13 @@ class WatcherManagerProxy : public IRemoteProxy<IWatcherManager> { ...@@ -25,10 +25,13 @@ class WatcherManagerProxy : public IRemoteProxy<IWatcherManager> {
public: public:
explicit WatcherManagerProxy(const sptr<IRemoteObject> &impl) : IRemoteProxy<IWatcherManager>(impl) {} explicit WatcherManagerProxy(const sptr<IRemoteObject> &impl) : IRemoteProxy<IWatcherManager>(impl) {}
uint32_t AddWatcher(const std::string &keyPrefix, const sptr<IWatcher> &watcher) override; uint32_t AddRemoteWatcher(uint32_t id, const sptr<IWatcher> &watcher) override;
int32_t DelWatcher(const std::string &keyPrefix, uint32_t watcherId) override; int32_t DelRemoteWatcher(uint32_t remoteWatcherId) override;
int32_t RefreshWatcher(const std::string &keyPrefix, uint32_t watcherId) override; int32_t AddWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) override;
int32_t DelWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) override;
int32_t RefreshWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) override;
private: private:
int32_t SendMsg(int op, const std::string &keyPrefix, uint32_t remoteWatcherId);
static inline BrokerDelegator<WatcherManagerProxy> delegator_; static inline BrokerDelegator<WatcherManagerProxy> delegator_;
}; };
} // namespace init_param } // namespace init_param
......
...@@ -22,15 +22,16 @@ namespace OHOS { ...@@ -22,15 +22,16 @@ namespace OHOS {
namespace init_param { namespace init_param {
int32_t WatcherStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) int32_t WatcherStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
{ {
std::u16string myDescripter = IWatcher::GetDescriptor(); std::u16string myDescriptor = IWatcher::GetDescriptor();
std::u16string remoteDescripter = data.ReadInterfaceToken(); std::u16string remoteDescriptor = data.ReadInterfaceToken();
WATCHER_CHECK(myDescripter == remoteDescripter, return -1, "Invalid remoteDescripter"); WATCHER_CHECK(myDescriptor == remoteDescriptor, return -1, "Invalid remoteDescriptor");
switch (code) { switch (code) {
case PARAM_CHANGE: { case PARAM_CHANGE: {
std::string key = data.ReadString();
std::string name = data.ReadString(); std::string name = data.ReadString();
std::string value = data.ReadString(); std::string value = data.ReadString();
OnParameterChange(name, value); OnParameterChange(key, name, value);
break; break;
} }
default: { default: {
......
...@@ -31,7 +31,7 @@ public: ...@@ -31,7 +31,7 @@ public:
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Startup.IWatcher"); DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Startup.IWatcher");
public: public:
virtual void OnParameterChange(const std::string &name, const std::string &value) = 0; virtual void OnParameterChange(const std::string &prefix, const std::string &name, const std::string &value) = 0;
}; };
} // namespace init_param } // namespace init_param
} // namespace OHOS } // namespace OHOS
......
...@@ -28,14 +28,18 @@ public: ...@@ -28,14 +28,18 @@ public:
enum { enum {
ADD_WATCHER, ADD_WATCHER,
DEL_WATCHER, DEL_WATCHER,
ADD_REMOTE_AGENT,
DEL_REMOTE_AGENT,
REFRESH_WATCHER REFRESH_WATCHER
}; };
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Startup.IWatcherManager"); DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Startup.IWatcherManager");
public: public:
virtual uint32_t AddWatcher(const std::string &keyPrefix, const sptr<IWatcher> &watcher) = 0; virtual uint32_t AddRemoteWatcher(uint32_t id, const sptr<IWatcher> &watcher) = 0;
virtual int32_t DelWatcher(const std::string &keyPrefix, uint32_t watcherId) = 0; virtual int32_t DelRemoteWatcher(uint32_t remoteWatcherId) = 0;
virtual int32_t RefreshWatcher(const std::string &keyPrefix, uint32_t watcherId) = 0; virtual int32_t AddWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) = 0;
virtual int32_t DelWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) = 0;
virtual int32_t RefreshWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) = 0;
}; };
} // namespace update_engine } // namespace update_engine
} // namespace OHOS } // namespace OHOS
......
...@@ -27,13 +27,27 @@ ...@@ -27,13 +27,27 @@
#include "message_parcel.h" #include "message_parcel.h"
#include "param_utils.h" #include "param_utils.h"
#include "parcel.h" #include "parcel.h"
#include "param_message.h"
#include "system_ability.h" #include "system_ability.h"
#include "watcher_manager_stub.h" #include "watcher_manager_stub.h"
namespace OHOS { namespace OHOS {
namespace init_param { namespace init_param {
class WatcherNode;
class ParamWatcherList;
class WatcherGroup;
class RemoteWatcher;
using WatcherGroupPtr = WatcherGroup *;
using RemoteWatcherPtr = RemoteWatcher *;
using WatcherNodePtr = WatcherNode *;
using ListNodePtr = ListNode *;
using ListHeadPtr = ListHead *;
using ParamWatcherListPtr = ParamWatcherList *;
using ParamWatcherProcessor = std::function<void(ParamWatcherListPtr list, WatcherNodePtr node, uint32_t index)>;
class WatcherManager : public SystemAbility, public WatcherManagerStub { class WatcherManager : public SystemAbility, public WatcherManagerStub {
public: public:
friend class WatcherGroup;
DECLARE_SYSTEM_ABILITY(WatcherManager); DECLARE_SYSTEM_ABILITY(WatcherManager);
DISALLOW_COPY_AND_MOVE(WatcherManager); DISALLOW_COPY_AND_MOVE(WatcherManager);
explicit WatcherManager(int32_t systemAbilityId, bool runOnCreate = true) explicit WatcherManager(int32_t systemAbilityId, bool runOnCreate = true)
...@@ -42,104 +56,28 @@ public: ...@@ -42,104 +56,28 @@ public:
} }
~WatcherManager() override; ~WatcherManager() override;
class ParamWatcher;
class WatcherGroup;
using ParamWatcherPtr = std::shared_ptr<WatcherManager::ParamWatcher>;
using WatcherGroupPtr = std::shared_ptr<WatcherManager::WatcherGroup>;
// For death event procession // For death event procession
class DeathRecipient final : public IRemoteObject::DeathRecipient { class DeathRecipient final : public IRemoteObject::DeathRecipient {
public: public:
explicit DeathRecipient(WatcherManager *manager) : manager_(manager) {} explicit DeathRecipient(WatcherManager *manager) : manager_(manager) {}
~DeathRecipient() final = default; ~DeathRecipient() final = default;
DISALLOW_COPY_AND_MOVE(DeathRecipient); DISALLOW_COPY_AND_MOVE(DeathRecipient);
void OnRemoteDied(const wptr<IRemoteObject> &remote) final; void OnRemoteDied(const wptr<IRemoteObject> &remote) final
{
manager_->OnRemoteDied(remote);
}
private: private:
WatcherManager *manager_; WatcherManager *manager_;
}; };
sptr<IRemoteObject::DeathRecipient> GetDeathRecipient() sptr<IRemoteObject::DeathRecipient> GetDeathRecipient(void)
{ {
return deathRecipient_; return deathRecipient_;
} }
uint32_t AddRemoteWatcher(uint32_t id, const sptr<IWatcher> &watcher) override;
class ParamWatcher { int32_t DelRemoteWatcher(uint32_t remoteWatcherId) override;
public: int32_t AddWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) override;
ParamWatcher(uint32_t watcherId, const sptr<IWatcher> &watcher, const WatcherGroupPtr &group) int32_t DelWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) override;
: watcherId_(watcherId), watcher_(watcher), group_(group) int32_t RefreshWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) override;
{
OH_ListInit(&groupNode_);
}
~ParamWatcher() = default;
uint32_t GetWatcherId() const
{
return watcherId_;
}
WatcherGroupPtr GetWatcherGroup()
{
return group_;
}
ListNode *GetGroupNode()
{
return &groupNode_;
}
sptr<IWatcher> GetRemoteWatcher() const
{
return watcher_;
}
void ProcessParameterChange(const std::string &name, const std::string &value)
{
#ifndef STARTUP_INIT_TEST
watcher_->OnParameterChange(name, value);
#endif
}
private:
ListNode groupNode_;
uint32_t watcherId_ = { 0 };
sptr<IWatcher> watcher_;
WatcherGroupPtr group_ { nullptr };
};
class WatcherGroup {
public:
WatcherGroup(uint32_t groupId, const std::string &key) : groupId_(groupId), keyPrefix_(key)
{
OH_ListInit(&watchers_);
}
~WatcherGroup() = default;
void AddWatcher(const ParamWatcherPtr &watcher);
void ProcessParameterChange(const std::string &name, const std::string &value);
const std::string GetKeyPrefix() const
{
return keyPrefix_;
}
bool Empty() const
{
return ListEmpty(watchers_);
}
uint32_t GetGroupId() const
{
return groupId_;
}
ListNode *GetWatchers()
{
return &watchers_;
}
ParamWatcher *GetNextWatcher(ParamWatcher *watcher);
private:
uint32_t groupId_;
std::string keyPrefix_ { };
ListNode watchers_;
};
uint32_t AddWatcher(const std::string &keyPrefix, const sptr<IWatcher> &watcher) override;
int32_t DelWatcher(const std::string &keyPrefix, uint32_t watcherId) override;
int32_t RefreshWatcher(const std::string &keyPrefix, uint32_t watcherId) override;
int32_t DelWatcher(WatcherGroupPtr group, ParamWatcherPtr watcher);
ParamWatcherPtr GetWatcher(uint32_t watcherId);
ParamWatcherPtr GetWatcher(const wptr<IRemoteObject> &remote);
#ifndef STARTUP_INIT_TEST #ifndef STARTUP_INIT_TEST
protected: protected:
#endif #endif
...@@ -149,33 +87,169 @@ protected: ...@@ -149,33 +87,169 @@ protected:
#ifndef STARTUP_INIT_TEST #ifndef STARTUP_INIT_TEST
private: private:
#endif #endif
void ProcessWatcherMessage(const std::vector<char> &buffer, uint32_t dataSize);
WatcherGroupPtr GetWatcherGroup(uint32_t groupId);
WatcherGroupPtr GetWatcherGroup(const std::string &keyPrefix);
void DelWatcherGroup(WatcherGroupPtr group);
void AddParamWatcher(const std::string &keyPrefix, WatcherGroupPtr group, ParamWatcherPtr watcher);
void DelParamWatcher(ParamWatcherPtr watcher);
void RunLoop(); void RunLoop();
void StartLoop(); void StartLoop();
void StopLoop(); void StopLoop();
void SendLocalChange(const std::string &keyPrefix, ParamWatcherPtr watcher); void SendLocalChange(const std::string &keyPrefix, RemoteWatcherPtr &remoteWatcher);
int SendMessage(WatcherGroupPtr group, int type); int SendMessage(WatcherGroupPtr group, int type);
int GetServerFd(bool retry); int GetServerFd(bool retry);
int GetWatcherId(uint32_t &watcherId); int GetRemoteWatcherId(uint32_t &remoteWatcherId);
int GetGroupId(uint32_t &groupId); int GetGroupId(uint32_t &groupId);
void DumpWatcherGroup(int fd, const WatcherGroupPtr &watchGroup); // for remote watcher
int AddRemoteWatcher(RemoteWatcherPtr remoteWatcher);
RemoteWatcherPtr GetRemoteWatcher(uint32_t remoteWatcherId);
RemoteWatcherPtr GetRemoteWatcher(const wptr<IRemoteObject> &remote);
void DelRemoteWatcher(RemoteWatcherPtr remoteWatcher);
// for group
WatcherGroupPtr AddWatcherGroup(const std::string &keyPrefix);
WatcherGroupPtr GetWatcherGroup(const std::string &keyPrefix);
WatcherGroupPtr GetWatcherGroup(uint32_t groupId);
void DelWatcherGroup(WatcherGroupPtr group);
// for param watcher
int AddParamWatcher(WatcherGroupPtr group, RemoteWatcherPtr remoteWatcher);
int DelParamWatcher(WatcherGroupPtr group, RemoteWatcherPtr remoteWatcher);
// for process message form init
void ProcessWatcherMessage(const ParamMessage *msg);
// for client died
void OnRemoteDied(const wptr<IRemoteObject> &remote);
void OnRemoteDied(RemoteWatcherPtr remoteWatcher);
// clear
void Clear(void);
// dump
void DumpAllGroup(int fd, ParamWatcherProcessor dumpHandle);
private: private:
std::atomic<uint32_t> watcherId_ { 0 }; std::atomic<uint32_t> remoteWatcherId_ { 0 };
std::atomic<uint32_t> groupId_ { 0 }; std::atomic<uint32_t> groupId_ { 0 };
std::mutex mutex_; std::mutex mutex_;
std::mutex watcherMutex_; std::mutex watcherMutex_;
int serverFd_ { -1 }; int serverFd_ { -1 };
std::thread *pRecvThread_ { nullptr }; std::thread *pRecvThread_ { nullptr };
std::atomic<bool> stop_ { false }; std::atomic<bool> stop_ { false };
std::map<std::string, uint32_t> groupMap_ {}; std::map<std::string, WatcherGroupPtr> groupMap_ {};
std::map<uint32_t, WatcherGroupPtr> watcherGroups_ {};
std::map<uint32_t, ParamWatcherPtr> watchers_ {};
sptr<IRemoteObject::DeathRecipient> deathRecipient_ {}; sptr<IRemoteObject::DeathRecipient> deathRecipient_ {};
ParamWatcherListPtr watcherGroups_ {};
ParamWatcherListPtr remoteWatchers_ {};
};
class WatcherNode {
public:
WatcherNode(uint32_t nodeId) : nodeId_(nodeId)
{
OH_ListInit(&node_);
}
virtual ~WatcherNode(void) = default;
uint32_t GetNodeId(void) const { return nodeId_; }
void AddToList(ListHeadPtr list);
void RemoveFromList(ListHeadPtr list);
WatcherNodePtr GetNext(ListHeadPtr list);
static WatcherNodePtr GetFromList(ListHeadPtr list, uint32_t nodeId);
static WatcherNodePtr GetNextFromList(ListHeadPtr list, uint32_t nodeId);
static WatcherNodePtr ConvertNodeToBase(ListNodePtr node) {
WatcherNodePtr tmp = NULL;
return reinterpret_cast<WatcherNodePtr >((char *)node - (char *)tmp->GetListNode());
}
ListNodePtr GetListNode() { return &node_; }
private:
static int CompareNode(ListNodePtr node, ListNodePtr newNode);
static int CompareData(ListNodePtr node, void *data);
static int Greater(ListNodePtr node, void *data);
ListNode node_;
uint32_t nodeId_;
};
template<typename T>
inline T *ConvertTo(WatcherNodePtr node)
{
#ifdef PARAM_WATCHER_RTTI_ENABLE
// when -frtti is enabled, we use dynamic cast directly
// to achieve the correct base class side-to-side conversion.
T *obj = dynamic_cast<T *>(node);
#else
// adjust pointer position when multiple inheritance.
void *tmp = reinterpret_cast<void *>(node);
// when -frtti is not enable, we use static cast.
// static cast is not safe enough, but we have checked before we get here.
T *obj = static_cast<T *>(tmp);
#endif
return obj;
}
class ParamWatcher : public WatcherNode {
public:
ParamWatcher(uint32_t watcherId) : WatcherNode(watcherId) {}
~ParamWatcher(void) override {}
};
class ParamWatcherList {
public:
ParamWatcherList(void)
{
OH_ListInit(&nodeList_);
}
~ParamWatcherList(void) = default;
bool Empty(void) const
{
return nodeList_.next == &nodeList_;
}
uint32_t GetNodeCount(void) const { return nodeCount_; }
int AddNode(WatcherNodePtr node);
int RemoveNode(WatcherNodePtr node);
WatcherNodePtr GetNode(uint32_t nodeId);
WatcherNodePtr GetNextNodeSafe(WatcherNodePtr node);
WatcherNodePtr GetNextNode(WatcherNodePtr node);
void TraversalNode(ParamWatcherProcessor handle);
void TraversalNodeSafe(ParamWatcherProcessor processor);
public:
ListHead nodeList_ {};
uint32_t nodeCount_ = 0;
};
class RemoteWatcher : public WatcherNode, public ParamWatcherList {
public:
RemoteWatcher(uint32_t watcherId, const sptr<IWatcher> &watcher)
: WatcherNode(watcherId), ParamWatcherList(), watcher_(watcher) {}
~RemoteWatcher(void) override
{
watcher_ = nullptr;
TraversalNodeSafe([](ParamWatcherListPtr list, WatcherNodePtr node, uint32_t index) {
list->RemoveNode(node);
ParamWatcher *watcher = ConvertTo<ParamWatcher>(node);
delete watcher;
});
}
uint32_t GetRemoteWatcherId(void) const { return GetNodeId(); }
uint32_t GetAgentId(void) const { return id_; }
void SetAgentId(uint32_t id) { id_ = id; }
void ProcessParameterChange(const std::string &prefix, const std::string &name, const std::string &value)
{
watcher_->OnParameterChange(prefix, name, value);
}
sptr<IWatcher> GetWatcher(void) { return watcher_; }
private:
uint32_t id_ = { 0 };
sptr<IWatcher> watcher_ {};
};
class WatcherGroup : public WatcherNode, public ParamWatcherList {
public:
WatcherGroup(uint32_t groupId, const std::string &key)
: WatcherNode(groupId), ParamWatcherList(), keyPrefix_(key) {}
~WatcherGroup() override
{
TraversalNodeSafe([](ParamWatcherListPtr list, WatcherNodePtr node, uint32_t index) {
list->RemoveNode(node);
ParamWatcher *watcher = ConvertTo<ParamWatcher>(node);
delete watcher;
});
}
void ProcessParameterChange(WatcherManager *mananger, const std::string &name, const std::string &value);
const std::string GetKeyPrefix() const { return keyPrefix_; }
uint32_t GetGroupId() const { return GetNodeId(); }
private:
std::string keyPrefix_ { };
}; };
} // namespace init_param } // namespace init_param
} // namespace OHOS } // namespace OHOS
......
...@@ -21,32 +21,42 @@ namespace init_param { ...@@ -21,32 +21,42 @@ namespace init_param {
int32_t WatcherManagerStub::OnRemoteRequest(uint32_t code, int32_t WatcherManagerStub::OnRemoteRequest(uint32_t code,
MessageParcel &data, MessageParcel &reply, MessageOption &option) MessageParcel &data, MessageParcel &reply, MessageOption &option)
{ {
std::u16string myDescripter = IWatcherManager::GetDescriptor(); std::u16string myDescriptor = IWatcherManager::GetDescriptor();
std::u16string remoteDescripter = data.ReadInterfaceToken(); std::u16string remoteDescriptor = data.ReadInterfaceToken();
WATCHER_CHECK(myDescripter == remoteDescripter, return -1, "Invalid remoteDescripter"); WATCHER_CHECK(myDescriptor == remoteDescriptor, return -1, "Invalid remoteDescriptor");
WATCHER_LOGV("OnRemoteRequest code %u", code);
switch (code) { switch (code) {
case ADD_WATCHER: { case ADD_WATCHER: {
std::string key = data.ReadString(); std::string key = data.ReadString();
int ret = AddWatcher(key, data.ReadUint32());
reply.WriteInt32(ret);
break;
}
case DEL_WATCHER: {
std::string key = data.ReadString();
int ret = DelWatcher(key, data.ReadUint32());
reply.WriteInt32(ret);
break;
}
case ADD_REMOTE_AGENT: {
auto remote = data.ReadRemoteObject(); auto remote = data.ReadRemoteObject();
// 0 is invalid watcherId // 0 is invalid watcherId
WATCHER_CHECK(remote != nullptr, reply.WriteUint32(0); WATCHER_CHECK(remote != nullptr, reply.WriteUint32(0);
return 0, "Failed to read remote watcher"); return 0, "Failed to read remote watcher");
uint32_t watcherId = AddWatcher(key, iface_cast<IWatcher>(remote)); uint32_t id = data.ReadUint32();
reply.WriteUint32(watcherId); uint32_t remoteWatcherId = AddRemoteWatcher(id, iface_cast<IWatcher>(remote));
reply.WriteUint32(remoteWatcherId);
break; break;
} }
case DEL_WATCHER: { case DEL_REMOTE_AGENT: {
std::string key = data.ReadString(); int ret = DelRemoteWatcher(data.ReadUint32());
uint32_t watcherId = data.ReadUint32();
int ret = DelWatcher(key, watcherId);
reply.WriteInt32(ret); reply.WriteInt32(ret);
break; break;
} }
case REFRESH_WATCHER: { case REFRESH_WATCHER: {
std::string key = data.ReadString(); std::string key = data.ReadString();
uint32_t watcherId = data.ReadUint32(); int ret = RefreshWatcher(key, data.ReadUint32());
int ret = RefreshWatcher(key, watcherId);
reply.WriteInt32(ret); reply.WriteInt32(ret);
break; break;
} }
......
...@@ -23,9 +23,9 @@ ...@@ -23,9 +23,9 @@
namespace OHOS { namespace OHOS {
namespace init_param { namespace init_param {
void WatcherProxy::OnParameterChange(const std::string &name, const std::string &value) void WatcherProxy::OnParameterChange(const std::string &prefix, const std::string &name, const std::string &value)
{ {
WATCHER_LOGV("WatcherProxy::OnParameterChange %s %s", name.c_str(), value.c_str()); WATCHER_LOGV("WatcherProxy::OnParameterChange %s %s %s", prefix.c_str(), name.c_str(), value.c_str());
MessageParcel data; MessageParcel data;
MessageParcel reply; MessageParcel reply;
MessageOption option { MessageOption::TF_ASYNC }; MessageOption option { MessageOption::TF_ASYNC };
...@@ -33,10 +33,11 @@ void WatcherProxy::OnParameterChange(const std::string &name, const std::string ...@@ -33,10 +33,11 @@ void WatcherProxy::OnParameterChange(const std::string &name, const std::string
WATCHER_CHECK(remote != nullptr, return, "Can not get remote"); WATCHER_CHECK(remote != nullptr, return, "Can not get remote");
data.WriteInterfaceToken(WatcherProxy::GetDescriptor()); data.WriteInterfaceToken(WatcherProxy::GetDescriptor());
data.WriteString(prefix);
data.WriteString(name); data.WriteString(name);
data.WriteString(value); data.WriteString(value);
int ret = remote->SendRequest(PARAM_CHANGE, data, reply, option); int ret = remote->SendRequest(PARAM_CHANGE, data, reply, option);
WATCHER_CHECK(ret == ERR_OK, return, "Can not SendRequest for name %s", name.c_str()); WATCHER_CHECK(ret == ERR_OK, return, "Can not SendRequest for name %s err:%d", name.c_str(), ret);
return; return;
} }
} }
......
...@@ -27,7 +27,7 @@ public: ...@@ -27,7 +27,7 @@ public:
virtual ~WatcherProxy() = default; virtual ~WatcherProxy() = default;
void OnParameterChange(const std::string &name, const std::string &value) override; void OnParameterChange(const std::string &prefix, const std::string &name, const std::string &value) override;
private: private:
static inline BrokerDelegator<WatcherProxy> delegator_; static inline BrokerDelegator<WatcherProxy> delegator_;
......
...@@ -19,12 +19,18 @@ ...@@ -19,12 +19,18 @@
#include "begetctl.h" #include "begetctl.h"
#include "init_param.h" #include "init_param.h"
#include "init_utils.h"
#include "loop_event.h" #include "loop_event.h"
#include "parameter.h" #include "parameter.h"
#include "plugin_test.h" #include "plugin_test.h"
#include "service_watcher.h" #include "service_watcher.h"
#include "parameter.h"
#define MAX_THREAD_NUMBER 100
#define MAX_NUMBER 10
#define READ_DURATION 100000 #define READ_DURATION 100000
#define CMD_INDEX 2
static char *GetLocalBuffer(uint32_t *buffSize) static char *GetLocalBuffer(uint32_t *buffSize)
{ {
static char buffer[PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX] = {0}; static char buffer[PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX] = {0};
...@@ -77,24 +83,138 @@ static int32_t BShellParamCmdRead(BShellHandle shell, int32_t argc, char *argv[] ...@@ -77,24 +83,138 @@ static int32_t BShellParamCmdRead(BShellHandle shell, int32_t argc, char *argv[]
return 0; return 0;
} }
static void HandleParamChange(const char *key, const char *value, void *context) typedef struct {
char name[PARAM_NAME_LEN_MAX];
pthread_t thread;
} TestWatchContext;
static void HandleParamChange2(const char *key, const char *value, void *context)
{ {
PLUGIN_CHECK(key != NULL && value != NULL, return, "Invalid parameter"); PLUGIN_CHECK(key != NULL && value != NULL, return, "Invalid parameter");
long long commit = GetSystemCommitId(); long long commit = GetSystemCommitId();
printf("Receive parameter commit %lld change %s %s \n", commit, key, value); size_t index = (size_t)context;
printf("[%zu] Receive parameter %p commit %lld change %s %s \n", index, context, commit, key, value);
static int addWatcher = 0;
int ret = 0;
if ((index == 4) && !addWatcher) { // 4 when context == 4 add
index = 5; // 5 add context
ret = SystemWatchParameter(key, HandleParamChange2, (void *)index);
if (ret != 0) {
printf("Add watcher %s fail %d \n", key, index);
}
addWatcher = 1;
return;
}
if (index == 2) { // 2 when context == 2 delete 3
index = 3; // 3 delete context
RemoveParameterWatcher(key, HandleParamChange2, (void *)index);
if (ret != 0) {
printf("Remove watcher fail %d \n", index);
}
return;
}
if (index == 1) { // 1 when context == 1 delete 1
RemoveParameterWatcher(key, HandleParamChange2, (void *)index);
if (ret != 0) {
printf("Remove watcher fail %d \n", index);
}
return;
}
if ((index == 5) && (addWatcher == 1)) { // 5 when context == 5 delete 5
RemoveParameterWatcher(key, HandleParamChange2, (void *)index);
if (ret != 0) {
printf("Remove watcher fail %d \n", index);
}
addWatcher = 0;
}
}
static void HandleParamChange1(const char *key, const char *value, void *context)
{
PLUGIN_CHECK(key != NULL && value != NULL, return, "Invalid parameter");
long long commit = GetSystemCommitId();
size_t index = (size_t)context;
printf("[%zu] Receive parameter commit %lld change %s %s \n", index, commit, key, value);
}
static void *CmdThreadWatcher(void *args)
{
TestWatchContext *context = (TestWatchContext *)args;
for (size_t i = 1; i <= MAX_NUMBER; i++) {
int ret = SystemWatchParameter(context->name, HandleParamChange2, (void *)i);
if (ret != 0) {
printf("Add watcher %s fail %d \n", context->name, i);
}
ret = SetParameter(context->name, context->name);
if (ret != 0) {
printf("Set parameter %s fail %d \n", context->name, i);
}
}
sleep(1);
for (size_t i = 1; i <= MAX_NUMBER; i++) {
int ret = RemoveParameterWatcher(context->name, HandleParamChange2, (void *)i);
if (ret != 0) {
printf("Remove watcher %s fail %d \n", context->name, i);
}
}
free(context);
return NULL;
}
static void StartWatcherInThread(const char *prefix)
{
TestWatchContext *context[MAX_THREAD_NUMBER] = { NULL };
for (size_t i = 0; i < MAX_THREAD_NUMBER; i++) {
context[i] = calloc(1, sizeof(TestWatchContext));
PLUGIN_CHECK(context[i] != NULL, return, "Failed to alloc context");
int len = sprintf_s(context[i]->name, sizeof(context[i]->name), "%s.%zu", prefix, i);
if (len > 0) {
printf("Add watcher %s \n", context[i]->name);
pthread_create(&context[i]->thread, NULL, CmdThreadWatcher, context[i]);
}
}
}
static void StartWatcher(const char *prefix)
{
static size_t index = 0;
int ret = SystemWatchParameter(prefix, HandleParamChange1, (void *)index);
if (ret != 0) {
printf("Add watcher %s fail \n", prefix);
return;
}
index++;
} }
static int32_t BShellParamCmdWatch(BShellHandle shell, int32_t argc, char *argv[]) static int32_t BShellParamCmdWatch(BShellHandle shell, int32_t argc, char *argv[])
{ {
PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter"); PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
PLUGIN_LOGV("BShellParamCmdWatch %s", argv[1]); PLUGIN_LOGV("BShellParamCmdWatch %s", argv[1]);
static size_t index = 0; StartWatcher(argv[1]);
int ret = SystemWatchParameter(argv[1], HandleParamChange, (void *)index);
if (ret != 0) { if (argc <= CMD_INDEX) {
PLUGIN_LOGE("Failed to watch %s", argv[1]);
return 0; return 0;
} }
index++; if (strcmp(argv[CMD_INDEX], "thread") == 0) { // 2 cmd index
StartWatcherInThread(argv[1]);
return 0;
}
int maxCount = StringToInt(argv[CMD_INDEX], -1); // 2 cmd index
if (maxCount <= 0 || maxCount > 65535) { // 65535 max count
PLUGIN_LOGE("Invalid input %s", argv[2]);
return 0;
}
uint32_t buffSize = 0;
char *buffer = GetLocalBuffer(&buffSize);
size_t count = 0;
while (count < (size_t)maxCount) { // 100 max count
int len = sprintf_s(buffer, buffSize, "%s.%d", argv[1], count);
PLUGIN_CHECK(len > 0, return -1, "Invalid buffer");
buffer[len] = '\0';
StartWatcher(buffer);
count++;
}
return 0; return 0;
} }
...@@ -150,11 +270,71 @@ static int32_t BShellParamCmdUdidGet(BShellHandle shell, int32_t argc, char *arg ...@@ -150,11 +270,71 @@ static int32_t BShellParamCmdUdidGet(BShellHandle shell, int32_t argc, char *arg
return 0; return 0;
} }
static int CalcValue(const char *value)
{
char *begin = (char *)value;
while (*begin != '\0') {
if (*begin == ' ') {
begin++;
} else {
break;
}
}
char *end = begin + strlen(begin);
while (end > begin) {
if (*end > '9' || *end < '0') {
*end = '\0';
}
end--;
}
return StringToInt(begin, -1);
}
static int32_t BShellParamCmdMemGet(BShellHandle shell, int32_t argc, char *argv[])
{
PLUGIN_CHECK(argc > 1, return -1, "Invalid parameter");
uint32_t buffSize = 0; // 1024 max buffer for decode
char *buff = GetLocalBuffer(&buffSize);
int ret = sprintf_s(buff, buffSize - 1, "/proc/%s/smaps", argv[1]);
PLUGIN_CHECK(ret > 0, return -1, "Failed to format path %s", argv[1]);
buff[ret] = '\0';
int all = 0;
if (argc > 2 && strcmp(argv[2], "all") == 0) { // 2 2 max arg
all = 1;
}
FILE *fp = fopen(buff, "r");
int value = 0;
while (fp != NULL && buff != NULL && fgets(buff, buffSize, fp) != NULL) {
buff[buffSize - 1] = '\0';
if (strncmp(buff, "Pss:", strlen("Pss:")) == 0) {
int v = CalcValue(buff + strlen("Pss:"));
if (all) {
printf("Pss: %d kb\n", v);
}
value += v;
} else if (strncmp(buff, "SwapPss:", strlen("SwapPss:")) == 0) {
int v = CalcValue(buff + strlen("SwapPss:"));
if (all) {
printf("SwapPss: %d kb\n", v);
}
value += v;
}
}
if (fp != NULL) {
fclose(fp);
printf("Total mem %d kb\n", value);
} else {
printf("Failed to get memory for %s %s \n", argv[1], buff);
}
return 0;
}
int32_t BShellCmdRegister(BShellHandle shell, int execMode) int32_t BShellCmdRegister(BShellHandle shell, int execMode)
{ {
if (execMode == 0) { if (execMode == 0) {
const CmdInfo infos[] = { const CmdInfo infos[] = {
{"init", BShellParamCmdGroupTest, "init group test", "init group test [stage]", "init group test"}, {"init", BShellParamCmdGroupTest, "init group test", "init group test [stage]", "init group test"},
{"display", BShellParamCmdMemGet, "display memory pid", "display memory [pid]", "display memory"},
}; };
for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) { for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) {
BShellEnvRegisterCmd(shell, &infos[i]); BShellEnvRegisterCmd(shell, &infos[i]);
...@@ -168,6 +348,7 @@ int32_t BShellCmdRegister(BShellHandle shell, int execMode) ...@@ -168,6 +348,7 @@ int32_t BShellCmdRegister(BShellHandle shell, int execMode)
{"uninstall", BShellParamCmdInstall, "uninstall plugin", "uninstall [name]", ""}, {"uninstall", BShellParamCmdInstall, "uninstall plugin", "uninstall [name]", ""},
{"group", BShellParamCmdGroupTest, "group test", "group test [stage]", "group test"}, {"group", BShellParamCmdGroupTest, "group test", "group test [stage]", "group test"},
{"display", BShellParamCmdUdidGet, "display udid", "display udid", "display udid"}, {"display", BShellParamCmdUdidGet, "display udid", "display udid", "display udid"},
{"display", BShellParamCmdMemGet, "display memory pid", "display memory [pid]", "display memory"},
}; };
for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) { for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) {
BShellEnvRegisterCmd(GetShellHandle(), &infos[i]); BShellEnvRegisterCmd(GetShellHandle(), &infos[i]);
......
...@@ -308,20 +308,24 @@ HWTEST_F(ServiceUnitTest, TestServiceBootEventHook, TestSize.Level1) ...@@ -308,20 +308,24 @@ HWTEST_F(ServiceUnitTest, TestServiceBootEventHook, TestSize.Level1)
serviceInfoContext.reserved = "bootevent"; serviceInfoContext.reserved = "bootevent";
HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr); HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr);
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_DUMP, (void *)(&serviceInfoContext), NULL); (void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_DUMP, (void *)(&serviceInfoContext), NULL);
cJSON *fileRoot = cJSON_Parse(serviceStr); cJSON *fileRoot = cJSON_Parse(serviceStr);
ASSERT_NE(nullptr, fileRoot); ASSERT_NE(nullptr, fileRoot);
PluginExecCmd("clear", 0, nullptr);
ParseAllServices(fileRoot); ParseAllServices(fileRoot);
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_FORK_BEFORE, (void *)(&serviceInfoContext), NULL); (void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_FORK_BEFORE, (void *)(&serviceInfoContext), NULL);
SystemWriteParam("bootevent.bootevent1", "true"); serviceInfoContext.reserved = NULL;
SystemWriteParam("bootevent.bootevent1", "true"); (void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_FORK_BEFORE, (void *)(&serviceInfoContext), NULL);
SystemWriteParam("bootevent.bootevent2", "true");
const char *initBootevent[] = {"init", "test"}; const char *initBootevent[] = {"init", "test"};
PluginExecCmd("bootevent", ARRAY_LENGTH(initBootevent), initBootevent); PluginExecCmd("bootevent", ARRAY_LENGTH(initBootevent), initBootevent);
PluginExecCmd("save.bootevent", 0, nullptr); const char *initBooteventDup[] = {"init", "test"};
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_DUMP, (void *)(&serviceInfoContext), NULL); PluginExecCmd("bootevent", ARRAY_LENGTH(initBooteventDup), initBooteventDup);
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_CLEAR, (void *)(&serviceInfoContext), NULL); const char *initBooteventErr[] = {"init"};
PluginExecCmd("clear", 0, nullptr); PluginExecCmd("bootevent", ARRAY_LENGTH(initBooteventErr), initBooteventErr);
SystemWriteParam("bootevent.bootevent1", "true");
SystemWriteParam("bootevent.bootevent2", "true");
SystemWriteParam("bootevent.bootevent2", "true");
SystemWriteParam("persist.init.bootevent.enable", "false");
HookMgrExecute(GetBootStageHookMgr(), INIT_POST_PERSIST_PARAM_LOAD, NULL, NULL);
cJSON_Delete(fileRoot); cJSON_Delete(fileRoot);
} }
......
...@@ -94,36 +94,40 @@ public: ...@@ -94,36 +94,40 @@ public:
ret = RemoveParameterWatcher("test.permission.watcher.test1", ret = RemoveParameterWatcher("test.permission.watcher.test1",
TestParameterChange, reinterpret_cast<void *>(index)); TestParameterChange, reinterpret_cast<void *>(index));
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
// has beed deleted
ret = RemoveParameterWatcher("test.permission.watcher.test1", ret = RemoveParameterWatcher("test.permission.watcher.test1",
TestParameterChange, reinterpret_cast<void *>(index)); TestParameterChange, reinterpret_cast<void *>(index));
EXPECT_EQ(ret, 0); EXPECT_NE(ret, 0);
// 非法 // 非法
ret = SystemWatchParameter("test.permission.watcher.tes^^^^t1*", TestParameterChange, nullptr); ret = SystemWatchParameter("test.permission.watcher.tes^^^^t1*", TestParameterChange, nullptr);
EXPECT_NE(ret, 0); EXPECT_NE(ret, 0);
ret = SystemWatchParameter("test.permission.read.test1*", TestParameterChange, nullptr); ret = SystemWatchParameter("test.permission.read.test1*", TestParameterChange, nullptr);
#ifdef __MUSL__
EXPECT_EQ(ret, DAC_RESULT_FORBIDED); EXPECT_EQ(ret, DAC_RESULT_FORBIDED);
#endif
return 0; return 0;
} }
int TestDelWatcher() int TestDelWatcher()
{ {
int ret = SystemWatchParameter("test.permission.watcher.test1", nullptr, nullptr); size_t index = 1;
int ret = SystemWatchParameter("test.permission.watcher.test3.1", TestParameterChange, (void *)index);
EXPECT_EQ(ret, 0);
ret = SystemWatchParameter("test.permission.watcher.test3.1*", TestParameterChange, (void *)index);
EXPECT_EQ(ret, 0);
ret = SystemWatchParameter("test.permission.watcher.test3.2", TestParameterChange, (void *)index);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
ret = SystemWatchParameter("test.permission.watcher.test1*", nullptr, nullptr); ret = SystemWatchParameter("test.permission.watcher.test3.1", nullptr, nullptr);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
ret = SystemWatchParameter("test.permission.watcher.test2", nullptr, nullptr); ret = SystemWatchParameter("test.permission.watcher.test3.1*", nullptr, nullptr);
EXPECT_EQ(ret, 0);
ret = SystemWatchParameter("test.permission.watcher.test3.2", nullptr, nullptr);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
// 非法 // 非法
ret = SystemWatchParameter("test.permission.watcher.tes^^^^t1*", nullptr, nullptr); ret = SystemWatchParameter("test.permission.watcher.tes^^^^t1*", nullptr, nullptr);
EXPECT_NE(ret, 0); EXPECT_NE(ret, 0);
ret = SystemWatchParameter("test.permission.read.test1*", nullptr, nullptr); ret = SystemWatchParameter("test.permission.read.test1*", nullptr, nullptr);
#ifdef __MUSL__
EXPECT_EQ(ret, DAC_RESULT_FORBIDED); EXPECT_EQ(ret, DAC_RESULT_FORBIDED);
#endif
return 0; return 0;
} }
...@@ -134,16 +138,15 @@ public: ...@@ -134,16 +138,15 @@ public:
MessageOption option; MessageOption option;
data.WriteInterfaceToken(IWatcher::GetDescriptor()); data.WriteInterfaceToken(IWatcher::GetDescriptor());
data.WriteString(name); data.WriteString(name);
data.WriteString(name);
data.WriteString("watcherId"); data.WriteString("watcherId");
int ret = SystemWatchParameter(name.c_str(), TestParameterChange, nullptr); int ret = SystemWatchParameter(name.c_str(), TestParameterChange, nullptr);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
OHOS::init_param::WatcherManagerKits &instance = OHOS::init_param::WatcherManagerKits::GetInstance(); WatcherManagerKits &instance = OHOS::init_param::WatcherManagerKits::GetInstance();
OHOS::init_param::WatcherManagerKits::ParamWatcherKitPtr watcher = instance.GetParamWatcher(name); if (instance.remoteWatcher_ != nullptr) {
if (watcher != nullptr) { instance.remoteWatcher_->OnRemoteRequest(IWatcher::PARAM_CHANGE, data, reply, option);
watcher->OnRemoteRequest(IWatcher::PARAM_CHANGE, data, reply, option); instance.remoteWatcher_->OnRemoteRequest(IWatcher::PARAM_CHANGE + 1, data, reply, option);
watcher->OnRemoteRequest(IWatcher::PARAM_CHANGE + 1, data, reply, option); instance.remoteWatcher_->OnParameterChange(name.c_str(), "testname", "testvalue");
watcher->OnParameterChange("testname", "testvalue");
} }
return 0; return 0;
} }
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "parcel.h" #include "parcel.h"
#include "securec.h" #include "securec.h"
#include "system_ability_definition.h" #include "system_ability_definition.h"
#include "string_ex.h"
#include "watcher.h" #include "watcher.h"
#include "watcher_manager.h" #include "watcher_manager.h"
#include "watcher_proxy.h" #include "watcher_proxy.h"
...@@ -41,7 +42,7 @@ public: ...@@ -41,7 +42,7 @@ public:
TestWatcher() {} TestWatcher() {}
~TestWatcher() = default; ~TestWatcher() = default;
void OnParameterChange(const std::string &name, const std::string &value) override void OnParameterChange(const std::string &prefix, const std::string &name, const std::string &value) override
{ {
printf("TestWatcher::OnParameterChange name %s %s \n", name.c_str(), value.c_str()); printf("TestWatcher::OnParameterChange name %s %s \n", name.c_str(), value.c_str());
} }
...@@ -57,7 +58,7 @@ public: ...@@ -57,7 +58,7 @@ public:
void TearDown() {} void TearDown() {}
void TestBody() {} void TestBody() {}
int TestAddWatcher(const std::string &keyPrefix, uint32_t &watcherId) int TestAddRemoteWatcher(uint32_t agentId, uint32_t &watcherId)
{ {
WatcherManagerPtr watcherManager = GetWatcherManager(); WatcherManagerPtr watcherManager = GetWatcherManager();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager"); WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager");
...@@ -66,19 +67,58 @@ public: ...@@ -66,19 +67,58 @@ public:
MessageOption option; MessageOption option;
data.WriteInterfaceToken(IWatcherManager::GetDescriptor()); data.WriteInterfaceToken(IWatcherManager::GetDescriptor());
data.WriteString(keyPrefix);
sptr<IWatcher> watcher = new TestWatcher(); sptr<IWatcher> watcher = new TestWatcher();
bool ret = data.WriteRemoteObject(watcher->AsObject()); bool ret = data.WriteRemoteObject(watcher->AsObject());
WATCHER_CHECK(ret, return 0, "Can not get remote"); WATCHER_CHECK(ret, return 0, "Can not get remote");
watcherManager->OnRemoteRequest(IWatcherManager::ADD_WATCHER, data, reply, option); data.WriteUint32(agentId);
watcherManager->OnRemoteRequest(IWatcherManager::ADD_REMOTE_AGENT, data, reply, option);
watcherId = reply.ReadUint32(); watcherId = reply.ReadUint32();
EXPECT_NE(watcherId, 0); EXPECT_NE(watcherId, 0);
EXPECT_EQ(watcherManager->GetWatcherGroup(1000) != NULL, 0); // 1000 test group id
EXPECT_EQ(watcherManager->GetWatcherGroup("TestAddWatcher") != NULL, 0); // test key not exist auto remoteWatcher = watcherManager->GetRemoteWatcher(watcherId);
if (remoteWatcher != nullptr) {
EXPECT_EQ(remoteWatcher->GetAgentId(), agentId);
} else {
EXPECT_EQ(0, agentId);
}
return 0;
}
int TestDelRemoteWatcher(uint32_t watcherId)
{
WatcherManagerPtr watcherManager = GetWatcherManager();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager");
MessageParcel data;
MessageParcel reply;
MessageOption option;
data.WriteInterfaceToken(IWatcherManager::GetDescriptor());
data.WriteUint32(watcherId);
watcherManager->OnRemoteRequest(IWatcherManager::DEL_REMOTE_AGENT, data, reply, option);
EXPECT_EQ(reply.ReadInt32(), 0);
EXPECT_EQ(watcherManager->GetRemoteWatcher(watcherId) == nullptr, 1);
return 0;
}
int TestAddWatcher(const std::string &keyPrefix, uint32_t watcherId)
{
WatcherManagerPtr watcherManager = GetWatcherManager();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager");
MessageParcel data;
MessageParcel reply;
MessageOption option;
data.WriteInterfaceToken(IWatcherManager::GetDescriptor());
data.WriteString(keyPrefix);
data.WriteUint32(watcherId);
watcherManager->OnRemoteRequest(IWatcherManager::ADD_WATCHER, data, reply, option);
int ret = reply.ReadInt32();
EXPECT_EQ(ret, 0);
EXPECT_EQ(watcherManager->GetWatcherGroup(keyPrefix) != nullptr, 1);
return 0; return 0;
} }
int TestDelWatcher(const std::string &keyPrefix, uint32_t &watcherId) int TestDelWatcher(const std::string &keyPrefix, uint32_t watcherId)
{ {
WatcherManagerPtr watcherManager = GetWatcherManager(); WatcherManagerPtr watcherManager = GetWatcherManager();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager"); WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager");
...@@ -90,7 +130,6 @@ public: ...@@ -90,7 +130,6 @@ public:
data.WriteUint32(watcherId); data.WriteUint32(watcherId);
watcherManager->OnRemoteRequest(IWatcherManager::DEL_WATCHER, data, reply, option); watcherManager->OnRemoteRequest(IWatcherManager::DEL_WATCHER, data, reply, option);
EXPECT_EQ(reply.ReadInt32(), 0); EXPECT_EQ(reply.ReadInt32(), 0);
printf("TestDelWatcher %s watcherId %d %p \n", keyPrefix.c_str(), watcherId, watcherManager);
return 0; return 0;
} }
...@@ -103,7 +142,7 @@ public: ...@@ -103,7 +142,7 @@ public:
msgSize = PARAM_ALIGN(msgSize); // align msgSize = PARAM_ALIGN(msgSize); // align
std::vector<char> buffer(msgSize, 0); std::vector<char> buffer(msgSize, 0);
ParamMessage *msg = reinterpret_cast<ParamMessage *>(buffer.data()); ParamMessage *msg = reinterpret_cast<ParamMessage *>(buffer.data());
WATCHER_CHECK(msg != NULL, return -1, "Invalid msg"); WATCHER_CHECK(msg != nullptr, return -1, "Invalid msg");
msg->type = MSG_NOTIFY_PARAM; msg->type = MSG_NOTIFY_PARAM;
msg->msgSize = msgSize; msg->msgSize = msgSize;
msg->id.watcherId = watcherId; msg->id.watcherId = watcherId;
...@@ -112,7 +151,7 @@ public: ...@@ -112,7 +151,7 @@ public:
uint32_t offset = 0; uint32_t offset = 0;
ret = FillParamMsgContent(msg, &offset, PARAM_VALUE, value.c_str(), value.size()); ret = FillParamMsgContent(msg, &offset, PARAM_VALUE, value.c_str(), value.size());
WATCHER_CHECK(ret == 0, return -1, "Failed to fill value"); WATCHER_CHECK(ret == 0, return -1, "Failed to fill value");
watcherManager->ProcessWatcherMessage(buffer, msgSize); watcherManager->ProcessWatcherMessage(msg);
return 0; return 0;
} }
...@@ -124,59 +163,61 @@ public: ...@@ -124,59 +163,61 @@ public:
EXPECT_NE(remoteObj, nullptr); EXPECT_NE(remoteObj, nullptr);
WatcherProxy *watcher = new WatcherProxy(remoteObj); WatcherProxy *watcher = new WatcherProxy(remoteObj);
if (watcher != nullptr) { if (watcher != nullptr) {
watcher->OnParameterChange(name, value); watcher->OnParameterChange(name, name, value);
delete watcher; delete watcher;
} }
return 0; return 0;
} }
int TestWatchAgentDel(const std::string &keyPrefix) int TestWatchAgentDump(const std::string &keyPrefix)
{ {
WatcherManagerPtr watcherManager = GetWatcherManager(); WatcherManagerPtr watcherManager = GetWatcherManager();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager"); // dump watcher
MessageParcel data; std::vector<std::u16string> args = {};
MessageParcel reply; watcherManager->Dump(STDOUT_FILENO, args);
MessageOption option; // dump parameter
args.push_back(Str8ToStr16("-h"));
watcherManager->Dump(STDOUT_FILENO, args);
args.clear();
args.push_back(Str8ToStr16("-k"));
args.push_back(Str8ToStr16(keyPrefix.c_str()));
watcherManager->Dump(STDOUT_FILENO, args);
return 0;
}
data.WriteInterfaceToken(IWatcherManager::GetDescriptor()); int TestWatchAgentDied(uint32_t watcherId)
data.WriteString(keyPrefix); {
sptr<IWatcher> watcher = new TestWatcher(); WatcherManagerPtr watcherManager = GetWatcherManager();
bool ret = data.WriteRemoteObject(watcher->AsObject()); WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get manager");
WATCHER_CHECK(ret, return 0, "Can not get remote"); auto remoteWatcher = watcherManager->GetRemoteWatcher(watcherId);
watcherManager->OnRemoteRequest(IWatcherManager::ADD_WATCHER, data, reply, option); WATCHER_CHECK(remoteWatcher != nullptr, return -1, "Failed to get remote watcher");
uint32_t watcherId = reply.ReadUint32();
EXPECT_NE(watcherId, 0);
if (watcherManager->GetDeathRecipient() != nullptr) { if (watcherManager->GetDeathRecipient() != nullptr) {
watcherManager->GetDeathRecipient()->OnRemoteDied(watcher->AsObject()); watcherManager->GetDeathRecipient()->OnRemoteDied(remoteWatcher->GetWatcher()->AsObject());
} }
printf("TestWatchAgentDel %s success \n", keyPrefix.c_str()); EXPECT_EQ(watcherManager->GetRemoteWatcher(watcherId) == nullptr, 1);
EXPECT_EQ(watcherManager->GetWatcher(watcherId) == nullptr, 1);
return 0; return 0;
} }
int TestInvalid(const std::string &keyPrefix) int TestInvalid(const std::string &keyPrefix)
{ {
WatcherManagerPtr watcherManager = GetWatcherManager(); WatcherManagerPtr watcherManager = GetWatcherManager();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager"); WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get manager");
MessageParcel data; MessageParcel data;
MessageParcel reply; MessageParcel reply;
MessageOption option; MessageOption option;
data.WriteString(keyPrefix); data.WriteString(keyPrefix);
sptr<IWatcher> watcher = new TestWatcher(); watcherManager->OnRemoteRequest(IWatcherManager::REFRESH_WATCHER + 1, data, reply, option);
bool ret = data.WriteRemoteObject(watcher->AsObject());
WATCHER_CHECK(ret, return 0, "Can not get remote");
watcherManager->OnRemoteRequest(IWatcherManager::ADD_WATCHER + 1, data, reply, option);
if (watcherManager->GetDeathRecipient() != nullptr) { data.WriteInterfaceToken(IWatcherManager::GetDescriptor());
watcherManager->GetDeathRecipient()->OnRemoteDied(watcher->AsObject()); data.WriteString(keyPrefix);
} watcherManager->OnRemoteRequest(IWatcherManager::REFRESH_WATCHER + 1, data, reply, option);
return 0; return 0;
} }
int TestStop() int TestStop()
{ {
WatcherManagerPtr watcherManager = GetWatcherManager(); WatcherManagerPtr watcherManager = GetWatcherManager();
WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager"); WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get manager");
watcherManager->OnStop(); watcherManager->OnStop();
return 0; return 0;
} }
...@@ -199,61 +240,79 @@ HWTEST_F(WatcherProxyUnitTest, TestAddWatcher, TestSize.Level0) ...@@ -199,61 +240,79 @@ HWTEST_F(WatcherProxyUnitTest, TestAddWatcher, TestSize.Level0)
{ {
WatcherProxyUnitTest test; WatcherProxyUnitTest test;
uint32_t watcherId = 0; uint32_t watcherId = 0;
test.TestAddRemoteWatcher(1000, watcherId); // 1000 test agent
test.TestAddWatcher("test.permission.watcher.test1", watcherId); test.TestAddWatcher("test.permission.watcher.test1", watcherId);
test.TestProcessWatcherMessage("test.permission.watcher.test1", watcherId); test.TestProcessWatcherMessage("test.permission.watcher.test1", watcherId);
test.TestWatchAgentDump("test.permission.watcher.test1");
} }
HWTEST_F(WatcherProxyUnitTest, TestAddWatcher2, TestSize.Level0) HWTEST_F(WatcherProxyUnitTest, TestAddWatcher2, TestSize.Level0)
{ {
WatcherProxyUnitTest test; WatcherProxyUnitTest test;
uint32_t watcherId = 0; uint32_t watcherId = 0;
test.TestAddRemoteWatcher(1001, watcherId); // 1001 test agent
test.TestAddWatcher("test.permission.watcher.test2", watcherId); test.TestAddWatcher("test.permission.watcher.test2", watcherId);
test.TestAddWatcher("test.permission.watcher.test2", watcherId); test.TestAddWatcher("test.permission.watcher.test2", watcherId);
test.TestAddWatcher("test.permission.watcher.test2", watcherId); test.TestAddWatcher("test.permission.watcher.test2", watcherId);
test.TestWatchAgentDump("test.permission.watcher.test2");
} }
HWTEST_F(WatcherProxyUnitTest, TestAddWatcher3, TestSize.Level0) HWTEST_F(WatcherProxyUnitTest, TestAddWatcher3, TestSize.Level0)
{ {
WatcherProxyUnitTest test; WatcherProxyUnitTest test;
uint32_t watcherId = 0; uint32_t watcherId = 0;
test.TestAddRemoteWatcher(1003, watcherId); // 1003 test agent
test.TestAddWatcher("test.permission.watcher.test3", watcherId); test.TestAddWatcher("test.permission.watcher.test3", watcherId);
test.TestWatchAgentDump("test.permission.watcher.test3");
} }
HWTEST_F(WatcherProxyUnitTest, TestAddWatcher4, TestSize.Level0) HWTEST_F(WatcherProxyUnitTest, TestAddWatcher4, TestSize.Level0)
{ {
WatcherProxyUnitTest test; WatcherProxyUnitTest test;
uint32_t watcherId = 0; uint32_t watcherId = 0;
test.TestAddRemoteWatcher(1004, watcherId); // 1004 test agent
SystemSetParameter("test.watcher.test4", "1101"); SystemSetParameter("test.watcher.test4", "1101");
SystemSetParameter("test.watcher.test4.test", "1102"); SystemSetParameter("test.watcher.test4.test", "1102");
test.TestAddWatcher("test.watcher.test4*", watcherId); test.TestAddWatcher("test.watcher.test4*", watcherId);
test.TestWatchAgentDump("test.watcher.test4*");
} }
HWTEST_F(WatcherProxyUnitTest, TestAddWatcher5, TestSize.Level0) HWTEST_F(WatcherProxyUnitTest, TestAddWatcher5, TestSize.Level0)
{ {
WatcherProxyUnitTest test; WatcherProxyUnitTest test;
uint32_t watcherId = 0; uint32_t watcherId = 0;
test.TestAddRemoteWatcher(1005, watcherId); // 1005 test agent
test.TestAddWatcher("test.permission.watcher.test5", watcherId); test.TestAddWatcher("test.permission.watcher.test5", watcherId);
SystemSetParameter("test.permission.watcher.test5", "1101"); SystemSetParameter("test.permission.watcher.test5", "1101");
test.TestWatchAgentDump("test.permission.watcher.test5");
} }
HWTEST_F(WatcherProxyUnitTest, TestDelWatcher, TestSize.Level0) HWTEST_F(WatcherProxyUnitTest, TestDelWatcher, TestSize.Level0)
{ {
WatcherProxyUnitTest test; WatcherProxyUnitTest test;
uint32_t watcherId = 0; uint32_t watcherId = 0;
test.TestAddRemoteWatcher(1006, watcherId); // 1005 test agent
test.TestAddWatcher("test.permission.watcher.testDel", watcherId); test.TestAddWatcher("test.permission.watcher.testDel", watcherId);
test.TestDelWatcher("test.permission.watcher.testDel", watcherId); test.TestDelWatcher("test.permission.watcher.testDel", watcherId);
test.TestDelRemoteWatcher(watcherId);
test.TestWatchAgentDump("test.permission.watcher.testDel");
} }
HWTEST_F(WatcherProxyUnitTest, TestWatchProxy, TestSize.Level0) HWTEST_F(WatcherProxyUnitTest, TestDiedWatcher, TestSize.Level0)
{ {
WatcherProxyUnitTest test; WatcherProxyUnitTest test;
test.TestWatchProxy("test.permission.watcher.test1", "watcherId"); uint32_t watcherId = 0;
test.TestAddRemoteWatcher(1006, watcherId); // 1005 test agent
test.TestAddWatcher("test.permission.watcher.testdied", watcherId);
test.TestDelWatcher("test.permission.watcher.testdied", watcherId);
test.TestWatchAgentDied(watcherId);
test.TestWatchAgentDump("test.permission.watcher.testdied");
} }
HWTEST_F(WatcherProxyUnitTest, TestWatchAgentDel, TestSize.Level0) HWTEST_F(WatcherProxyUnitTest, TestWatchProxy, TestSize.Level0)
{ {
WatcherProxyUnitTest test; WatcherProxyUnitTest test;
test.TestWatchAgentDel("test.permission.watcher.test1"); test.TestWatchProxy("test.permission.watcher.test1", "watcherId");
} }
HWTEST_F(WatcherProxyUnitTest, TestInvalid, TestSize.Level0) HWTEST_F(WatcherProxyUnitTest, TestInvalid, TestSize.Level0)
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "seccomp_policy.h" #include "seccomp_policy.h"
using SyscallFunc = bool (*)(void); using SyscallFunc = bool (*)(void);
constexpr int SLEEP_TIME = 100000; // 100ms
using namespace testing::ext; using namespace testing::ext;
using namespace std; using namespace std;
...@@ -93,6 +94,11 @@ public: ...@@ -93,6 +94,11 @@ public:
std::cout << "signal failed:" << strerror(errno) << std::endl; std::cout << "signal failed:" << strerror(errno) << std::endl;
} }
/* Sleeping for avoiding influencing child proccess wait for other threads
* which were created by other unittests to release global rwlock. The global
* rwlock will be used by function dlopen in child process */
usleep(SLEEP_TIME);
pid = StartChild(filterName, func); pid = StartChild(filterName, func);
if (pid == -1) { if (pid == -1) {
std::cout << "fork failed:" << strerror(errno) << std::endl; std::cout << "fork failed:" << strerror(errno) << std::endl;
......
...@@ -72,3 +72,7 @@ ...@@ -72,3 +72,7 @@
/dev/block/sdd19 0660 6666 6666 /dev/block/sdd19 0660 6666 6666
/dev/watchdog 0660 watchdog watchdog /dev/watchdog 0660 watchdog watchdog
/dev/hdf_input_event* 0660 3029 3029 /dev/hdf_input_event* 0660 3029 3029
/dev/HDF* 0666 0 0
/dev/ttyS* 0666 0 0
/dev/ttyACM* 0666 0 0
/dev/ttyUSB* 0666 0 0
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册