1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ability_context.h"
17 
18 #include "ability_manager_client.h"
19 #include "accesstoken_kit.h"
20 #include "authorization_result.h"
21 #include "bundle_constants.h"
22 #include "hilog_tag_wrapper.h"
23 #include "iservice_registry.h"
24 #include "os_account_manager_wrapper.h"
25 #include "resource_manager.h"
26 #include "sys_mgr_client.h"
27 #include "system_ability_definition.h"
28 #include "hitrace_meter.h"
29 #include "remote_object_wrapper.h"
30 #include "scene_board_judgement.h"
31 #include "session/host/include/zidl/session_interface.h"
32 #include "session_info.h"
33 #include "string_wrapper.h"
34 #include "want_params_wrapper.h"
35 
36 namespace OHOS {
37 namespace AppExecFwk {
38 int AbilityContext::ABILITY_CONTEXT_DEFAULT_REQUEST_CODE(0);
39 namespace {
40 const std::string GRANT_ABILITY_BUNDLE_NAME = "com.ohos.permissionmanager";
41 const std::string GRANT_ABILITY_ABILITY_NAME = "com.ohos.permissionmanager.GrantAbility";
42 const std::string PERMISSION_KEY = "ohos.user.grant.permission";
43 const std::string STATE_KEY = "ohos.user.grant.permission.state";
44 const std::string TOKEN_KEY = "ohos.ability.params.token";
45 const std::string CALLBACK_KEY = "ohos.ability.params.callback";
46 }
47 
StartAbility(const AAFwk::Want & want,int requestCode)48 ErrCode AbilityContext::StartAbility(const AAFwk::Want &want, int requestCode)
49 {
50     TAG_LOGD(AAFwkTag::CONTEXT, "requestCode = %{public}d", requestCode);
51     AppExecFwk::AbilityType type = GetAbilityInfoType();
52     if (type != AppExecFwk::AbilityType::PAGE && type != AppExecFwk::AbilityType::SERVICE) {
53         TAG_LOGE(AAFwkTag::CONTEXT, "abilityType: %{public}d", type);
54         return ERR_INVALID_VALUE;
55     }
56     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, token_, requestCode);
57     TAG_LOGD(AAFwkTag::CONTEXT, "ret=%{public}d", err);
58     return err;
59 }
60 
StartAbility(const Want & want,int requestCode,const AbilityStartSetting & abilityStartSetting)61 ErrCode AbilityContext::StartAbility(const Want &want, int requestCode, const AbilityStartSetting &abilityStartSetting)
62 {
63     TAG_LOGD(AAFwkTag::CONTEXT, "requestCode: %{public}d",
64         requestCode);
65     AppExecFwk::AbilityType type = GetAbilityInfoType();
66     if (type != AppExecFwk::AbilityType::PAGE && type != AppExecFwk::AbilityType::SERVICE) {
67         TAG_LOGE(AAFwkTag::CONTEXT, "abilityType: %{public}d", type);
68         return ERR_INVALID_VALUE;
69     }
70     ErrCode err =
71         AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, abilityStartSetting, token_, requestCode);
72     TAG_LOGD(AAFwkTag::CONTEXT, "ret=%{public}d", err);
73     return err;
74 }
75 
TerminateAbility()76 ErrCode AbilityContext::TerminateAbility()
77 {
78     std::shared_ptr<AbilityInfo> info = GetAbilityInfo();
79     if (info == nullptr) {
80         TAG_LOGE(AAFwkTag::CONTEXT, "null info");
81         return ERR_NULL_OBJECT;
82     }
83 
84     ErrCode err = ERR_OK;
85     switch (info->type) {
86         case AppExecFwk::AbilityType::PAGE:
87             TAG_LOGD(AAFwkTag::CONTEXT, "type: page, ability: %{public}s", info->name.c_str());
88             if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
89                 auto sessionToken = GetSessionToken();
90                 if (sessionToken == nullptr) {
91                     TAG_LOGE(AAFwkTag::CONTEXT, "null sessionToken");
92                     return ERR_INVALID_VALUE;
93                 }
94                 sptr<AAFwk::SessionInfo> sessionInfo = new AAFwk::SessionInfo();
95                 sessionInfo->want = resultWant_;
96                 sessionInfo->resultCode = resultCode_;
97                 TAG_LOGI(AAFwkTag::CONTEXT, "resultCode: %{public}d", sessionInfo->resultCode);
98                 auto ifaceSessionToken = iface_cast<Rosen::ISession>(sessionToken);
99                 auto err = ifaceSessionToken->TerminateSession(sessionInfo);
100                 TAG_LOGI(AAFwkTag::CONTEXT, "ret: %{public}d", err);
101                 return static_cast<int32_t>(err);
102             } else {
103                 err = AAFwk::AbilityManagerClient::GetInstance()->TerminateAbility(token_, resultCode_, &resultWant_);
104             }
105             break;
106         case AppExecFwk::AbilityType::SERVICE:
107             TAG_LOGD(AAFwkTag::CONTEXT, "service type, ability: %{public}s", info->name.c_str());
108             err = AAFwk::AbilityManagerClient::GetInstance()->TerminateAbility(token_, -1, nullptr);
109             break;
110         default:
111             TAG_LOGE(AAFwkTag::CONTEXT, "error type: %{public}d", info->type);
112             break;
113     }
114 
115     if (err != ERR_OK) {
116         TAG_LOGE(AAFwkTag::CONTEXT, "failed %{public}d", err);
117     }
118     return err;
119 }
120 
GetCallingBundle()121 std::string AbilityContext::GetCallingBundle()
122 {
123     return callingBundleName_;
124 }
125 
GetElementName()126 std::shared_ptr<ElementName> AbilityContext::GetElementName()
127 {
128     TAG_LOGD(AAFwkTag::CONTEXT, "called");
129     std::shared_ptr<AbilityInfo> info = GetAbilityInfo();
130     if (info == nullptr) {
131         TAG_LOGE(AAFwkTag::CONTEXT, "null info");
132         return nullptr;
133     }
134 
135     std::shared_ptr<ElementName> elementName = std::make_shared<ElementName>();
136     elementName->SetAbilityName(info->name);
137     elementName->SetBundleName(info->bundleName);
138     elementName->SetDeviceID(info->deviceId);
139     elementName->SetModuleName(info->moduleName);
140     TAG_LOGD(AAFwkTag::CONTEXT, "end");
141     return elementName;
142 }
143 
GetCallingAbility()144 std::shared_ptr<ElementName> AbilityContext::GetCallingAbility()
145 {
146     TAG_LOGD(AAFwkTag::CONTEXT, "called");
147     std::shared_ptr<ElementName> elementName = std::make_shared<ElementName>();
148     elementName->SetAbilityName(callingAbilityName_);
149     elementName->SetBundleName(callingBundleName_);
150     elementName->SetDeviceID(callingDeviceId_);
151     elementName->SetModuleName(callingModuleName_);
152     TAG_LOGD(AAFwkTag::CONTEXT, "end");
153     return elementName;
154 }
155 
ConnectAbility(const Want & want,const sptr<AAFwk::IAbilityConnection> & conn)156 bool AbilityContext::ConnectAbility(const Want &want, const sptr<AAFwk::IAbilityConnection> &conn)
157 {
158     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
159     AppExecFwk::AbilityType type = GetAbilityInfoType();
160 
161     std::shared_ptr<AbilityInfo> abilityInfo = GetAbilityInfo();
162     if (abilityInfo == nullptr) {
163         TAG_LOGE(AAFwkTag::CONTEXT, "null info");
164         return false;
165     }
166 
167     TAG_LOGD(AAFwkTag::CONTEXT, "ability:%{public}s", abilityInfo->name.c_str());
168 
169     if (type != AppExecFwk::AbilityType::PAGE && type != AppExecFwk::AbilityType::SERVICE) {
170         TAG_LOGE(AAFwkTag::CONTEXT, "abilityType: %{public}d", type);
171         return false;
172     }
173 
174     ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, conn, token_);
175     TAG_LOGD(AAFwkTag::CONTEXT, "ret=%{public}d", ret);
176     bool value = ((ret == ERR_OK) ? true : false);
177     if (!value) {
178         TAG_LOGE(AAFwkTag::CONTEXT, "errorCode: %{public}d", ret);
179     }
180     TAG_LOGD(AAFwkTag::CONTEXT, "end");
181     return value;
182 }
183 
DisconnectAbility(const sptr<AAFwk::IAbilityConnection> & conn)184 ErrCode AbilityContext::DisconnectAbility(const sptr<AAFwk::IAbilityConnection> &conn)
185 {
186     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
187     std::shared_ptr<AbilityInfo> info = GetAbilityInfo();
188     TAG_LOGI(AAFwkTag::CONTEXT, "caller:%{public}s",
189         info == nullptr ? "" : info->name.c_str());
190 
191     AppExecFwk::AbilityType type = GetAbilityInfoType();
192     if (type != AppExecFwk::AbilityType::PAGE && type != AppExecFwk::AbilityType::SERVICE) {
193         TAG_LOGE(AAFwkTag::CONTEXT, "abilityType:%{public}d", type);
194         return ERR_INVALID_VALUE;
195     }
196 
197     ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(conn);
198     if (ret != ERR_OK) {
199         TAG_LOGE(AAFwkTag::CONTEXT, "error, ret:%{public}d", ret);
200     }
201     return ret;
202 }
203 
StopAbility(const AAFwk::Want & want)204 bool AbilityContext::StopAbility(const AAFwk::Want &want)
205 {
206     TAG_LOGD(AAFwkTag::CONTEXT, "called");
207     AppExecFwk::AbilityType type = GetAbilityInfoType();
208     if (type != AppExecFwk::AbilityType::PAGE && type != AppExecFwk::AbilityType::SERVICE) {
209         TAG_LOGE(AAFwkTag::CONTEXT, "abilityType: %{public}d", type);
210         return false;
211     }
212 
213     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StopServiceAbility(want, token_);
214     if (err != ERR_OK) {
215         TAG_LOGE(AAFwkTag::CONTEXT, "failed %{public}d", err);
216         return false;
217     }
218 
219     return true;
220 }
221 
GetToken()222 sptr<IRemoteObject> AbilityContext::GetToken()
223 {
224     return token_;
225 }
226 
GetAbilityInfoType()227 AppExecFwk::AbilityType AbilityContext::GetAbilityInfoType()
228 {
229     std::shared_ptr<AbilityInfo> info = GetAbilityInfo();
230     if (info == nullptr) {
231         TAG_LOGE(AAFwkTag::CONTEXT, "null info");
232         return AppExecFwk::AbilityType::UNKNOWN;
233     }
234 
235     return info->type;
236 }
237 
GetResourceManager() const238 std::shared_ptr<Global::Resource::ResourceManager> AbilityContext::GetResourceManager() const
239 {
240     std::shared_ptr<Context> appContext = GetApplicationContext();
241     if (appContext == nullptr) {
242         TAG_LOGE(AAFwkTag::CONTEXT, "null appContext");
243         return nullptr;
244     }
245 
246     TAG_LOGD(AAFwkTag::CONTEXT, "before getResourceManager");
247     std::shared_ptr<Global::Resource::ResourceManager> resourceManager = appContext->GetResourceManager();
248     TAG_LOGD(AAFwkTag::CONTEXT, "after getResourceManager");
249     if (resourceManager == nullptr) {
250         TAG_LOGE(AAFwkTag::CONTEXT, "null resourceManager");
251         return nullptr;
252     }
253     return resourceManager;
254 }
255 
VerifyPermission(const std::string & permission,int pid,int uid)256 int AbilityContext::VerifyPermission(const std::string &permission, int pid, int uid)
257 {
258     TAG_LOGI(AAFwkTag::CONTEXT, "permission=%{public}s, pid=%{public}d, uid=%{public}d",
259         permission.c_str(),
260         pid,
261         uid);
262     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->VerifyPermission(permission, pid, uid);
263     TAG_LOGD(AAFwkTag::CONTEXT, "ret=%{public}d", err);
264     if (err != ERR_OK) {
265         return AppExecFwk::Constants::PERMISSION_NOT_GRANTED;
266     }
267     return 0;
268 }
269 
GetPermissionDes(const std::string & permissionName,std::string & des)270 void AbilityContext::GetPermissionDes(const std::string &permissionName, std::string &des)
271 {
272     Security::AccessToken::PermissionDef permissionDef;
273     int32_t ret = Security::AccessToken::AccessTokenKit::GetDefPermission(permissionName, permissionDef);
274     if (ret == Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
275         TAG_LOGD(AAFwkTag::CONTEXT, "%{public}s: RET_SUCCESS", permissionName.c_str());
276         des = permissionDef.description;
277     }
278     TAG_LOGD(AAFwkTag::CONTEXT, "end");
279 }
280 
RequestPermissionsFromUser(std::vector<std::string> & permissions,std::vector<int> & permissionsState,PermissionRequestTask && task)281 void AbilityContext::RequestPermissionsFromUser(std::vector<std::string> &permissions,
282     std::vector<int> &permissionsState, PermissionRequestTask &&task)
283 {
284     TAG_LOGD(AAFwkTag::CONTEXT, "called");
285     if (permissions.size() == 0) {
286         TAG_LOGE(AAFwkTag::CONTEXT, "empty permissions");
287         return;
288     }
289 
290     AAFwk::Want want;
291     want.SetElementName(GRANT_ABILITY_BUNDLE_NAME, GRANT_ABILITY_ABILITY_NAME);
292     want.SetParam(PERMISSION_KEY, permissions);
293     want.SetParam(STATE_KEY, permissionsState);
294     want.SetParam(TOKEN_KEY, token_);
295     sptr<IRemoteObject> remoteObject = new AbilityRuntime::AuthorizationResult(std::move(task));
296     want.SetParam(CALLBACK_KEY, remoteObject);
297     StartAbility(want, -1);
298     TAG_LOGD(AAFwkTag::CONTEXT, "end");
299 }
300 
SetCallingContext(const std::string & deviceId,const std::string & bundleName,const std::string & abilityName,const std::string & moduleName)301 void AbilityContext::SetCallingContext(const std::string &deviceId, const std::string &bundleName,
302     const std::string &abilityName, const std::string &moduleName)
303 {
304     callingDeviceId_ = deviceId;
305     callingBundleName_ = bundleName;
306     callingAbilityName_ = abilityName;
307     callingModuleName_ = moduleName;
308 }
309 
StartAbilities(const std::vector<AAFwk::Want> & wants)310 void AbilityContext::StartAbilities(const std::vector<AAFwk::Want> &wants)
311 {
312     for (auto want : wants) {
313         StartAbility(want, ABILITY_CONTEXT_DEFAULT_REQUEST_CODE);
314     }
315     TAG_LOGD(AAFwkTag::CONTEXT, "end");
316 }
317 
GetSessionToken()318 sptr<IRemoteObject> AbilityContext::GetSessionToken()
319 {
320     std::lock_guard lock(sessionTokenMutex_);
321     return sessionToken_;
322 }
323 
AddFreeInstallObserver(const sptr<AbilityRuntime::IFreeInstallObserver> & observer)324 int32_t AbilityContext::AddFreeInstallObserver(const sptr<AbilityRuntime::IFreeInstallObserver> &observer)
325 {
326     ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->AddFreeInstallObserver(token_, observer);
327     if (ret != ERR_OK) {
328         TAG_LOGE(AAFwkTag::CONTEXT, "add observer failed, ret: %{public}d", ret);
329     }
330     return ret;
331 }
332 }  // namespace AppExecFwk
333 }  // namespace OHOS
334