1 /*
2  * Copyright (c) 2020 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ability_scheduler.h"
17 
18 #include <log.h>
19 #include <utils.h>
20 
21 #include "ability_errors.h"
22 #include "ability_kit_command.h"
23 #include "ability_service_interface.h"
24 #include "ipc_skeleton.h"
25 #include "want_utils.h"
26 
27 namespace OHOS {
28 const int MAX_MODULE_SIZE = 16;
AbilityScheduler(AbilityEventHandler & eventHandler,Scheduler & scheduler)29 AbilityScheduler::AbilityScheduler(AbilityEventHandler &eventHandler, Scheduler &scheduler)
30     : eventHandler_(eventHandler), scheduler_(scheduler)
31 {
32 }
33 
AmsCallback(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)34 int32_t AbilityScheduler::AmsCallback(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option)
35 {
36     auto scheduler = static_cast<AbilityScheduler *>(option.args);
37     if (scheduler == nullptr) {
38         HILOG_ERROR(HILOG_MODULE_APP, "ams call back error, scheduler is null");
39         // if you need to send reply to the client, please use SendReply method
40         return PARAM_NULL_ERROR;
41     }
42     int result = 0;
43     switch (code) {
44         case SCHEDULER_APP_INIT: {
45             AppInfo appInfo = {};
46             char *bundleName = reinterpret_cast<char *>(ReadString(data, nullptr));
47             char *srcPath = reinterpret_cast<char *>(ReadString(data, nullptr));
48             char *dataPath = reinterpret_cast<char *>(ReadString(data, nullptr));
49             if ((bundleName == nullptr) || (srcPath == nullptr) || (dataPath == nullptr)) {
50                 HILOG_ERROR(HILOG_MODULE_APP, "ams call back error, bundleName, srcPath or dataPath is null");
51                 return PARAM_NULL_ERROR;
52             }
53             appInfo.bundleName = bundleName;
54             appInfo.srcPath = srcPath;
55             appInfo.dataPath = dataPath;
56             ReadBool(data, &(appInfo.isNativeApp));
57             int moduleSize = 0;
58             ReadInt32(data, &moduleSize);
59             if (moduleSize > MAX_MODULE_SIZE) {
60                 HILOG_ERROR(HILOG_MODULE_APP, "moduleSize is too big");
61                 return COMMAND_ERROR;
62             }
63             for (int i = 0; i < moduleSize; i++) {
64                 char *moduleName = reinterpret_cast<char *>(ReadString(data, nullptr));
65                 if ((moduleName != nullptr) && (strlen(moduleName) > 0)) {
66                     appInfo.moduleNames.emplace_front(moduleName);
67                 }
68             }
69             scheduler->PerformAppInit(appInfo);
70             break;
71         }
72         case SCHEDULER_ABILITY_LIFECYCLE: {
73             int state = 0;
74             ReadInt32(data, &state);
75             uint64_t token = 0;
76             ReadUint64(data, &token);
77             int abilityType = 0;
78             ReadInt32(data, &abilityType);
79             Want want = { nullptr, nullptr, nullptr, 0 };
80             if (!DeserializeWant(&want, data)) {
81                 result = SERIALIZE_ERROR;
82                 break;
83             }
84             scheduler->PerformTransactAbilityState(want, state, token, abilityType);
85             break;
86         }
87         case SCHEDULER_ABILITY_CONNECT: {
88             uint64_t token = 0;
89             ReadUint64(data, &token);
90             Want want = { nullptr, nullptr, nullptr, 0 };
91             if (!DeserializeWant(&want, data)) {
92                 result = SERIALIZE_ERROR;
93                 break;
94             }
95             scheduler->PerformConnectAbility(want, token);
96             break;
97         }
98         case SCHEDULER_ABILITY_DISCONNECT: {
99             uint64_t token = 0;
100             ReadUint64(data, &token);
101             Want want = { nullptr, nullptr, nullptr, 0 };
102             if (!DeserializeWant(&want, data)) {
103                 result = SERIALIZE_ERROR;
104                 break;
105             }
106             scheduler->PerformDisconnectAbility(want, token);
107             break;
108         }
109         case SCHEDULER_APP_EXIT: {
110             scheduler->PerformAppExit();
111             break;
112         }
113         case SCHEDULER_DUMP_ABILITY: {
114             Want want = {};
115             if (!DeserializeWant(&want, data)) {
116                 result = SERIALIZE_ERROR;
117                 break;
118             }
119 
120             uint64_t token = 0;
121             ReadUint64(data, &token);
122             scheduler->PerformDumpAbility(want, token);
123             break;
124         }
125         default: {
126             result = COMMAND_ERROR;
127             break;
128         }
129     }
130     return result;
131 }
132 
PerformAppInit(const AppInfo & appInfo)133 void AbilityScheduler::PerformAppInit(const AppInfo &appInfo)
134 {
135     auto task = [this, appInfo] {
136         scheduler_.PerformAppInit(appInfo);
137     };
138     eventHandler_.PostTask(task);
139 }
140 
PerformTransactAbilityState(const Want & want,int state,uint64_t token,int abilityType)141 void AbilityScheduler::PerformTransactAbilityState(const Want &want, int state, uint64_t token, int abilityType)
142 {
143     auto task = [this, want, state, token, abilityType] {
144         scheduler_.PerformTransactAbilityState(want, state, token, abilityType);
145         ClearWant(const_cast<Want *>(&want));
146     };
147     eventHandler_.PostTask(task);
148 }
149 
PerformConnectAbility(const Want & want,uint64_t token)150 void AbilityScheduler::PerformConnectAbility(const Want &want, uint64_t token)
151 {
152     auto task = [this, want, token] {
153         scheduler_.PerformConnectAbility(want, token);
154         ClearWant(const_cast<Want *>(&want));
155     };
156     eventHandler_.PostTask(task);
157 }
158 
PerformDisconnectAbility(const Want & want,uint64_t token)159 void AbilityScheduler::PerformDisconnectAbility(const Want &want, uint64_t token)
160 {
161     auto task = [this, want, token] {
162         scheduler_.PerformDisconnectAbility(want, token);
163         ClearWant(const_cast<Want *>(&want));
164     };
165     eventHandler_.PostTask(task);
166 }
167 
PerformAppExit()168 void AbilityScheduler::PerformAppExit()
169 {
170     auto task = [this] {
171         scheduler_.PerformAppExit();
172     };
173     eventHandler_.PostTask(task);
174 }
175 
PerformDumpAbility(const Want & want,uint64_t token)176 void AbilityScheduler::PerformDumpAbility(const Want &want, uint64_t token)
177 {
178     if (want.sid == nullptr) {
179         HILOG_ERROR(HILOG_MODULE_APP, "svcId is invalid when dump ability");
180         return;
181     }
182     auto task = [this, want, token] {
183         scheduler_.PerformDumpAbility(want, token);
184         ClearWant(const_cast<Want *>(&want));
185     };
186     eventHandler_.PostTask(task);
187 }
188 } // namespace OHOS
189