1 /*
2  * Copyright (c) 2023-2024 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 "connection_manager.h"
20 #include "hilog_tag_wrapper.h"
21 #include "hitrace_meter.h"
22 
23 namespace OHOS {
24 namespace AbilityRuntime {
25 const size_t UIExtensionContext::CONTEXT_TYPE_ID(std::hash<const char*> {} ("UIExtensionContext"));
26 int UIExtensionContext::ILLEGAL_REQUEST_CODE(-1);
27 
StartAbility(const AAFwk::Want & want) const28 ErrCode UIExtensionContext::StartAbility(const AAFwk::Want &want) const
29 {
30     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
31     TAG_LOGD(AAFwkTag::UI_EXT, "begin, ability:%{public}s", want.GetElement().GetAbilityName().c_str());
32     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, token_, ILLEGAL_REQUEST_CODE);
33     if (err != ERR_OK) {
34         TAG_LOGE(AAFwkTag::UI_EXT, "StartAbility is failed %{public}d", err);
35     }
36     return err;
37 }
38 
StartAbility(const AAFwk::Want & want,int requestCode) const39 ErrCode UIExtensionContext::StartAbility(const AAFwk::Want &want, int requestCode) const
40 {
41     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
42     TAG_LOGD(AAFwkTag::UI_EXT, "begin, requestCode:%{public}d", requestCode);
43     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, token_, requestCode);
44     if (err != ERR_OK) {
45         TAG_LOGE(AAFwkTag::UI_EXT, "StartAbility is failed %{public}d", err);
46     }
47     return err;
48 }
49 
StartAbility(const AAFwk::Want & want,const AAFwk::StartOptions & startOptions) const50 ErrCode UIExtensionContext::StartAbility(const AAFwk::Want &want, const AAFwk::StartOptions &startOptions) const
51 {
52     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
53     TAG_LOGD(AAFwkTag::UI_EXT, "begin, ability:%{public}s", want.GetElement().GetAbilityName().c_str());
54     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, startOptions, token_,
55         ILLEGAL_REQUEST_CODE);
56     if (err != ERR_OK) {
57         TAG_LOGE(AAFwkTag::UI_EXT, "StartAbility is failed %{public}d", err);
58     }
59     return err;
60 }
61 
StartUIServiceExtension(const AAFwk::Want & want,int32_t accountId) const62 ErrCode UIExtensionContext::StartUIServiceExtension(const AAFwk::Want& want, int32_t accountId) const
63 {
64     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
65     TAG_LOGD(AAFwkTag::UI_EXT, "Start UIServiceExtension begin");
66     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartExtensionAbility(
67         want, token_, accountId, AppExecFwk::ExtensionAbilityType::UI_SERVICE);
68     if (err != ERR_OK) {
69         TAG_LOGE(AAFwkTag::UI_EXT, "StartUIServiceExtension is failed %{public}d", err);
70     }
71     return err;
72 }
73 
TerminateSelf()74 ErrCode UIExtensionContext::TerminateSelf()
75 {
76     TAG_LOGD(AAFwkTag::UI_EXT, "begin");
77     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->TerminateAbility(token_, -1, nullptr);
78     if (err != ERR_OK) {
79         TAG_LOGE(AAFwkTag::UI_EXT, "TerminateSelf is failed %{public}d", err);
80     }
81     TAG_LOGD(AAFwkTag::UI_EXT, "TerminateSelf end");
82     return err;
83 }
84 
ConnectAbility(const AAFwk::Want & want,const sptr<AbilityConnectCallback> & connectCallback) const85 ErrCode UIExtensionContext::ConnectAbility(
86     const AAFwk::Want &want, const sptr<AbilityConnectCallback> &connectCallback) const
87 {
88     TAG_LOGD(AAFwkTag::UI_EXT, "begin, ability:%{public}s",
89         want.GetElement().GetAbilityName().c_str());
90     ErrCode ret =
91         ConnectionManager::GetInstance().ConnectAbility(token_, want, connectCallback);
92     TAG_LOGD(AAFwkTag::UI_EXT, "UIExtensionContext::ConnectAbility ErrorCode = %{public}d", ret);
93     return ret;
94 }
95 
ConnectUIServiceExtensionAbility(const AAFwk::Want & want,const sptr<AbilityConnectCallback> & connectCallback) const96 ErrCode UIExtensionContext::ConnectUIServiceExtensionAbility(
97     const AAFwk::Want &want, const sptr<AbilityConnectCallback> &connectCallback) const
98 {
99     TAG_LOGD(AAFwkTag::UI_EXT, "begin, ability:%{public}s",
100         want.GetElement().GetAbilityName().c_str());
101     ErrCode ret =
102         ConnectionManager::GetInstance().ConnectUIServiceExtensionAbility(token_, want, connectCallback);
103     TAG_LOGD(AAFwkTag::UI_EXT, "UIExtensionContext::ConnectUIServiceExtensionAbility ErrorCode = %{public}d", ret);
104     return ret;
105 }
106 
DisconnectAbility(const AAFwk::Want & want,const sptr<AbilityConnectCallback> & connectCallback) const107 ErrCode UIExtensionContext::DisconnectAbility(
108     const AAFwk::Want &want, const sptr<AbilityConnectCallback> &connectCallback) const
109 {
110     TAG_LOGD(AAFwkTag::UI_EXT, "begin");
111     ErrCode ret =
112         ConnectionManager::GetInstance().DisconnectAbility(token_, want, connectCallback);
113     if (ret != ERR_OK) {
114         TAG_LOGE(AAFwkTag::UI_EXT, "DisconnectAbility error, ret=%{public}d", ret);
115     }
116     TAG_LOGD(AAFwkTag::UI_EXT, "end");
117     return ret;
118 }
119 
StartAbilityForResult(const AAFwk::Want & want,int requestCode,RuntimeTask && task)120 ErrCode UIExtensionContext::StartAbilityForResult(const AAFwk::Want &want, int requestCode, RuntimeTask &&task)
121 {
122     TAG_LOGD(AAFwkTag::UI_EXT, "begin");
123     {
124         std::lock_guard<std::mutex> lock(mutexlock_);
125         resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
126     }
127     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, token_, requestCode);
128     if (err != ERR_OK) {
129         TAG_LOGE(AAFwkTag::UI_EXT, "ret=%{public}d", err);
130         OnAbilityResultInner(requestCode, err, want);
131     }
132     TAG_LOGD(AAFwkTag::UI_EXT, "end");
133     return err;
134 }
135 
InsertResultCallbackTask(int requestCode,RuntimeTask && task)136 void UIExtensionContext::InsertResultCallbackTask(int requestCode, RuntimeTask &&task)
137 {
138     TAG_LOGD(AAFwkTag::UI_EXT, "called");
139     {
140         std::lock_guard<std::mutex> lock(mutexlock_);
141         resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
142     }
143 }
144 
RemoveResultCallbackTask(int requestCode)145 void UIExtensionContext::RemoveResultCallbackTask(int requestCode)
146 {
147     TAG_LOGD(AAFwkTag::UI_EXT, "called");
148     {
149         std::lock_guard<std::mutex> lock(mutexlock_);
150         resultCallbacks_.erase(requestCode);
151     }
152 }
153 
StartAbilityForResult(const AAFwk::Want & want,const AAFwk::StartOptions & startOptions,int requestCode,RuntimeTask && task)154 ErrCode UIExtensionContext::StartAbilityForResult(
155     const AAFwk::Want &want, const AAFwk::StartOptions &startOptions, int requestCode, RuntimeTask &&task)
156 {
157     TAG_LOGD(AAFwkTag::UI_EXT, "begin");
158     {
159         std::lock_guard<std::mutex> lock(mutexlock_);
160         resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
161     }
162     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, startOptions, token_, requestCode);
163     if (err != ERR_OK) {
164         TAG_LOGE(AAFwkTag::UI_EXT, "ret=%{public}d", err);
165         OnAbilityResultInner(requestCode, err, want);
166     }
167     TAG_LOGD(AAFwkTag::UI_EXT, "end");
168     return err;
169 }
170 
StartAbilityForResultAsCaller(const AAFwk::Want & want,int requestCode,RuntimeTask && task)171 ErrCode UIExtensionContext::StartAbilityForResultAsCaller(const AAFwk::Want &want, int requestCode, RuntimeTask &&task)
172 {
173     TAG_LOGD(AAFwkTag::UI_EXT, "called");
174     {
175         std::lock_guard<std::mutex> lock(mutexlock_);
176         resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
177     }
178     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbilityForResultAsCaller(want, token_, requestCode);
179     if (err != ERR_OK) {
180         TAG_LOGE(AAFwkTag::UI_EXT, "The result = %{public}d", err);
181         OnAbilityResultInner(requestCode, err, want);
182     }
183     TAG_LOGD(AAFwkTag::UI_EXT, "End");
184     return err;
185 }
186 
StartAbilityForResultAsCaller(const AAFwk::Want & want,const AAFwk::StartOptions & startOptions,int requestCode,RuntimeTask && task)187 ErrCode UIExtensionContext::StartAbilityForResultAsCaller(
188     const AAFwk::Want &want, const AAFwk::StartOptions &startOptions, int requestCode, RuntimeTask &&task)
189 {
190     TAG_LOGD(AAFwkTag::UI_EXT, "called");
191     {
192         std::lock_guard<std::mutex> lock(mutexlock_);
193         resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
194     }
195     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbilityForResultAsCaller(
196         want, startOptions, token_, requestCode);
197     if (err != ERR_OK) {
198         TAG_LOGE(AAFwkTag::UI_EXT, "The result = %{public}d", err);
199         OnAbilityResultInner(requestCode, err, want);
200     }
201     TAG_LOGD(AAFwkTag::UI_EXT, "End");
202     return err;
203 }
204 
ReportDrawnCompleted()205 ErrCode UIExtensionContext::ReportDrawnCompleted()
206 {
207     TAG_LOGD(AAFwkTag::UI_EXT, "begin");
208     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->ReportDrawnCompleted(token_);
209     if (err != ERR_OK) {
210         TAG_LOGE(AAFwkTag::UI_EXT, "ret=%{public}d", err);
211     }
212     return err;
213 }
214 
OnAbilityResult(int requestCode,int resultCode,const AAFwk::Want & resultData)215 void UIExtensionContext::OnAbilityResult(int requestCode, int resultCode, const AAFwk::Want &resultData)
216 {
217     TAG_LOGD(AAFwkTag::UI_EXT, "begin");
218     std::lock_guard<std::mutex> lock(mutexlock_);
219     auto callback = resultCallbacks_.find(requestCode);
220     if (callback != resultCallbacks_.end()) {
221         if (callback->second) {
222             callback->second(resultCode, resultData, false);
223         }
224         resultCallbacks_.erase(requestCode);
225     }
226     TAG_LOGD(AAFwkTag::UI_EXT, "end");
227 }
228 
GetAbilityInfoType() const229 AppExecFwk::AbilityType UIExtensionContext::GetAbilityInfoType() const
230 {
231     std::shared_ptr<AppExecFwk::AbilityInfo> info = GetAbilityInfo();
232     if (info == nullptr) {
233         TAG_LOGW(AAFwkTag::UI_EXT, "GetAbilityInfoType info is nullptr");
234         return AppExecFwk::AbilityType::UNKNOWN;
235     }
236 
237     return info->type;
238 }
239 
OnAbilityResultInner(int requestCode,int resultCode,const AAFwk::Want & resultData)240 void UIExtensionContext::OnAbilityResultInner(int requestCode, int resultCode, const AAFwk::Want &resultData)
241 {
242     TAG_LOGD(AAFwkTag::UI_EXT, "begin");
243     std::lock_guard<std::mutex> lock(mutexlock_);
244     auto callback = resultCallbacks_.find(requestCode);
245     if (callback != resultCallbacks_.end()) {
246         if (callback->second) {
247             callback->second(resultCode, resultData, true);
248         }
249         resultCallbacks_.erase(requestCode);
250     }
251     TAG_LOGD(AAFwkTag::UI_EXT, "end");
252 }
253 
GenerateCurRequestCode()254 int UIExtensionContext::GenerateCurRequestCode()
255 {
256     std::lock_guard lock(requestCodeMutex_);
257     curRequestCode_ = (curRequestCode_ == INT_MAX) ? 0 : (curRequestCode_ + 1);
258     return curRequestCode_;
259 }
260 
SetWindow(sptr<Rosen::Window> window)261 void UIExtensionContext::SetWindow(sptr<Rosen::Window> window)
262 {
263     window_ = window;
264 }
GetWindow()265 sptr<Rosen::Window> UIExtensionContext::GetWindow()
266 {
267     return window_;
268 }
GetUIContent()269 Ace::UIContent* UIExtensionContext::GetUIContent()
270 {
271     TAG_LOGI(AAFwkTag::UI_EXT, "called");
272     if (window_ == nullptr) {
273         return nullptr;
274     }
275     return window_->GetUIContent();
276 }
277 
OpenAtomicService(AAFwk::Want & want,const AAFwk::StartOptions & options,int requestCode,RuntimeTask && task)278 ErrCode UIExtensionContext::OpenAtomicService(AAFwk::Want& want, const AAFwk::StartOptions &options, int requestCode,
279     RuntimeTask &&task)
280 {
281     TAG_LOGD(AAFwkTag::UI_EXT, "called");
282     resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
283     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->OpenAtomicService(want, options, token_, requestCode);
284     if (err != ERR_OK && err != AAFwk::START_ABILITY_WAITING) {
285         TAG_LOGE(AAFwkTag::UI_EXT, "OpenAtomicService. ret=%{public}d", err);
286         OnAbilityResultInner(requestCode, err, want);
287     }
288     return err;
289 }
290 
AddFreeInstallObserver(const sptr<IFreeInstallObserver> & observer)291 ErrCode UIExtensionContext::AddFreeInstallObserver(const sptr<IFreeInstallObserver> &observer)
292 {
293     ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->AddFreeInstallObserver(token_, observer);
294     if (ret != ERR_OK) {
295         TAG_LOGE(AAFwkTag::UI_EXT, "error, ret: %{public}d", ret);
296     }
297     return ret;
298 }
299 
OpenLink(const AAFwk::Want & want,int requestCode)300 ErrCode UIExtensionContext::OpenLink(const AAFwk::Want& want, int requestCode)
301 {
302     TAG_LOGD(AAFwkTag::UI_EXT, "called");
303     return AAFwk::AbilityManagerClient::GetInstance()->OpenLink(want, token_, -1, requestCode);
304 }
305 
306 int32_t UIExtensionContext::curRequestCode_ = 0;
307 std::mutex UIExtensionContext::requestCodeMutex_;
308 }  // namespace AbilityRuntime
309 }  // namespace OHOS
310