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 ¶m, 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