1/*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include <stdlib.h>
16#include "init_log.h"
17#include "init_module_engine.h"
18#include "loop_event.h"
19
20static MODULE_MGR *defaultModuleMgr = NULL;
21static MODULE_MGR *autorunModuleMgr = NULL;
22
23int InitModuleMgrInstall(const char *moduleName)
24{
25    if (moduleName == NULL) {
26        return -1;
27    }
28
29    if (defaultModuleMgr == NULL) {
30        defaultModuleMgr = ModuleMgrCreate("init");
31    }
32    if (defaultModuleMgr == NULL) {
33        return -1;
34    }
35
36    return ModuleMgrInstall(defaultModuleMgr, moduleName, 0, NULL);
37}
38
39void InitModuleMgrUnInstall(const char *moduleName)
40{
41    ModuleMgrUninstall(defaultModuleMgr, moduleName);
42}
43
44static void DelayedUninstall(const IdleHandle taskHandle, void *context)
45{
46    const char *moduleName = (const char *)context;
47    if (moduleName == NULL) {
48        return;
49    }
50    ModuleMgrUninstall(autorunModuleMgr, moduleName);
51}
52
53void AutorunModuleMgrUnInstall(const char *moduleName)
54{
55    void *context = (void *)strdup(moduleName);
56    if (context == NULL) {
57        return;
58    }
59    LE_DelayProc(LE_GetDefaultLoop(), DelayedUninstall, context);
60}
61
62static void InitModuleDump(const MODULE_INFO *moduleInfo)
63{
64    printf("%s\n", moduleInfo->name);
65}
66
67void InitModuleMgrDump(void)
68{
69    if (defaultModuleMgr != NULL) {
70        ModuleMgrTraversal(defaultModuleMgr, NULL, InitModuleDump);
71    }
72
73    if (autorunModuleMgr != NULL) {
74        ModuleMgrTraversal(autorunModuleMgr, NULL, InitModuleDump);
75    }
76}
77
78static int ModuleMgrCmdInstall(int id, const char *name, int argc, const char **argv)
79{
80    INIT_ERROR_CHECK(argv != NULL && argc >= 1, return -1, "Invalid install parameter");
81    int ret;
82    if (defaultModuleMgr == NULL) {
83        defaultModuleMgr = ModuleMgrCreate("init");
84    }
85    ret = ModuleMgrInstall(defaultModuleMgr, argv[0], argc-1, argv+1);
86    INIT_ERROR_CHECK(ret == 0, return ret, "Install module %s fail errno %d", argv[0], ret);
87    return 0;
88}
89
90static int ModuleMgrCmdUninstall(int id, const char *name, int argc, const char **argv)
91{
92    INIT_ERROR_CHECK(argv != NULL && argc >= 1, return -1, "Invalid install parameter");
93    ModuleMgrUninstall(defaultModuleMgr, argv[0]);
94    return 0;
95}
96
97static int moduleMgrCommandsInit(const HOOK_INFO *info, void *cookie)
98{
99    // "ohos.servicectrl.install"
100    (void)AddCmdExecutor("install", ModuleMgrCmdInstall);
101    (void)AddCmdExecutor("uninstall", ModuleMgrCmdUninstall);
102    // read cfg and start static plugin
103    return 0;
104}
105
106static int loadAutorunModules(const HOOK_INFO *info, void *cookie)
107{
108    autorunModuleMgr = ModuleMgrScan("init/autorun");
109    INIT_LOGV("Load autorun modules return autorunModuleMgr");
110    return 0;
111}
112
113MODULE_CONSTRUCTOR(void)
114{
115    // Depends on parameter service
116    InitAddGlobalInitHook(0, loadAutorunModules);
117    InitAddPreCfgLoadHook(0, moduleMgrCommandsInit);
118}
119