1 /*
2  * Copyright (c) 2021-2023 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 "local_ability_manager_stub.h"
17 
18 #include <cstdint>
19 #include <utility>
20 #include <cinttypes>
21 
22 #include "errors.h"
23 #include "hilog/log_cpp.h"
24 #include "if_local_ability_manager.h"
25 #include "ipc_types.h"
26 #include "message_option.h"
27 #include "message_parcel.h"
28 #include "parse_util.h"
29 #include "safwk_log.h"
30 #include "datetime_ex.h"
31 #include "system_ability_definition.h"
32 #include "ipc_skeleton.h"
33 #include "accesstoken_kit.h"
34 
35 using namespace OHOS::HiviewDFX;
36 
37 namespace OHOS {
38 namespace {
39 const std::string PERMISSION_EXT_TRANSACTION = "ohos.permission.ACCESS_EXT_SYSTEM_ABILITY";
40 const std::string PERMISSION_MANAGE = "ohos.permission.MANAGE_SYSTEM_ABILITY";
41 }
42 
LocalAbilityManagerStub()43 LocalAbilityManagerStub::LocalAbilityManagerStub()
44 {
45     memberFuncMap_[static_cast<uint32_t>(SafwkInterfaceCode::START_ABILITY_TRANSACTION)] =
46         LocalAbilityManagerStub::LocalStartAbility;
47     memberFuncMap_[static_cast<uint32_t>(SafwkInterfaceCode::STOP_ABILITY_TRANSACTION)] =
48         LocalAbilityManagerStub::LocalStopAbility;
49     memberFuncMap_[static_cast<uint32_t>(SafwkInterfaceCode::ACTIVE_ABILITY_TRANSACTION)] =
50         LocalAbilityManagerStub::LocalActiveAbility;
51     memberFuncMap_[static_cast<uint32_t>(SafwkInterfaceCode::IDLE_ABILITY_TRANSACTION)] =
52         LocalAbilityManagerStub::LocalIdleAbility;
53     memberFuncMap_[static_cast<uint32_t>(SafwkInterfaceCode::SEND_STRATEGY_TO_SA_TRANSACTION)] =
54         LocalAbilityManagerStub::LocalSendStrategyToSA;
55     memberFuncMap_[static_cast<uint32_t>(SafwkInterfaceCode::IPC_STAT_CMD_TRANSACTION)] =
56         LocalAbilityManagerStub::LocalIpcStatCmdProc;
57     memberFuncMap_[static_cast<uint32_t>(SafwkInterfaceCode::FFRT_DUMPER_TRANSACTION)] =
58         LocalAbilityManagerStub::LocalFfrtDumperProc;
59     memberFuncMap_[static_cast<uint32_t>(SafwkInterfaceCode::SYSTEM_ABILITY_EXT_TRANSACTION)] =
60         LocalAbilityManagerStub::LocalSystemAbilityExtProc;
61 }
62 
CheckPermission(uint32_t code)63 bool LocalAbilityManagerStub::CheckPermission(uint32_t code)
64 {
65     uint32_t accessToken = IPCSkeleton::GetCallingTokenID();
66     std::string permissionToCheck;
67 
68     if (code == static_cast<uint32_t>(SafwkInterfaceCode::SYSTEM_ABILITY_EXT_TRANSACTION)) {
69         permissionToCheck = PERMISSION_EXT_TRANSACTION;
70     } else {
71         permissionToCheck = PERMISSION_MANAGE;
72     }
73 
74     int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(accessToken, permissionToCheck);
75     return ret == static_cast<int32_t>(Security::AccessToken::PermissionState::PERMISSION_GRANTED);
76 }
77 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)78 int32_t LocalAbilityManagerStub::OnRemoteRequest(uint32_t code,
79     MessageParcel& data, MessageParcel& reply, MessageOption& option)
80 {
81     HILOGD(TAG, "code:%{public}u, flags:%{public}d", code, option.GetFlags());
82     if (!EnforceInterceToken(data)) {
83         HILOGW(TAG, "check interface token failed!");
84         return ERR_PERMISSION_DENIED;
85     }
86 
87     if (CheckPermission(code) == false) {
88         HILOGW(TAG, "check permission failed! code:%{public}u, callingPid:%{public}d, callingTokenId:%{public}u",
89             code, IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingTokenID());
90         return ERR_PERMISSION_DENIED;
91     }
92     HILOGD(TAG, "check permission success!");
93 
94     auto iter = memberFuncMap_.find(code);
95     if (iter != memberFuncMap_.end()) {
96         return iter->second(this, data, reply);
97     }
98     HILOGW(TAG, "unknown request code!");
99     return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
100 }
101 
StartAbilityInner(MessageParcel & data,MessageParcel & reply)102 int32_t LocalAbilityManagerStub::StartAbilityInner(MessageParcel& data, MessageParcel& reply)
103 {
104     int32_t saId = -1;
105     bool ret = data.ReadInt32(saId);
106     if (!ret) {
107         HILOGW(TAG, "read saId failed!");
108         return ERR_NULL_OBJECT;
109     }
110     if (!CheckInputSysAbilityId(saId)) {
111         HILOGW(TAG, "check SA:%{public}d id failed!", saId);
112         return ERR_NULL_OBJECT;
113     }
114     int64_t begin = GetTickCount();
115     std::string eventStr = data.ReadString();
116     if (eventStr.empty()) {
117         HILOGW(TAG, "LocalAbilityManagerStub::StartAbilityInner read eventStr failed!");
118         return ERR_NULL_OBJECT;
119     }
120     bool result = StartAbility(saId, eventStr);
121     LOGI("StartSaInner %{public}s to start SA:%{public}d,eventLen:%{public}zu,spend:%{public}" PRId64 "ms",
122         result ? "suc" : "fail", saId, eventStr.length(), (GetTickCount() - begin));
123     return ERR_NONE;
124 }
125 
StopAbilityInner(MessageParcel & data,MessageParcel & reply)126 int32_t LocalAbilityManagerStub::StopAbilityInner(MessageParcel& data, MessageParcel& reply)
127 {
128     int32_t saId = -1;
129     bool ret = data.ReadInt32(saId);
130     if (!ret) {
131         return ERR_NULL_OBJECT;
132     }
133     if (!CheckInputSysAbilityId(saId)) {
134         HILOGW(TAG, "read saId failed!");
135         return ERR_NULL_OBJECT;
136     }
137     int64_t begin = GetTickCount();
138     std::string eventStr = data.ReadString();
139     if (eventStr.empty()) {
140         HILOGW(TAG, "StopAbilityInner read eventStr failed!");
141         return ERR_NULL_OBJECT;
142     }
143     bool result = StopAbility(saId, eventStr);
144     LOGI("StopSaInner %{public}s to stop SA:%{public}d,eventLen:%{public}zu,spend:%{public}" PRId64 "ms",
145         result ? "suc" : "fail", saId, eventStr.length(), (GetTickCount() - begin));
146     return ERR_NONE;
147 }
148 
ActiveAbilityInner(MessageParcel & data,MessageParcel & reply)149 int32_t LocalAbilityManagerStub::ActiveAbilityInner(MessageParcel& data, MessageParcel& reply)
150 {
151     int32_t saId = -1;
152     bool ret = data.ReadInt32(saId);
153     if (!ret) {
154         return ERR_NULL_OBJECT;
155     }
156     if (!CheckInputSysAbilityId(saId)) {
157         HILOGW(TAG, "read saId failed!");
158         return ERR_NULL_OBJECT;
159     }
160     int64_t begin = GetTickCount();
161     nlohmann::json activeReason = ParseUtil::StringToJsonObj(data.ReadString());
162     bool result = ActiveAbility(saId, activeReason);
163     if (!reply.WriteBool(result)) {
164         HILOGW(TAG, "ActiveAbilityInner Write result failed!");
165         return ERR_NULL_OBJECT;
166     }
167     LOGI("ActiveSaInner %{public}s to Active SA:%{public}d,spend:%{public}" PRId64 "ms",
168         result ? "suc" : "fail", saId, (GetTickCount() - begin));
169     return ERR_NONE;
170 }
171 
IdleAbilityInner(MessageParcel & data,MessageParcel & reply)172 int32_t LocalAbilityManagerStub::IdleAbilityInner(MessageParcel& data, MessageParcel& reply)
173 {
174     int32_t saId = -1;
175     bool ret = data.ReadInt32(saId);
176     if (!ret) {
177         return ERR_NULL_OBJECT;
178     }
179     if (!CheckInputSysAbilityId(saId)) {
180         HILOGW(TAG, "read saId failed!");
181         return ERR_NULL_OBJECT;
182     }
183     int64_t begin = GetTickCount();
184     nlohmann::json idleReason = ParseUtil::StringToJsonObj(data.ReadString());
185     int32_t delayTime = 0;
186     bool result = IdleAbility(saId, idleReason, delayTime);
187     if (!reply.WriteBool(result)) {
188         HILOGW(TAG, "ActiveAbilityInner Write result failed!");
189         return ERR_NULL_OBJECT;
190     }
191     if (!reply.WriteInt32(delayTime)) {
192         HILOGW(TAG, "ActiveAbilityInner Write delayTime failed!");
193         return ERR_NULL_OBJECT;
194     }
195     LOGI("IdleSaInner %{public}s to Idle SA:%{public}d,delayTime:%{public}d,spend:%{public}" PRId64 "ms",
196         result ? "suc" : "fail", saId, delayTime, (GetTickCount() - begin));
197     return ERR_NONE;
198 }
199 
SendStrategyToSAInner(MessageParcel & data,MessageParcel & reply)200 int32_t LocalAbilityManagerStub::SendStrategyToSAInner(MessageParcel& data, MessageParcel& reply)
201 {
202     int32_t type = -1;
203     bool ret = data.ReadInt32(type);
204     if (!ret) {
205         return ERR_NULL_OBJECT;
206     }
207     int32_t saId = -1;
208     ret = data.ReadInt32(saId);
209     if (!ret) {
210         return ERR_NULL_OBJECT;
211     }
212     if (!CheckInputSysAbilityId(saId)) {
213         HILOGW(TAG, "read saId failed!");
214         return ERR_NULL_OBJECT;
215     }
216     int32_t level = -1;
217     ret = data.ReadInt32(level);
218     if (!ret) {
219         return ERR_NULL_OBJECT;
220     }
221     std::string aciton;
222     ret = data.ReadString(aciton);
223     if (!ret) {
224         return ERR_NULL_OBJECT;
225     }
226     bool result = SendStrategyToSA(type, saId, level, aciton);
227     if (!result) {
228         HILOGE(TAG, "SendStrategyToSA:%{public}d called failed", saId);
229         return ERR_NULL_OBJECT;
230     }
231     return ERR_NONE;
232 }
233 
IpcStatCmdProcInner(MessageParcel & data,MessageParcel & reply)234 int32_t LocalAbilityManagerStub::IpcStatCmdProcInner(MessageParcel& data, MessageParcel& reply)
235 {
236     int32_t fd = data.ReadFileDescriptor();
237     if (fd < 0) {
238         return ERR_NULL_OBJECT;
239     }
240     int cmd = -1;
241     bool ret = data.ReadInt32(cmd);
242     if (!ret) {
243         ::close(fd);
244         return ERR_NULL_OBJECT;
245     }
246     bool result = IpcStatCmdProc(fd, cmd);
247     if (!reply.WriteBool(result)) {
248         HILOGW(TAG, "IpcStatCmdProc Write result failed!");
249         ::close(fd);
250         return ERR_NULL_OBJECT;
251     }
252     ::close(fd);
253     HILOGD(TAG, "IpcStatCmdProc called %{public}s  ", result ? "success" : "failed");
254     return ERR_NONE;
255 }
256 
FfrtDumperProcInner(MessageParcel & data,MessageParcel & reply)257 int32_t LocalAbilityManagerStub::FfrtDumperProcInner(MessageParcel& data, MessageParcel& reply)
258 {
259     std::string ffrtDumperInfo;
260     bool result = FfrtDumperProc(ffrtDumperInfo);
261     HILOGI(TAG, "safwk ffrt dumper result %{public}s", result ? "succeed" : "failed");
262     if (!reply.WriteString(ffrtDumperInfo)) {
263         HILOGW(TAG, "FfrtDumperProc write ffrtDumperInfo failed!");
264         return ERR_NULL_OBJECT;
265     }
266     HILOGD(TAG, "FfrtDumperProc called %{public}s ", result? "success" : "failed");
267     return ERR_NONE;
268 }
269 
SystemAbilityExtProcInner(MessageParcel & data,MessageParcel & reply)270 int32_t LocalAbilityManagerStub::SystemAbilityExtProcInner(MessageParcel& data, MessageParcel& reply)
271 {
272     int32_t saId = -1;
273     bool ret = data.ReadInt32(saId);
274     if (!ret) {
275         return INVALID_DATA;
276     }
277     if (!CheckInputSysAbilityId(saId)) {
278         HILOGW(TAG, "read saId failed!");
279         return INVALID_DATA;
280     }
281     std::string extension = data.ReadString();
282     if (extension.empty()) {
283         HILOGW(TAG, "LocalAbilityManagerStub::SystemAbilityExtProcInner read extension failed!");
284         return INVALID_DATA;
285     }
286 
287     SystemAbilityExtensionPara callback;
288     callback.data_ = &data;
289     callback.reply_ = &reply;
290 
291     int32_t result = SystemAbilityExtProc(extension, saId, &callback, false);
292     if (result != ERR_NONE) {
293         HILOGW(TAG, "SystemAbilityExtProc fail!");
294         return result;
295     }
296 
297     HILOGD(TAG, "SystemAbilityExtProc success ");
298     return ERR_NONE;
299 }
300 
CheckInputSysAbilityId(int32_t systemAbilityId)301 bool LocalAbilityManagerStub::CheckInputSysAbilityId(int32_t systemAbilityId)
302 {
303     return (systemAbilityId >= FIRST_SYS_ABILITY_ID) && (systemAbilityId <= LAST_SYS_ABILITY_ID);
304 }
305 
EnforceInterceToken(MessageParcel & data)306 bool LocalAbilityManagerStub::EnforceInterceToken(MessageParcel& data)
307 {
308     std::u16string interfaceToken = data.ReadInterfaceToken();
309     return interfaceToken == LOCAL_ABILITY_MANAGER_INTERFACE_TOKEN;
310 }
311 }
312