1 /*
2 * Copyright (c) 2023-2025 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 "ui_extension_context.h"
17
18 #include "ability_manager_client.h"
19 #include "bool_wrapper.h"
20 #include "connection_manager.h"
21 #include "hilog_tag_wrapper.h"
22 #include "hitrace_meter.h"
23 #include "configuration_convertor.h"
24 #include "configuration.h"
25 #include "ui_content.h"
26
27 namespace OHOS {
28 namespace AbilityRuntime {
29 const size_t UIExtensionContext::CONTEXT_TYPE_ID(std::hash<const char*> {} ("UIExtensionContext"));
30 int UIExtensionContext::ILLEGAL_REQUEST_CODE(-1);
31 constexpr const char* REQUEST_COMPONENT_TERMINATE_KEY = "ohos.param.key.requestComponentTerminate";
32 constexpr const char* UIEXTENSION_TARGET_TYPE_KEY = "ability.want.params.uiExtensionTargetType";
33 constexpr const char* FLAG_AUTH_READ_URI_PERMISSION = "ability.want.params.uriPermissionFlag";
34
StartAbility(const AAFwk::Want & want) const35 ErrCode UIExtensionContext::StartAbility(const AAFwk::Want &want) const
36 {
37 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
38 TAG_LOGD(AAFwkTag::UI_EXT, "begin, ability:%{public}s", want.GetElement().GetAbilityName().c_str());
39 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, token_, ILLEGAL_REQUEST_CODE);
40 if (err != ERR_OK) {
41 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
42 }
43 return err;
44 }
45
StartAbility(const AAFwk::Want & want,int requestCode) const46 ErrCode UIExtensionContext::StartAbility(const AAFwk::Want &want, int requestCode) const
47 {
48 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
49 TAG_LOGD(AAFwkTag::UI_EXT, "begin, requestCode:%{public}d", requestCode);
50 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, token_, requestCode);
51 if (err != ERR_OK) {
52 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
53 }
54 return err;
55 }
56
StartAbility(const AAFwk::Want & want,const AAFwk::StartOptions & startOptions) const57 ErrCode UIExtensionContext::StartAbility(const AAFwk::Want &want, const AAFwk::StartOptions &startOptions) const
58 {
59 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
60 TAG_LOGD(AAFwkTag::UI_EXT, "begin, ability:%{public}s", want.GetElement().GetAbilityName().c_str());
61 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, startOptions, token_,
62 ILLEGAL_REQUEST_CODE);
63 if (err != ERR_OK) {
64 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
65 }
66 return err;
67 }
68
StartUIServiceExtension(const AAFwk::Want & want,int32_t accountId) const69 ErrCode UIExtensionContext::StartUIServiceExtension(const AAFwk::Want& want, int32_t accountId) const
70 {
71 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
72 TAG_LOGD(AAFwkTag::UI_EXT, "Start UIServiceExtension begin");
73 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartExtensionAbility(
74 want, token_, accountId, AppExecFwk::ExtensionAbilityType::UI_SERVICE);
75 if (err != ERR_OK) {
76 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
77 }
78 return err;
79 }
80
TerminateSelf()81 ErrCode UIExtensionContext::TerminateSelf()
82 {
83 TAG_LOGD(AAFwkTag::UI_EXT, "begin");
84 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->TerminateAbility(token_, -1, nullptr);
85 if (err != ERR_OK) {
86 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
87 }
88 TAG_LOGD(AAFwkTag::UI_EXT, "TerminateSelf end");
89 return err;
90 }
91
ConnectAbility(const AAFwk::Want & want,const sptr<AbilityConnectCallback> & connectCallback) const92 ErrCode UIExtensionContext::ConnectAbility(
93 const AAFwk::Want &want, const sptr<AbilityConnectCallback> &connectCallback) const
94 {
95 TAG_LOGD(AAFwkTag::UI_EXT, "begin, ability:%{public}s",
96 want.GetElement().GetAbilityName().c_str());
97 ErrCode ret =
98 ConnectionManager::GetInstance().ConnectAbility(token_, want, connectCallback);
99 TAG_LOGD(AAFwkTag::UI_EXT, "UIExtensionContext::ConnectAbility ErrorCode = %{public}d", ret);
100 return ret;
101 }
102
ConnectUIServiceExtensionAbility(const AAFwk::Want & want,const sptr<AbilityConnectCallback> & connectCallback) const103 ErrCode UIExtensionContext::ConnectUIServiceExtensionAbility(
104 const AAFwk::Want &want, const sptr<AbilityConnectCallback> &connectCallback) const
105 {
106 TAG_LOGD(AAFwkTag::UI_EXT, "begin, ability:%{public}s",
107 want.GetElement().GetAbilityName().c_str());
108 ErrCode ret =
109 ConnectionManager::GetInstance().ConnectUIServiceExtensionAbility(token_, want, connectCallback);
110 TAG_LOGD(AAFwkTag::UI_EXT, "UIExtensionContext::ConnectUIServiceExtensionAbility ErrorCode = %{public}d", ret);
111 return ret;
112 }
113
DisconnectAbility(const AAFwk::Want & want,const sptr<AbilityConnectCallback> & connectCallback) const114 ErrCode UIExtensionContext::DisconnectAbility(
115 const AAFwk::Want &want, const sptr<AbilityConnectCallback> &connectCallback) const
116 {
117 TAG_LOGD(AAFwkTag::UI_EXT, "begin");
118 ErrCode ret =
119 ConnectionManager::GetInstance().DisconnectAbility(token_, want, connectCallback);
120 if (ret != ERR_OK) {
121 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", ret);
122 }
123 TAG_LOGD(AAFwkTag::UI_EXT, "end");
124 return ret;
125 }
126
StartServiceExtensionAbility(const AAFwk::Want & want,int32_t accountId)127 ErrCode UIExtensionContext::StartServiceExtensionAbility(const AAFwk::Want& want, int32_t accountId)
128 {
129 TAG_LOGI(AAFwkTag::UI_EXT, "Start service extension %{public}s, accountId: %{public}d",
130 want.GetElement().GetURI().c_str(), accountId);
131 auto ret = AAFwk::AbilityManagerClient::GetInstance()->StartExtensionAbility(
132 want, token_, accountId, AppExecFwk::ExtensionAbilityType::SERVICE);
133 if (ret != ERR_OK) {
134 TAG_LOGE(AAFwkTag::UI_EXT, "Start service extension failed %{public}d", ret);
135 }
136 return ret;
137 }
138
StartUIAbilities(const std::vector<AAFwk::Want> & wantList,const std::string & requestKey)139 ErrCode UIExtensionContext::StartUIAbilities(const std::vector<AAFwk::Want> &wantList, const std::string &requestKey)
140 {
141 TAG_LOGD(AAFwkTag::UI_EXT, "call StartUIAbilities");
142 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilities(wantList, requestKey, token_);
143 return err;
144 }
145
StartAbilityForResult(const AAFwk::Want & want,int requestCode,RuntimeTask && task)146 ErrCode UIExtensionContext::StartAbilityForResult(const AAFwk::Want &want, int requestCode, RuntimeTask &&task)
147 {
148 TAG_LOGD(AAFwkTag::UI_EXT, "begin");
149 {
150 std::lock_guard<std::mutex> lock(mutexlock_);
151 resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
152 }
153 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, token_, requestCode);
154 if (err != ERR_OK) {
155 TAG_LOGE(AAFwkTag::UI_EXT, "ret=%{public}d", err);
156 OnAbilityResultInner(requestCode, err, want);
157 }
158 TAG_LOGD(AAFwkTag::UI_EXT, "end");
159 return err;
160 }
161
InsertResultCallbackTask(int requestCode,RuntimeTask && task)162 void UIExtensionContext::InsertResultCallbackTask(int requestCode, RuntimeTask &&task)
163 {
164 TAG_LOGD(AAFwkTag::UI_EXT, "called");
165 {
166 std::lock_guard<std::mutex> lock(mutexlock_);
167 resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
168 }
169 }
170
RemoveResultCallbackTask(int requestCode)171 void UIExtensionContext::RemoveResultCallbackTask(int requestCode)
172 {
173 TAG_LOGD(AAFwkTag::UI_EXT, "called");
174 {
175 std::lock_guard<std::mutex> lock(mutexlock_);
176 resultCallbacks_.erase(requestCode);
177 }
178 }
179
StartAbilityForResult(const AAFwk::Want & want,const AAFwk::StartOptions & startOptions,int requestCode,RuntimeTask && task)180 ErrCode UIExtensionContext::StartAbilityForResult(
181 const AAFwk::Want &want, const AAFwk::StartOptions &startOptions, int requestCode, RuntimeTask &&task)
182 {
183 TAG_LOGD(AAFwkTag::UI_EXT, "begin");
184 {
185 std::lock_guard<std::mutex> lock(mutexlock_);
186 resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
187 }
188 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, startOptions, token_, requestCode);
189 if (err != ERR_OK) {
190 TAG_LOGE(AAFwkTag::UI_EXT, "ret=%{public}d", err);
191 OnAbilityResultInner(requestCode, err, want);
192 }
193 TAG_LOGD(AAFwkTag::UI_EXT, "end");
194 return err;
195 }
196
StartAbilityForResultAsCaller(const AAFwk::Want & want,int requestCode,RuntimeTask && task)197 ErrCode UIExtensionContext::StartAbilityForResultAsCaller(const AAFwk::Want &want, int requestCode, RuntimeTask &&task)
198 {
199 TAG_LOGD(AAFwkTag::UI_EXT, "called");
200 {
201 std::lock_guard<std::mutex> lock(mutexlock_);
202 resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
203 }
204 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbilityForResultAsCaller(want, token_, requestCode);
205 if (err != ERR_OK) {
206 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
207 OnAbilityResultInner(requestCode, err, want);
208 }
209 TAG_LOGD(AAFwkTag::UI_EXT, "End");
210 return err;
211 }
212
StartAbilityForResultAsCaller(const AAFwk::Want & want,const AAFwk::StartOptions & startOptions,int requestCode,RuntimeTask && task)213 ErrCode UIExtensionContext::StartAbilityForResultAsCaller(
214 const AAFwk::Want &want, const AAFwk::StartOptions &startOptions, int requestCode, RuntimeTask &&task)
215 {
216 TAG_LOGD(AAFwkTag::UI_EXT, "called");
217 {
218 std::lock_guard<std::mutex> lock(mutexlock_);
219 resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
220 }
221 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbilityForResultAsCaller(
222 want, startOptions, token_, requestCode);
223 if (err != ERR_OK) {
224 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
225 OnAbilityResultInner(requestCode, err, want);
226 }
227 TAG_LOGD(AAFwkTag::UI_EXT, "End");
228 return err;
229 }
230
ReportDrawnCompleted()231 ErrCode UIExtensionContext::ReportDrawnCompleted()
232 {
233 TAG_LOGD(AAFwkTag::UI_EXT, "begin");
234 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->ReportDrawnCompleted(token_);
235 if (err != ERR_OK) {
236 TAG_LOGE(AAFwkTag::UI_EXT, "ret=%{public}d", err);
237 }
238 return err;
239 }
240
OnAbilityResult(int requestCode,int resultCode,const AAFwk::Want & resultData)241 void UIExtensionContext::OnAbilityResult(int requestCode, int resultCode, const AAFwk::Want &resultData)
242 {
243 TAG_LOGD(AAFwkTag::UI_EXT, "begin");
244 std::lock_guard<std::mutex> lock(mutexlock_);
245 auto callback = resultCallbacks_.find(requestCode);
246 if (callback != resultCallbacks_.end()) {
247 if (callback->second) {
248 callback->second(resultCode, resultData, false);
249 }
250 resultCallbacks_.erase(requestCode);
251 }
252 TAG_LOGD(AAFwkTag::UI_EXT, "end");
253 }
254
GetAbilityInfoType() const255 AppExecFwk::AbilityType UIExtensionContext::GetAbilityInfoType() const
256 {
257 std::shared_ptr<AppExecFwk::AbilityInfo> info = GetAbilityInfo();
258 if (info == nullptr) {
259 TAG_LOGW(AAFwkTag::UI_EXT, "null info");
260 return AppExecFwk::AbilityType::UNKNOWN;
261 }
262
263 return info->type;
264 }
265
OnAbilityResultInner(int requestCode,int resultCode,const AAFwk::Want & resultData)266 void UIExtensionContext::OnAbilityResultInner(int requestCode, int resultCode, const AAFwk::Want &resultData)
267 {
268 TAG_LOGD(AAFwkTag::UI_EXT, "begin");
269 std::lock_guard<std::mutex> lock(mutexlock_);
270 auto callback = resultCallbacks_.find(requestCode);
271 if (callback != resultCallbacks_.end()) {
272 if (callback->second) {
273 callback->second(resultCode, resultData, true);
274 }
275 resultCallbacks_.erase(requestCode);
276 }
277 TAG_LOGD(AAFwkTag::UI_EXT, "end");
278 }
279
GetScreenMode() const280 int32_t UIExtensionContext::GetScreenMode() const
281 {
282 return screenMode_;
283 }
284
SetScreenMode(int32_t screenMode)285 void UIExtensionContext::SetScreenMode(int32_t screenMode)
286 {
287 screenMode_ = screenMode;
288 }
289
GenerateCurRequestCode()290 int UIExtensionContext::GenerateCurRequestCode()
291 {
292 std::lock_guard lock(requestCodeMutex_);
293 curRequestCode_ = (curRequestCode_ == INT_MAX) ? 0 : (curRequestCode_ + 1);
294 return curRequestCode_;
295 }
296 #ifdef SUPPORT_SCREEN
SetWindow(sptr<Rosen::Window> window)297 void UIExtensionContext::SetWindow(sptr<Rosen::Window> window)
298 {
299 window_ = window;
300 }
GetWindow()301 sptr<Rosen::Window> UIExtensionContext::GetWindow()
302 {
303 return window_;
304 }
GetUIContent()305 Ace::UIContent* UIExtensionContext::GetUIContent()
306 {
307 TAG_LOGI(AAFwkTag::UI_EXT, "called");
308 if (window_ == nullptr) {
309 return nullptr;
310 }
311 return window_->GetUIContent();
312 }
313 #endif // SUPPORT_SCREEN
OpenAtomicService(AAFwk::Want & want,const AAFwk::StartOptions & options,int requestCode,RuntimeTask && task)314 ErrCode UIExtensionContext::OpenAtomicService(AAFwk::Want& want, const AAFwk::StartOptions &options, int requestCode,
315 RuntimeTask &&task)
316 {
317 TAG_LOGD(AAFwkTag::UI_EXT, "called");
318 resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
319 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->OpenAtomicService(want, options, token_, requestCode);
320 if (err != ERR_OK && err != AAFwk::START_ABILITY_WAITING) {
321 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
322 OnAbilityResultInner(requestCode, err, want);
323 }
324 return err;
325 }
326
AddFreeInstallObserver(const sptr<IFreeInstallObserver> & observer)327 ErrCode UIExtensionContext::AddFreeInstallObserver(const sptr<IFreeInstallObserver> &observer)
328 {
329 ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->AddFreeInstallObserver(token_, observer);
330 if (ret != ERR_OK) {
331 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", ret);
332 }
333 return ret;
334 }
335
OpenLink(const AAFwk::Want & want,int requestCode)336 ErrCode UIExtensionContext::OpenLink(const AAFwk::Want& want, int requestCode)
337 {
338 TAG_LOGD(AAFwkTag::UI_EXT, "called");
339 return AAFwk::AbilityManagerClient::GetInstance()->OpenLink(want, token_, -1, requestCode);
340 }
341
GetResourceManager() const342 std::shared_ptr<Global::Resource::ResourceManager> UIExtensionContext::GetResourceManager() const
343 {
344 if (abilityResourceMgr_) {
345 return abilityResourceMgr_;
346 }
347
348 return ContextImpl::GetResourceManager();
349 }
350
SetAbilityResourceManager(std::shared_ptr<Global::Resource::ResourceManager> abilityResourceMgr)351 void UIExtensionContext::SetAbilityResourceManager(
352 std::shared_ptr<Global::Resource::ResourceManager> abilityResourceMgr)
353 {
354 abilityResourceMgr_ = abilityResourceMgr;
355 }
356
RegisterAbilityConfigUpdateCallback(AbilityConfigUpdateCallback abilityConfigUpdateCallback)357 void UIExtensionContext::RegisterAbilityConfigUpdateCallback(AbilityConfigUpdateCallback abilityConfigUpdateCallback)
358 {
359 abilityConfigUpdateCallback_ = abilityConfigUpdateCallback;
360 }
361
GetAbilityConfiguration() const362 std::shared_ptr<AppExecFwk::Configuration> UIExtensionContext::GetAbilityConfiguration() const
363 {
364 return abilityConfiguration_;
365 }
366
SetAbilityConfiguration(const AppExecFwk::Configuration & config)367 void UIExtensionContext::SetAbilityConfiguration(const AppExecFwk::Configuration &config)
368 {
369 if (!abilityConfiguration_) {
370 abilityConfiguration_ = std::make_shared<AppExecFwk::Configuration>(config);
371 TAG_LOGI(AAFwkTag::CONTEXT, "abilityConfiguration: %{public}s", abilityConfiguration_->GetName().c_str());
372 return;
373 }
374 std::vector<std::string> changeKeyV;
375 abilityConfiguration_->CompareDifferent(changeKeyV, config);
376 if (!changeKeyV.empty()) {
377 abilityConfiguration_->Merge(changeKeyV, config);
378 }
379 TAG_LOGI(AAFwkTag::CONTEXT, "abilityConfiguration: %{public}s", abilityConfiguration_->GetName().c_str());
380 }
381
SetAbilityColorMode(int32_t colorMode)382 void UIExtensionContext::SetAbilityColorMode(int32_t colorMode)
383 {
384 TAG_LOGI(AAFwkTag::CONTEXT, "SetAbilityColorMode colorMode: %{public}d", colorMode);
385 if (colorMode < -1 || colorMode > 1) {
386 TAG_LOGE(AAFwkTag::CONTEXT, "colorMode error");
387 return;
388 }
389 AppExecFwk::Configuration config;
390
391 config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, AppExecFwk::GetColorModeStr(colorMode));
392 config.AddItem(AAFwk::GlobalConfigurationKey::COLORMODE_IS_SET_BY_APP,
393 AppExecFwk::ConfigurationInner::IS_SET_BY_APP);
394 if (!abilityConfigUpdateCallback_) {
395 TAG_LOGE(AAFwkTag::CONTEXT, "abilityConfigUpdateCallback_ nullptr");
396 return;
397 }
398 abilityConfigUpdateCallback_(config);
399 }
400
IsTerminating()401 bool UIExtensionContext::IsTerminating()
402 {
403 return isTerminating_;
404 }
405
SetTerminating(bool state)406 void UIExtensionContext::SetTerminating(bool state)
407 {
408 isTerminating_ = state;
409 }
410
StartAbilityByType(const std::string & type,AAFwk::WantParams & wantParam,const std::shared_ptr<JsUIExtensionCallback> & uiExtensionCallbacks)411 ErrCode UIExtensionContext::StartAbilityByType(const std::string &type,
412 AAFwk::WantParams &wantParam, const std::shared_ptr<JsUIExtensionCallback> &uiExtensionCallbacks)
413 {
414 TAG_LOGD(AAFwkTag::UI_EXT, "StartAbilityByType begin.");
415 if (uiExtensionCallbacks == nullptr) {
416 TAG_LOGE(AAFwkTag::UI_EXT, "null uiExtensionCallbacks");
417 return ERR_INVALID_VALUE;
418 }
419 auto uiContent = GetUIContent();
420 if (uiContent == nullptr) {
421 TAG_LOGE(AAFwkTag::UI_EXT, "null uiContent");
422 return ERR_INVALID_VALUE;
423 }
424 wantParam.SetParam(UIEXTENSION_TARGET_TYPE_KEY, AAFwk::String::Box(type));
425 AAFwk::Want want;
426 want.SetParams(wantParam);
427 if (wantParam.HasParam(FLAG_AUTH_READ_URI_PERMISSION)) {
428 int32_t flag = wantParam.GetIntParam(FLAG_AUTH_READ_URI_PERMISSION, 0);
429 want.SetFlags(flag);
430 wantParam.Remove(FLAG_AUTH_READ_URI_PERMISSION);
431 }
432
433 OHOS::Ace::ModalUIExtensionCallbacks callback;
434 OHOS::Ace::ModalUIExtensionConfig config;
435 callback.onError = [uiExtensionCallbacks](int32_t arg, const std::string &str1, const std::string &str2) {
436 uiExtensionCallbacks->OnError(arg);
437 };
438 callback.onRelease = [uiExtensionCallbacks](int32_t arg) {
439 uiExtensionCallbacks->OnRelease(arg);
440 };
441 callback.onResult = [uiExtensionCallbacks](int32_t arg1, const OHOS::AAFwk::Want arg2) {
442 uiExtensionCallbacks->OnResult(arg1, arg2);
443 };
444
445 int32_t sessionId = uiContent->CreateModalUIExtension(want, callback, config);
446 if (sessionId == 0) {
447 TAG_LOGE(AAFwkTag::UI_EXT, "createModalUIExtension fail");
448 return ERR_INVALID_VALUE;
449 }
450 uiExtensionCallbacks->SetUIContent(uiContent);
451 uiExtensionCallbacks->SetSessionId(sessionId);
452 return ERR_OK;
453 }
454
RequestComponentTerminate()455 void UIExtensionContext::RequestComponentTerminate()
456 {
457 TAG_LOGD(AAFwkTag::CONTEXT, "RequestComponentTerminate called");
458 if (!window_) {
459 TAG_LOGE(AAFwkTag::CONTEXT, "null window_");
460 return;
461 }
462 AAFwk::WantParams params;
463 params.SetParam(REQUEST_COMPONENT_TERMINATE_KEY, AAFwk::Boolean::Box(true));
464 auto ret = window_->TransferExtensionData(params);
465 if (ret != Rosen::WMError::WM_OK) {
466 TAG_LOGE(AAFwkTag::CONTEXT, "transfer extension data failed, ret:%{public}d", ret);
467 }
468 }
469
AddCompletionHandlerForAtomicService(const std::string & requestId,OnAtomicRequestSuccess onRequestSucc,OnAtomicRequestFailure onRequestFail,const std::string & appId)470 ErrCode UIExtensionContext::AddCompletionHandlerForAtomicService(const std::string &requestId,
471 OnAtomicRequestSuccess onRequestSucc, OnAtomicRequestFailure onRequestFail, const std::string &appId)
472 {
473 if (onRequestSucc == nullptr || onRequestFail == nullptr) {
474 TAG_LOGE(AAFwkTag::UI_EXT, "either func is null");
475 return ERR_INVALID_VALUE;
476 }
477 std::lock_guard lock(onRequestResultMutex_);
478 for (auto iter = onAtomicRequestResults_.begin(); iter != onAtomicRequestResults_.end(); iter++) {
479 if ((*iter)->requestId_ == requestId) {
480 TAG_LOGI(AAFwkTag::UI_EXT, "requestId=%{public}s already exists", requestId.c_str());
481 return ERR_OK;
482 }
483 }
484 onAtomicRequestResults_.emplace_back(std::make_shared<OnAtomicRequestResult>(
485 requestId, appId, onRequestSucc, onRequestFail));
486 return ERR_OK;
487 }
488
OnRequestSuccess(const std::string & requestId,const AppExecFwk::ElementName & element,const std::string & message)489 void UIExtensionContext::OnRequestSuccess(const std::string &requestId, const AppExecFwk::ElementName &element,
490 const std::string &message)
491 {
492 std::shared_ptr<OnAtomicRequestResult> atomicResult = nullptr;
493 {
494 std::lock_guard<std::mutex> lock(onRequestResultMutex_);
495 for (auto iter = onAtomicRequestResults_.begin(); iter != onAtomicRequestResults_.end(); iter++) {
496 if ((*iter)->requestId_ == requestId) {
497 atomicResult = *iter;
498 onAtomicRequestResults_.erase(iter);
499 break;
500 }
501 }
502 }
503
504 if (atomicResult != nullptr) {
505 TAG_LOGI(AAFwkTag::CONTEXT, "requestId=%{public}s, call onRequestSuccess", requestId.c_str());
506 atomicResult->onRequestSuccess_(atomicResult->appId_);
507 return;
508 }
509
510 TAG_LOGE(AAFwkTag::UI_EXT, "requestId=%{public}s not exist", requestId.c_str());
511 }
512
OnRequestFailure(const std::string & requestId,const AppExecFwk::ElementName & element,const std::string & message,int32_t resultCode)513 void UIExtensionContext::OnRequestFailure(const std::string &requestId, const AppExecFwk::ElementName &element,
514 const std::string &message, int32_t resultCode)
515 {
516 std::shared_ptr<OnAtomicRequestResult> atomicResult = nullptr;
517 {
518 std::lock_guard lock(onRequestResultMutex_);
519 for (auto iter = onAtomicRequestResults_.begin(); iter != onAtomicRequestResults_.end(); iter++) {
520 if ((*iter)->requestId_ == requestId) {
521 atomicResult = *iter;
522 onAtomicRequestResults_.erase(iter);
523 break;
524 }
525 }
526 }
527
528 if (atomicResult != nullptr) {
529 TAG_LOGI(AAFwkTag::UI_EXT, "requestId=%{public}s, call onRequestFailure", requestId.c_str());
530 int32_t failureCode = 0;
531 std::string failureMessage;
532 GetFailureInfoByMessage(message, failureCode, failureMessage, resultCode);
533 atomicResult->onRequestFailure_(atomicResult->appId_, failureCode, failureMessage);
534 return;
535 }
536
537 TAG_LOGE(AAFwkTag::UI_EXT, "requestId=%{public}s not exist", requestId.c_str());
538 }
539
GetFailureInfoByMessage(const std::string & message,int32_t & failureCode,std::string & failureMessage,int32_t resultCode)540 void UIExtensionContext::GetFailureInfoByMessage(
541 const std::string &message, int32_t &failureCode, std::string &failureMessage, int32_t resultCode)
542 {
543 if (resultCode == USER_CANCEL) {
544 failureCode = static_cast<int32_t>(FailureCode::FAILURE_CODE_USER_CANCEL);
545 failureMessage = "The user canceled this startup";
546 } else if (message.find("User refused redirection") != std::string::npos) {
547 failureCode = static_cast<int32_t>(FailureCode::FAILURE_CODE_USER_REFUSE);
548 failureMessage = "User refused redirection";
549 } else {
550 failureCode = static_cast<int32_t>(FailureCode::FAILURE_CODE_SYSTEM_MALFUNCTION);
551 failureMessage = "A system error occurred";
552 }
553 }
554
555 int32_t UIExtensionContext::curRequestCode_ = 0;
556 std::mutex UIExtensionContext::requestCodeMutex_;
557 } // namespace AbilityRuntime
558 } // namespace OHOS
559