• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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