• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 
16 #include "ability_process.h"
17 #include "app_log_wrapper.h"
18 #include <dlfcn.h>
19 namespace OHOS {
20 namespace AppExecFwk {
21 static void *g_handle = nullptr;
22 constexpr char SHARED_LIBRARY_FEATURE_ABILITY[] = "/system/lib/module/ability/libfeatureability.z.so";
23 constexpr char FUNC_CALL_ON_ABILITY_RESULT[] = "CallOnAbilityResult";
24 using NAPICallOnAbilityResult = void (*)(int requestCode, int resultCode, const Want &resultData, CallbackInfo cb);
25 constexpr char FUNC_CALL_ON_REQUEST_PERMISSIONS_FROM_USERRESULT[] = "CallOnRequestPermissionsFromUserResult";
26 using NAPICallOnRequestPermissionsFromUserResult = void (*)(int requestCode,
27     const std::vector<std::string> &permissions, const std::vector<int> &grantResults, CallbackInfo callbackInfo);
28 
29 std::shared_ptr<AbilityProcess> AbilityProcess::instance_ = nullptr;
30 std::map<Ability *, std::map<int, CallbackInfo>> AbilityProcess::abilityResultMap_;
31 std::map<Ability *, std::map<int, CallbackInfo>> AbilityProcess::abilityRequestPermissionsForUserMap_;
32 std::mutex AbilityProcess::mutex_;
GetInstance()33 std::shared_ptr<AbilityProcess> AbilityProcess::GetInstance()
34 {
35     if (instance_ == nullptr) {
36         std::lock_guard<std::mutex> lock_l(mutex_);
37         if (instance_ == nullptr) {
38             instance_ = std::make_shared<AbilityProcess>();
39         }
40     }
41     return instance_;
42 }
43 
AbilityProcess()44 AbilityProcess::AbilityProcess()
45 {}
46 
~AbilityProcess()47 AbilityProcess::~AbilityProcess()
48 {}
49 
StartAbility(Ability * ability,CallAbilityParam param,CallbackInfo callback)50 void AbilityProcess::StartAbility(Ability *ability, CallAbilityParam param, CallbackInfo callback)
51 {
52     APP_LOGI("AbilityProcess::StartAbility begin");
53     if (ability == nullptr) {
54         APP_LOGE("AbilityProcess::StartAbility ability is nullptr");
55         return;
56     }
57 
58     if (param.forResultOption == true) {
59         if (param.setting == nullptr) {
60             APP_LOGI("%{public}s param.setting == nullptr call StartAbilityForResult.", __func__);
61             ability->StartAbilityForResult(param.want, param.requestCode);
62         } else {
63             APP_LOGI("%{public}s param.setting != nullptr call StartAbilityForResult.", __func__);
64             ability->StartAbilityForResult(param.want, param.requestCode, *(param.setting));
65         }
66 
67         std::lock_guard<std::mutex> lock_l(mutex_);
68 
69         std::map<int, CallbackInfo> map;
70         auto it = abilityResultMap_.find(ability);
71         if (it == abilityResultMap_.end()) {
72             APP_LOGI("AbilityProcess::StartAbility ability: %{public}p is not in the abilityResultMap_", ability);
73         } else {
74             APP_LOGI("AbilityProcess::StartAbility ability: %{public}p is in the abilityResultMap_", ability);
75             map = it->second;
76         }
77 
78         map[param.requestCode] = callback;
79         abilityResultMap_[ability] = map;
80     } else {
81         if (param.setting == nullptr) {
82             APP_LOGI("%{public}s param.setting == nullptr call StartAbility.", __func__);
83             ability->StartAbility(param.want);
84         } else {
85             APP_LOGI("%{public}s param.setting != nullptr call StartAbility.", __func__);
86             ability->StartAbility(param.want, *(param.setting));
87         }
88     }
89     APP_LOGI("AbilityProcess::StartAbility end");
90 }
91 
OnAbilityResult(Ability * ability,int requestCode,int resultCode,const Want & resultData)92 void AbilityProcess::OnAbilityResult(Ability *ability, int requestCode, int resultCode, const Want &resultData)
93 {
94     APP_LOGI("AbilityProcess::OnAbilityResult begin");
95 
96     std::lock_guard<std::mutex> lock_l(mutex_);
97 
98     auto it = abilityResultMap_.find(ability);
99     if (it == abilityResultMap_.end()) {
100         APP_LOGE("AbilityProcess::OnAbilityResult ability: %{public}p is not in the abilityResultMap", ability);
101         return;
102     }
103     std::map<int, CallbackInfo> map = it->second;
104 
105     auto callback = map.find(requestCode);
106     if (callback == map.end()) {
107         APP_LOGE("AbilityProcess::OnAbilityResult requestCode: %{public}d is not in the map", requestCode);
108         return;
109     }
110     CallbackInfo callbackInfo = callback->second;
111 
112     // start open featureability lib
113     if (g_handle == nullptr) {
114         g_handle = dlopen(SHARED_LIBRARY_FEATURE_ABILITY, RTLD_LAZY);
115         if (g_handle == nullptr) {
116             APP_LOGE("%{public}s, dlopen failed %{public}s. %{public}s",
117                 __func__,
118                 SHARED_LIBRARY_FEATURE_ABILITY,
119                 dlerror());
120             return;
121         }
122     }
123 
124     // get function
125     auto func = reinterpret_cast<NAPICallOnAbilityResult>(dlsym(g_handle, FUNC_CALL_ON_ABILITY_RESULT));
126     if (func == nullptr) {
127         APP_LOGE("%{public}s, dlsym failed %{public}s. %{public}s", __func__, FUNC_CALL_ON_ABILITY_RESULT, dlerror());
128         dlclose(g_handle);
129         g_handle = nullptr;
130         return;
131     }
132     func(requestCode, resultCode, resultData, callbackInfo);
133 
134     map.erase(requestCode);
135 
136     abilityResultMap_[ability] = map;
137     APP_LOGI("AbilityProcess::OnAbilityResult end");
138 }
139 
RequestPermissionsFromUser(Ability * ability,CallAbilityPermissionParam & param,CallbackInfo callbackInfo)140 void AbilityProcess::RequestPermissionsFromUser(
141     Ability *ability, CallAbilityPermissionParam &param, CallbackInfo callbackInfo)
142 {
143     APP_LOGI("AbilityProcess::RequestPermissionsFromUser begin");
144     if (ability == nullptr) {
145         APP_LOGE("AbilityProcess::RequestPermissionsFromUser ability is nullptr");
146         return;
147     }
148 
149     ability->RequestPermissionsFromUser(param.permission_list, param.requestCode);
150 
151     {
152         std::lock_guard<std::mutex> lock_l(mutex_);
153         std::map<int, CallbackInfo> map;
154         auto it = abilityRequestPermissionsForUserMap_.find(ability);
155         if (it == abilityRequestPermissionsForUserMap_.end()) {
156             APP_LOGI("AbilityProcess::RequestPermissionsFromUser ability: %{public}p is not in the "
157                      "abilityRequestPermissionsForUserMap_",
158                 ability);
159         } else {
160             APP_LOGI("AbilityProcess::RequestPermissionsFromUser ability: %{public}p is in the "
161                      "abilityRequestPermissionsForUserMap_",
162                 ability);
163             map = it->second;
164         }
165 
166         map[param.requestCode] = callbackInfo;
167         abilityRequestPermissionsForUserMap_[ability] = map;
168     }
169     APP_LOGI("AbilityProcess::RequestPermissionsFromUser end");
170 }
171 
OnRequestPermissionsFromUserResult(Ability * ability,int requestCode,const std::vector<std::string> & permissions,const std::vector<int> & grantResults)172 void AbilityProcess::OnRequestPermissionsFromUserResult(Ability *ability, int requestCode,
173     const std::vector<std::string> &permissions, const std::vector<int> &grantResults)
174 {
175     APP_LOGI("AbilityProcess::OnRequestPermissionsFromUserResult begin");
176     if (ability == nullptr) {
177         APP_LOGE("AbilityProcess::OnRequestPermissionsFromUserResult ability is nullptr");
178         return;
179     }
180 
181     std::lock_guard<std::mutex> lock_l(mutex_);
182 
183     auto it = abilityRequestPermissionsForUserMap_.find(ability);
184     if (it == abilityRequestPermissionsForUserMap_.end()) {
185         APP_LOGE("AbilityProcess::OnRequestPermissionsFromUserResult ability: %{public}p is not in the "
186                  "abilityRequestPermissionsForUserMap_",
187             ability);
188         return;
189     }
190     std::map<int, CallbackInfo> map = it->second;
191 
192     auto callback = map.find(requestCode);
193     if (callback == map.end()) {
194         APP_LOGE("AbilityProcess::OnRequestPermissionsFromUserResult requestCode: %{public}d is not in the map",
195             requestCode);
196         return;
197     }
198     CallbackInfo callbackInfo = callback->second;
199 
200     // start open featureability lib
201     if (g_handle == nullptr) {
202         g_handle = dlopen(SHARED_LIBRARY_FEATURE_ABILITY, RTLD_LAZY);
203         if (g_handle == nullptr) {
204             APP_LOGE("%{public}s, dlopen failed %{public}s. %{public}s",
205                 __func__,
206                 SHARED_LIBRARY_FEATURE_ABILITY,
207                 dlerror());
208             return;
209         }
210     }
211 
212     // get function
213     auto func = reinterpret_cast<NAPICallOnRequestPermissionsFromUserResult>(
214         dlsym(g_handle, FUNC_CALL_ON_REQUEST_PERMISSIONS_FROM_USERRESULT));
215     if (func == nullptr) {
216         APP_LOGE("%{public}s, dlsym failed %{public}s. %{public}s",
217             __func__,
218             FUNC_CALL_ON_REQUEST_PERMISSIONS_FROM_USERRESULT,
219             dlerror());
220         dlclose(g_handle);
221         g_handle = nullptr;
222         return;
223     }
224     func(requestCode, permissions, grantResults, callbackInfo);
225     map.erase(requestCode);
226 
227     abilityRequestPermissionsForUserMap_[ability] = map;
228     APP_LOGI("AbilityProcess::OnRequestPermissionsFromUserResult end");
229 }
230 }  // namespace AppExecFwk
231 }  // namespace OHOS