1 /*
2 * Copyright (c) 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 #include "ani_common.h"
16 #include "accesstoken_common_log.h"
17 #include <sstream>
18 namespace OHOS {
19 namespace Security {
20 namespace AccessToken {
21 namespace {
22 constexpr const char* WRAPPER_CLASS_NAME = "L@ohos/abilityAccessCtrl/AsyncCallbackWrapper;";
23 constexpr const char* INVOKE_METHOD_NAME = "invoke";
24 } // namespace
25
ExecuteAsyncCallback(ani_env * env,ani_object callback,ani_object error,ani_object result)26 bool ExecuteAsyncCallback(ani_env* env, ani_object callback, ani_object error, ani_object result)
27 {
28 if (env == nullptr || callback == nullptr || error == nullptr || result == nullptr) {
29 LOGE(ATM_DOMAIN, ATM_TAG, "Invalid paramter.");
30 return false;
31 }
32 ani_status status = ANI_ERROR;
33 ani_class clsCall {};
34
35 if ((status = env->FindClass(WRAPPER_CLASS_NAME, &clsCall)) != ANI_OK) {
36 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to FindClass, error=%{public}d.", static_cast<int32_t>(status));
37 return false;
38 }
39 ani_method method = {};
40 if ((status = env->Class_FindMethod(
41 clsCall, INVOKE_METHOD_NAME, "L@ohos/base/BusinessError;Lstd/core/Object;:V", &method)) != ANI_OK) {
42 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to Class_FindMethod, error=%{public}d.", static_cast<int32_t>(status));
43 return false;
44 }
45
46 status = env->Object_CallMethod_Void(static_cast<ani_object>(callback), method, error, result);
47 if (status != ANI_OK) {
48 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to Object_CallMethod_Void, error=%{public}d.", static_cast<int32_t>(status));
49 return false;
50 }
51 return true;
52 }
53
GetUIContent(const std::shared_ptr<OHOS::AbilityRuntime::Context> stageContext)54 OHOS::Ace::UIContent* GetUIContent(const std::shared_ptr<OHOS::AbilityRuntime::Context> stageContext)
55 {
56 if (stageContext == nullptr) {
57 LOGE(ATM_DOMAIN, ATM_TAG, "stageContext is nullptr");
58 return nullptr;
59 }
60 OHOS::Ace::UIContent* uiContent = nullptr;
61 auto abilityContext = OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(
62 stageContext);
63 if (abilityContext != nullptr) {
64 uiContent = abilityContext->GetUIContent();
65 } else {
66 auto uiExtensionContext =
67 OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::UIExtensionContext>(stageContext);
68 if (uiExtensionContext == nullptr) {
69 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to ConvertTo UIExtensionContext.");
70 return nullptr;
71 }
72 uiContent = uiExtensionContext->GetUIContent();
73 }
74 return uiContent;
75 }
76
CreateUIExtensionMainThread(std::shared_ptr<RequestAsyncContextBase> asyncContext,const OHOS::AAFwk::Want & want,const OHOS::Ace::ModalUIExtensionCallbacks & uiExtensionCallbacks,const std::shared_ptr<UIExtensionCallback> uiExtCallback)77 void CreateUIExtensionMainThread(std::shared_ptr<RequestAsyncContextBase> asyncContext,
78 const OHOS::AAFwk::Want& want, const OHOS::Ace::ModalUIExtensionCallbacks& uiExtensionCallbacks,
79 const std::shared_ptr<UIExtensionCallback> uiExtCallback)
80 {
81 if (asyncContext == nullptr || uiExtCallback == nullptr) {
82 LOGE(ATM_DOMAIN, ATM_TAG, "asyncContext or uiExtCallback is nullptr");
83 return;
84 }
85 auto task = [asyncContext, want, uiExtensionCallbacks, uiExtCallback]() {
86 OHOS::Ace::UIContent* uiContent = GetUIContent(asyncContext->stageContext_);
87 if (uiContent == nullptr) {
88 LOGE(ATM_DOMAIN, ATM_TAG, "Get ui content failed!");
89 asyncContext->result.errorCode = AccessToken::RET_FAILED;
90 asyncContext->uiExtensionFlag = false;
91 return;
92 }
93
94 OHOS::Ace::ModalUIExtensionConfig config;
95 config.isProhibitBack = true;
96 int32_t sessionId = uiContent->CreateModalUIExtension(want, uiExtensionCallbacks, config);
97 LOGI(ATM_DOMAIN, ATM_TAG, "Create end, sessionId: %{public}d, tokenId: %{public}d.",
98 sessionId, asyncContext->tokenId);
99 if (sessionId <= 0) {
100 LOGE(ATM_DOMAIN, ATM_TAG, "Create component failed, sessionId is invalid");
101 asyncContext->result.errorCode = AccessToken::RET_FAILED;
102 asyncContext->uiExtensionFlag = false;
103 return;
104 }
105 uiExtCallback->SetSessionId(sessionId);
106 };
107 #ifdef EVENTHANDLER_ENABLE
108 if (asyncContext->handler_ != nullptr) {
109 asyncContext->handler_->PostSyncTask(task, "AT:CreateUIExtensionMainThread");
110 } else {
111 task();
112 }
113 #else
114 task();
115 #endif
116 }
117
CloseModalUIExtensionMainThread(std::shared_ptr<RequestAsyncContextBase> asyncContext,int32_t sessionId)118 void CloseModalUIExtensionMainThread(std::shared_ptr<RequestAsyncContextBase> asyncContext, int32_t sessionId)
119 {
120 if (asyncContext == nullptr) {
121 LOGE(ATM_DOMAIN, ATM_TAG, "asyncContext is nullptr");
122 return;
123 }
124 auto task = [asyncContext, sessionId]() {
125 Ace::UIContent* uiContent = GetUIContent(asyncContext->stageContext_);
126 if (uiContent == nullptr) {
127 LOGE(ATM_DOMAIN, ATM_TAG, "Get ui content failed!");
128 asyncContext->result.errorCode = RET_FAILED;
129 return;
130 }
131 uiContent->CloseModalUIExtension(sessionId);
132 LOGI(ATM_DOMAIN, ATM_TAG, "Close end, sessionId: %{public}d", sessionId);
133 };
134 #ifdef EVENTHANDLER_ENABLE
135 if (asyncContext->handler_ != nullptr) {
136 asyncContext->handler_->PostSyncTask(task, "AT:CloseModalUIExtensionMainThread");
137 } else {
138 task();
139 }
140 #else
141 task();
142 #endif
143 LOGI(ATM_DOMAIN, ATM_TAG, "Instance id: %{public}d", asyncContext->instanceId);
144 }
145
CreateUIExtension(const OHOS::AAFwk::Want & want,std::shared_ptr<RequestAsyncContextBase> asyncContext,std::shared_ptr<RequestInstanceControl> controller)146 void CreateUIExtension(
147 const OHOS::AAFwk::Want& want,
148 std::shared_ptr<RequestAsyncContextBase> asyncContext,
149 std::shared_ptr<RequestInstanceControl> controller)
150 {
151 if (asyncContext == nullptr || controller == nullptr) {
152 LOGE(ATM_DOMAIN, ATM_TAG, "asyncContext or controller is nullptr");
153 return;
154 }
155 auto uiExtCallback = std::make_shared<UIExtensionCallback>(asyncContext);
156 uiExtCallback->SetRequestInstanceControl(controller);
157 OHOS::Ace::ModalUIExtensionCallbacks uiExtensionCallbacks = {
158 [uiExtCallback](int32_t releaseCode) { uiExtCallback->OnRelease(releaseCode); },
159 [uiExtCallback](
160 int32_t resultCode, const OHOS::AAFwk::Want& result) { uiExtCallback->OnResult(resultCode, result); },
161 [uiExtCallback](const OHOS::AAFwk::WantParams& receive) { uiExtCallback->OnReceive(receive); },
162 [uiExtCallback](int32_t code, const std::string& name, [[maybe_unused]] const std::string& message) {
163 uiExtCallback->OnError(code, name, name);
164 },
165 [uiExtCallback](const std::shared_ptr<OHOS::Ace::ModalUIExtensionProxy>& uiProxy) {
166 uiExtCallback->OnRemoteReady(uiProxy);
167 },
168 [uiExtCallback]() { uiExtCallback->OnDestroy(); },
169 };
170 CreateUIExtensionMainThread(asyncContext, want, uiExtensionCallbacks, uiExtCallback);
171 }
172 } // namespace AccessToken
173 } // namespace Security
174 } // namespace OHOS