• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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_process.h"
17 
18 #include <dlfcn.h>
19 
20 #include "accesstoken_kit.h"
21 #include "hilog_wrapper.h"
22 #include "permission_list_state.h"
23 
24 using OHOS::Security::AccessToken::AccessTokenKit;
25 using OHOS::Security::AccessToken::PermissionListState;
26 using OHOS::Security::AccessToken::TypePermissionOper;
27 
28 namespace OHOS {
29 namespace AppExecFwk {
30 static void *g_handle = nullptr;
31 #ifdef SUPPORT_GRAPHICS
32 #ifdef APP_USE_ARM
33 constexpr char SHARED_LIBRARY_FEATURE_ABILITY[] = "/system/lib/module/ability/libfeatureability.z.so";
34 #else
35 constexpr char SHARED_LIBRARY_FEATURE_ABILITY[] = "/system/lib64/module/ability/libfeatureability.z.so";
36 #endif
37 #endif
38 constexpr char FUNC_CALL_ON_ABILITY_RESULT[] = "CallOnAbilityResult";
39 using NAPICallOnAbilityResult = void (*)(int requestCode, int resultCode, const Want &resultData, CallbackInfo cb);
40 constexpr char FUNC_CALL_ON_REQUEST_PERMISSIONS_FROM_USERRESULT[] = "CallOnRequestPermissionsFromUserResult";
41 using NAPICallOnRequestPermissionsFromUserResult = void (*)(int requestCode,
42     const std::vector<std::string> &permissions, const std::vector<int> &grantResults, CallbackInfo callbackInfo);
43 
44 std::shared_ptr<AbilityProcess> AbilityProcess::instance_ = nullptr;
45 std::map<Ability *, std::map<int, CallbackInfo>> AbilityProcess::abilityResultMap_;
46 std::mutex AbilityProcess::mutex_;
GetInstance()47 std::shared_ptr<AbilityProcess> AbilityProcess::GetInstance()
48 {
49     if (instance_ == nullptr) {
50         std::lock_guard<std::mutex> lock_l(mutex_);
51         if (instance_ == nullptr) {
52             instance_ = std::make_shared<AbilityProcess>();
53         }
54     }
55     return instance_;
56 }
57 
AbilityProcess()58 AbilityProcess::AbilityProcess()
59 {}
60 
~AbilityProcess()61 AbilityProcess::~AbilityProcess()
62 {}
63 
StartAbility(Ability * ability,CallAbilityParam param,CallbackInfo callback)64 ErrCode AbilityProcess::StartAbility(Ability *ability, CallAbilityParam param, CallbackInfo callback)
65 {
66     HILOG_DEBUG("begin");
67     if (ability == nullptr) {
68         HILOG_ERROR("ability is nullptr");
69         return ERR_NULL_OBJECT;
70     }
71 #ifdef SUPPORT_GRAPHICS
72     // inherit split mode
73     auto windowMode = ability->GetCurrentWindowMode();
74     if (windowMode == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_PRIMARY ||
75         windowMode == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_SECONDARY) {
76         param.want.SetParam(Want::PARAM_RESV_WINDOW_MODE, windowMode);
77     }
78     HILOG_INFO("window mode is %{public}d", windowMode);
79 #endif
80     ErrCode err = ERR_OK;
81     if (param.forResultOption == true) {
82         if (param.setting == nullptr) {
83             HILOG_INFO("param.setting == nullptr call StartAbilityForResult.");
84             param.want.SetParam(Want::PARAM_RESV_FOR_RESULT, true);
85             err = ability->StartAbilityForResult(param.want, param.requestCode);
86         } else {
87             HILOG_INFO("param.setting != nullptr call StartAbilityForResult.");
88             err = ability->StartAbilityForResult(param.want, param.requestCode, *(param.setting));
89         }
90 
91         std::lock_guard<std::mutex> lock_l(mutex_);
92 
93         std::map<int, CallbackInfo> map;
94         auto it = abilityResultMap_.find(ability);
95         if (it == abilityResultMap_.end()) {
96             HILOG_INFO("ability is not in the abilityResultMap_");
97         } else {
98             HILOG_INFO("ability is in the abilityResultMap_");
99             map = it->second;
100         }
101         callback.errCode = err;
102         map[param.requestCode] = callback;
103         abilityResultMap_[ability] = map;
104     } else {
105         if (param.setting == nullptr) {
106             HILOG_INFO("param.setting == nullptr call StartAbility.");
107             err = ability->StartAbility(param.want);
108         } else {
109             HILOG_INFO("param.setting != nullptr call StartAbility.");
110             err = ability->StartAbility(param.want, *(param.setting));
111         }
112     }
113     HILOG_DEBUG("end");
114     return err;
115 }
116 
AddAbilityResultCallback(Ability * ability,CallAbilityParam & param,int32_t errCode,CallbackInfo & callback)117 void AbilityProcess::AddAbilityResultCallback(Ability *ability, CallAbilityParam &param, int32_t errCode,
118                                               CallbackInfo &callback)
119 {
120     std::lock_guard<std::mutex> lock(mutex_);
121 
122     std::map<int, CallbackInfo> map;
123     auto it = abilityResultMap_.find(ability);
124     if (it == abilityResultMap_.end()) {
125         HILOG_INFO("ability is not in the abilityResultMap_");
126     } else {
127         HILOG_INFO("ability is in the abilityResultMap_");
128         map = it->second;
129     }
130     callback.errCode = errCode;
131     map[param.requestCode] = callback;
132     abilityResultMap_[ability] = map;
133 }
134 
OnAbilityResult(Ability * ability,int requestCode,int resultCode,const Want & resultData)135 void AbilityProcess::OnAbilityResult(Ability *ability, int requestCode, int resultCode, const Want &resultData)
136 {
137     HILOG_DEBUG("begin");
138 
139     std::lock_guard<std::mutex> lock_l(mutex_);
140 
141     auto it = abilityResultMap_.find(ability);
142     if (it == abilityResultMap_.end()) {
143         HILOG_ERROR("ability is not in the abilityResultMap");
144         return;
145     }
146     std::map<int, CallbackInfo> map = it->second;
147 
148     auto callback = map.find(requestCode);
149     if (callback == map.end()) {
150         HILOG_ERROR("requestCode: %{public}d is not in the map", requestCode);
151         return;
152     }
153     CallbackInfo callbackInfo = callback->second;
154 #ifdef SUPPORT_GRAPHICS
155     // start open featureability lib
156     if (g_handle == nullptr) {
157         g_handle = dlopen(SHARED_LIBRARY_FEATURE_ABILITY, RTLD_LAZY);
158         if (g_handle == nullptr) {
159             HILOG_ERROR("dlopen failed %{public}s. %{public}s",
160                 SHARED_LIBRARY_FEATURE_ABILITY,
161                 dlerror());
162             return;
163         }
164     }
165 #endif
166     // get function
167     auto func = reinterpret_cast<NAPICallOnAbilityResult>(dlsym(g_handle, FUNC_CALL_ON_ABILITY_RESULT));
168     if (func == nullptr) {
169         HILOG_ERROR("dlsym failed %{public}s. %{public}s", FUNC_CALL_ON_ABILITY_RESULT, dlerror());
170         dlclose(g_handle);
171         g_handle = nullptr;
172         return;
173     }
174     func(requestCode, resultCode, resultData, callbackInfo);
175 
176     map.erase(requestCode);
177 
178     abilityResultMap_[ability] = map;
179     HILOG_DEBUG("end");
180 }
181 
RequestPermissionsFromUser(Ability * ability,CallAbilityPermissionParam & param,CallbackInfo callbackInfo)182 void AbilityProcess::RequestPermissionsFromUser(
183     Ability *ability, CallAbilityPermissionParam &param, CallbackInfo callbackInfo)
184 {
185     HILOG_DEBUG("begin");
186     if (ability == nullptr) {
187         HILOG_ERROR("ability is nullptr");
188         return;
189     }
190 
191     std::vector<PermissionListState> permList;
192     for (auto permission : param.permission_list) {
193         HILOG_DEBUG("permission: %{public}s.", permission.c_str());
194         PermissionListState permState;
195         permState.permissionName = permission;
196         permState.state = -1;
197         permList.emplace_back(permState);
198     }
199     HILOG_DEBUG("permList size: %{public}zu, permissions size: %{public}zu.",
200         permList.size(), param.permission_list.size());
201 
202     auto ret = AccessTokenKit::GetSelfPermissionsState(permList);
203     if (permList.size() != param.permission_list.size()) {
204         HILOG_ERROR("Returned permList size: %{public}zu.", permList.size());
205         return;
206     }
207 
208     std::vector<int> permissionsState;
209     for (auto permState : permList) {
210         HILOG_DEBUG("permissions: %{public}s. permissionsState: %{public}u",
211             permState.permissionName.c_str(), permState.state);
212         permissionsState.emplace_back(permState.state);
213     }
214     HILOG_DEBUG("permissions size: %{public}zu. permissionsState size: %{public}zu",
215         param.permission_list.size(), permissionsState.size());
216 
217     auto requestCode = param.requestCode;
218     if (ret != TypePermissionOper::DYNAMIC_OPER) {
219         HILOG_DEBUG("No dynamic popup required.");
220         (void)CaullFunc(requestCode, param.permission_list, permissionsState, callbackInfo);
221         return;
222     }
223 
224     auto task = [self = GetInstance(), requestCode, callbackInfo]
225         (const std::vector<std::string> &permissions, const std::vector<int> &grantResults) mutable {
226         if (!self) {
227             HILOG_ERROR("self is nullptr.");
228             return;
229         }
230         if (!self->CaullFunc(requestCode, permissions, grantResults, callbackInfo)) {
231             HILOG_ERROR("call function failed.");
232             return;
233         }
234     };
235 
236     ability->RequestPermissionsFromUser(param.permission_list, permissionsState, std::move(task));
237 }
238 
CaullFunc(int requestCode,const std::vector<std::string> & permissions,const std::vector<int> & permissionsState,CallbackInfo & callbackInfo)239 bool AbilityProcess::CaullFunc(int requestCode, const std::vector<std::string> &permissions,
240     const std::vector<int> &permissionsState, CallbackInfo &callbackInfo)
241 {
242 #ifdef SUPPORT_GRAPHICS
243     // start open featureability lib
244     if (g_handle == nullptr) {
245         g_handle = dlopen(SHARED_LIBRARY_FEATURE_ABILITY, RTLD_LAZY);
246         if (g_handle == nullptr) {
247             HILOG_ERROR("dlopen failed %{public}s. %{public}s",
248                 SHARED_LIBRARY_FEATURE_ABILITY, dlerror());
249             return false;
250         }
251     }
252 #endif
253     // get function
254     auto func = reinterpret_cast<NAPICallOnRequestPermissionsFromUserResult>(
255         dlsym(g_handle, FUNC_CALL_ON_REQUEST_PERMISSIONS_FROM_USERRESULT));
256     if (func == nullptr) {
257         HILOG_ERROR("dlsym failed %{public}s. %{public}s",
258             FUNC_CALL_ON_REQUEST_PERMISSIONS_FROM_USERRESULT, dlerror());
259         dlclose(g_handle);
260         g_handle = nullptr;
261         return false;
262     }
263     func(requestCode, permissions, permissionsState, callbackInfo);
264     return true;
265 }
266 }  // namespace AppExecFwk
267 }  // namespace OHOS
268