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 #include "configuration_convertor.h"
23
24 namespace OHOS {
25 namespace AbilityRuntime {
26 const size_t UIExtensionContext::CONTEXT_TYPE_ID(std::hash<const char*> {} ("UIExtensionContext"));
27 int UIExtensionContext::ILLEGAL_REQUEST_CODE(-1);
28
StartAbility(const AAFwk::Want & want) const29 ErrCode UIExtensionContext::StartAbility(const AAFwk::Want &want) const
30 {
31 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
32 TAG_LOGD(AAFwkTag::UI_EXT, "begin, ability:%{public}s", want.GetElement().GetAbilityName().c_str());
33 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, token_, ILLEGAL_REQUEST_CODE);
34 if (err != ERR_OK) {
35 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
36 }
37 return err;
38 }
39
StartAbility(const AAFwk::Want & want,int requestCode) const40 ErrCode UIExtensionContext::StartAbility(const AAFwk::Want &want, int requestCode) const
41 {
42 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
43 TAG_LOGD(AAFwkTag::UI_EXT, "begin, requestCode:%{public}d", requestCode);
44 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, token_, requestCode);
45 if (err != ERR_OK) {
46 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
47 }
48 return err;
49 }
50
StartAbility(const AAFwk::Want & want,const AAFwk::StartOptions & startOptions) const51 ErrCode UIExtensionContext::StartAbility(const AAFwk::Want &want, const AAFwk::StartOptions &startOptions) const
52 {
53 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
54 TAG_LOGD(AAFwkTag::UI_EXT, "begin, ability:%{public}s", want.GetElement().GetAbilityName().c_str());
55 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, startOptions, token_,
56 ILLEGAL_REQUEST_CODE);
57 if (err != ERR_OK) {
58 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
59 }
60 return err;
61 }
62
StartUIServiceExtension(const AAFwk::Want & want,int32_t accountId) const63 ErrCode UIExtensionContext::StartUIServiceExtension(const AAFwk::Want& want, int32_t accountId) const
64 {
65 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
66 TAG_LOGD(AAFwkTag::UI_EXT, "Start UIServiceExtension begin");
67 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartExtensionAbility(
68 want, token_, accountId, AppExecFwk::ExtensionAbilityType::UI_SERVICE);
69 if (err != ERR_OK) {
70 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
71 }
72 return err;
73 }
74
TerminateSelf()75 ErrCode UIExtensionContext::TerminateSelf()
76 {
77 TAG_LOGD(AAFwkTag::UI_EXT, "begin");
78 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->TerminateAbility(token_, -1, nullptr);
79 if (err != ERR_OK) {
80 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
81 }
82 TAG_LOGD(AAFwkTag::UI_EXT, "TerminateSelf end");
83 return err;
84 }
85
ConnectAbility(const AAFwk::Want & want,const sptr<AbilityConnectCallback> & connectCallback) const86 ErrCode UIExtensionContext::ConnectAbility(
87 const AAFwk::Want &want, const sptr<AbilityConnectCallback> &connectCallback) const
88 {
89 TAG_LOGD(AAFwkTag::UI_EXT, "begin, ability:%{public}s",
90 want.GetElement().GetAbilityName().c_str());
91 ErrCode ret =
92 ConnectionManager::GetInstance().ConnectAbility(token_, want, connectCallback);
93 TAG_LOGD(AAFwkTag::UI_EXT, "UIExtensionContext::ConnectAbility ErrorCode = %{public}d", ret);
94 return ret;
95 }
96
ConnectUIServiceExtensionAbility(const AAFwk::Want & want,const sptr<AbilityConnectCallback> & connectCallback) const97 ErrCode UIExtensionContext::ConnectUIServiceExtensionAbility(
98 const AAFwk::Want &want, const sptr<AbilityConnectCallback> &connectCallback) const
99 {
100 TAG_LOGD(AAFwkTag::UI_EXT, "begin, ability:%{public}s",
101 want.GetElement().GetAbilityName().c_str());
102 ErrCode ret =
103 ConnectionManager::GetInstance().ConnectUIServiceExtensionAbility(token_, want, connectCallback);
104 TAG_LOGD(AAFwkTag::UI_EXT, "UIExtensionContext::ConnectUIServiceExtensionAbility ErrorCode = %{public}d", ret);
105 return ret;
106 }
107
DisconnectAbility(const AAFwk::Want & want,const sptr<AbilityConnectCallback> & connectCallback) const108 ErrCode UIExtensionContext::DisconnectAbility(
109 const AAFwk::Want &want, const sptr<AbilityConnectCallback> &connectCallback) const
110 {
111 TAG_LOGD(AAFwkTag::UI_EXT, "begin");
112 ErrCode ret =
113 ConnectionManager::GetInstance().DisconnectAbility(token_, want, connectCallback);
114 if (ret != ERR_OK) {
115 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", ret);
116 }
117 TAG_LOGD(AAFwkTag::UI_EXT, "end");
118 return ret;
119 }
120
StartServiceExtensionAbility(const AAFwk::Want & want,int32_t accountId)121 ErrCode UIExtensionContext::StartServiceExtensionAbility(const AAFwk::Want& want, int32_t accountId)
122 {
123 TAG_LOGI(AAFwkTag::UI_EXT, "Start service extension %{public}s, accountId: %{public}d",
124 want.GetElement().GetURI().c_str(), accountId);
125 auto ret = AAFwk::AbilityManagerClient::GetInstance()->StartExtensionAbility(
126 want, token_, accountId, AppExecFwk::ExtensionAbilityType::SERVICE);
127 if (ret != ERR_OK) {
128 TAG_LOGE(AAFwkTag::UI_EXT, "Start service extension failed %{public}d", ret);
129 }
130 return ret;
131 }
132
StartAbilityForResult(const AAFwk::Want & want,int requestCode,RuntimeTask && task)133 ErrCode UIExtensionContext::StartAbilityForResult(const AAFwk::Want &want, int requestCode, RuntimeTask &&task)
134 {
135 TAG_LOGD(AAFwkTag::UI_EXT, "begin");
136 {
137 std::lock_guard<std::mutex> lock(mutexlock_);
138 resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
139 }
140 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, token_, requestCode);
141 if (err != ERR_OK) {
142 TAG_LOGE(AAFwkTag::UI_EXT, "ret=%{public}d", err);
143 OnAbilityResultInner(requestCode, err, want);
144 }
145 TAG_LOGD(AAFwkTag::UI_EXT, "end");
146 return err;
147 }
148
InsertResultCallbackTask(int requestCode,RuntimeTask && task)149 void UIExtensionContext::InsertResultCallbackTask(int requestCode, RuntimeTask &&task)
150 {
151 TAG_LOGD(AAFwkTag::UI_EXT, "called");
152 {
153 std::lock_guard<std::mutex> lock(mutexlock_);
154 resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
155 }
156 }
157
RemoveResultCallbackTask(int requestCode)158 void UIExtensionContext::RemoveResultCallbackTask(int requestCode)
159 {
160 TAG_LOGD(AAFwkTag::UI_EXT, "called");
161 {
162 std::lock_guard<std::mutex> lock(mutexlock_);
163 resultCallbacks_.erase(requestCode);
164 }
165 }
166
StartAbilityForResult(const AAFwk::Want & want,const AAFwk::StartOptions & startOptions,int requestCode,RuntimeTask && task)167 ErrCode UIExtensionContext::StartAbilityForResult(
168 const AAFwk::Want &want, const AAFwk::StartOptions &startOptions, int requestCode, RuntimeTask &&task)
169 {
170 TAG_LOGD(AAFwkTag::UI_EXT, "begin");
171 {
172 std::lock_guard<std::mutex> lock(mutexlock_);
173 resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
174 }
175 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, startOptions, token_, requestCode);
176 if (err != ERR_OK) {
177 TAG_LOGE(AAFwkTag::UI_EXT, "ret=%{public}d", err);
178 OnAbilityResultInner(requestCode, err, want);
179 }
180 TAG_LOGD(AAFwkTag::UI_EXT, "end");
181 return err;
182 }
183
StartAbilityForResultAsCaller(const AAFwk::Want & want,int requestCode,RuntimeTask && task)184 ErrCode UIExtensionContext::StartAbilityForResultAsCaller(const AAFwk::Want &want, int requestCode, RuntimeTask &&task)
185 {
186 TAG_LOGD(AAFwkTag::UI_EXT, "called");
187 {
188 std::lock_guard<std::mutex> lock(mutexlock_);
189 resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
190 }
191 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbilityForResultAsCaller(want, token_, requestCode);
192 if (err != ERR_OK) {
193 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
194 OnAbilityResultInner(requestCode, err, want);
195 }
196 TAG_LOGD(AAFwkTag::UI_EXT, "End");
197 return err;
198 }
199
StartAbilityForResultAsCaller(const AAFwk::Want & want,const AAFwk::StartOptions & startOptions,int requestCode,RuntimeTask && task)200 ErrCode UIExtensionContext::StartAbilityForResultAsCaller(
201 const AAFwk::Want &want, const AAFwk::StartOptions &startOptions, int requestCode, RuntimeTask &&task)
202 {
203 TAG_LOGD(AAFwkTag::UI_EXT, "called");
204 {
205 std::lock_guard<std::mutex> lock(mutexlock_);
206 resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
207 }
208 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbilityForResultAsCaller(
209 want, startOptions, token_, requestCode);
210 if (err != ERR_OK) {
211 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
212 OnAbilityResultInner(requestCode, err, want);
213 }
214 TAG_LOGD(AAFwkTag::UI_EXT, "End");
215 return err;
216 }
217
ReportDrawnCompleted()218 ErrCode UIExtensionContext::ReportDrawnCompleted()
219 {
220 TAG_LOGD(AAFwkTag::UI_EXT, "begin");
221 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->ReportDrawnCompleted(token_);
222 if (err != ERR_OK) {
223 TAG_LOGE(AAFwkTag::UI_EXT, "ret=%{public}d", err);
224 }
225 return err;
226 }
227
OnAbilityResult(int requestCode,int resultCode,const AAFwk::Want & resultData)228 void UIExtensionContext::OnAbilityResult(int requestCode, int resultCode, const AAFwk::Want &resultData)
229 {
230 TAG_LOGD(AAFwkTag::UI_EXT, "begin");
231 std::lock_guard<std::mutex> lock(mutexlock_);
232 auto callback = resultCallbacks_.find(requestCode);
233 if (callback != resultCallbacks_.end()) {
234 if (callback->second) {
235 callback->second(resultCode, resultData, false);
236 }
237 resultCallbacks_.erase(requestCode);
238 }
239 TAG_LOGD(AAFwkTag::UI_EXT, "end");
240 }
241
GetAbilityInfoType() const242 AppExecFwk::AbilityType UIExtensionContext::GetAbilityInfoType() const
243 {
244 std::shared_ptr<AppExecFwk::AbilityInfo> info = GetAbilityInfo();
245 if (info == nullptr) {
246 TAG_LOGW(AAFwkTag::UI_EXT, "null info");
247 return AppExecFwk::AbilityType::UNKNOWN;
248 }
249
250 return info->type;
251 }
252
OnAbilityResultInner(int requestCode,int resultCode,const AAFwk::Want & resultData)253 void UIExtensionContext::OnAbilityResultInner(int requestCode, int resultCode, const AAFwk::Want &resultData)
254 {
255 TAG_LOGD(AAFwkTag::UI_EXT, "begin");
256 std::lock_guard<std::mutex> lock(mutexlock_);
257 auto callback = resultCallbacks_.find(requestCode);
258 if (callback != resultCallbacks_.end()) {
259 if (callback->second) {
260 callback->second(resultCode, resultData, true);
261 }
262 resultCallbacks_.erase(requestCode);
263 }
264 TAG_LOGD(AAFwkTag::UI_EXT, "end");
265 }
266
GetScreenMode() const267 int32_t UIExtensionContext::GetScreenMode() const
268 {
269 return screenMode_;
270 }
271
SetScreenMode(int32_t screenMode)272 void UIExtensionContext::SetScreenMode(int32_t screenMode)
273 {
274 screenMode_ = screenMode;
275 }
276
GenerateCurRequestCode()277 int UIExtensionContext::GenerateCurRequestCode()
278 {
279 std::lock_guard lock(requestCodeMutex_);
280 curRequestCode_ = (curRequestCode_ == INT_MAX) ? 0 : (curRequestCode_ + 1);
281 return curRequestCode_;
282 }
283 #ifdef SUPPORT_SCREEN
SetWindow(sptr<Rosen::Window> window)284 void UIExtensionContext::SetWindow(sptr<Rosen::Window> window)
285 {
286 window_ = window;
287 }
GetWindow()288 sptr<Rosen::Window> UIExtensionContext::GetWindow()
289 {
290 return window_;
291 }
GetUIContent()292 Ace::UIContent* UIExtensionContext::GetUIContent()
293 {
294 TAG_LOGI(AAFwkTag::UI_EXT, "called");
295 if (window_ == nullptr) {
296 return nullptr;
297 }
298 return window_->GetUIContent();
299 }
300 #endif // SUPPORT_SCREEN
OpenAtomicService(AAFwk::Want & want,const AAFwk::StartOptions & options,int requestCode,RuntimeTask && task)301 ErrCode UIExtensionContext::OpenAtomicService(AAFwk::Want& want, const AAFwk::StartOptions &options, int requestCode,
302 RuntimeTask &&task)
303 {
304 TAG_LOGD(AAFwkTag::UI_EXT, "called");
305 resultCallbacks_.insert(make_pair(requestCode, std::move(task)));
306 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->OpenAtomicService(want, options, token_, requestCode);
307 if (err != ERR_OK && err != AAFwk::START_ABILITY_WAITING) {
308 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", err);
309 OnAbilityResultInner(requestCode, err, want);
310 }
311 return err;
312 }
313
AddFreeInstallObserver(const sptr<IFreeInstallObserver> & observer)314 ErrCode UIExtensionContext::AddFreeInstallObserver(const sptr<IFreeInstallObserver> &observer)
315 {
316 ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->AddFreeInstallObserver(token_, observer);
317 if (ret != ERR_OK) {
318 TAG_LOGE(AAFwkTag::UI_EXT, "ret = %{public}d", ret);
319 }
320 return ret;
321 }
322
OpenLink(const AAFwk::Want & want,int requestCode)323 ErrCode UIExtensionContext::OpenLink(const AAFwk::Want& want, int requestCode)
324 {
325 TAG_LOGD(AAFwkTag::UI_EXT, "called");
326 return AAFwk::AbilityManagerClient::GetInstance()->OpenLink(want, token_, -1, requestCode);
327 }
328
GetResourceManager() const329 std::shared_ptr<Global::Resource::ResourceManager> UIExtensionContext::GetResourceManager() const
330 {
331 if (abilityResourceMgr_) {
332 return abilityResourceMgr_;
333 }
334
335 return ContextImpl::GetResourceManager();
336 }
337
SetAbilityResourceManager(std::shared_ptr<Global::Resource::ResourceManager> abilityResourceMgr)338 void UIExtensionContext::SetAbilityResourceManager(
339 std::shared_ptr<Global::Resource::ResourceManager> abilityResourceMgr)
340 {
341 abilityResourceMgr_ = abilityResourceMgr;
342 }
343
RegisterAbilityConfigUpdateCallback(AbilityConfigUpdateCallback abilityConfigUpdateCallback)344 void UIExtensionContext::RegisterAbilityConfigUpdateCallback(AbilityConfigUpdateCallback abilityConfigUpdateCallback)
345 {
346 abilityConfigUpdateCallback_ = abilityConfigUpdateCallback;
347 }
348
GetAbilityConfiguration() const349 std::shared_ptr<AppExecFwk::Configuration> UIExtensionContext::GetAbilityConfiguration() const
350 {
351 return abilityConfiguration_;
352 }
353
SetAbilityConfiguration(const AppExecFwk::Configuration & config)354 void UIExtensionContext::SetAbilityConfiguration(const AppExecFwk::Configuration &config)
355 {
356 if (!abilityConfiguration_) {
357 abilityConfiguration_ = std::make_shared<AppExecFwk::Configuration>(config);
358 TAG_LOGI(AAFwkTag::CONTEXT, "abilityConfiguration: %{public}s", abilityConfiguration_->GetName().c_str());
359 return;
360 }
361 std::vector<std::string> changeKeyV;
362 abilityConfiguration_->CompareDifferent(changeKeyV, config);
363 if (!changeKeyV.empty()) {
364 abilityConfiguration_->Merge(changeKeyV, config);
365 }
366 TAG_LOGI(AAFwkTag::CONTEXT, "abilityConfiguration: %{public}s", abilityConfiguration_->GetName().c_str());
367 }
368
SetAbilityColorMode(int32_t colorMode)369 void UIExtensionContext::SetAbilityColorMode(int32_t colorMode)
370 {
371 TAG_LOGI(AAFwkTag::CONTEXT, "SetAbilityColorMode colorMode: %{public}d", colorMode);
372 if (colorMode < -1 || colorMode > 1) {
373 TAG_LOGE(AAFwkTag::CONTEXT, "colorMode error");
374 return;
375 }
376 AppExecFwk::Configuration config;
377
378 config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, AppExecFwk::GetColorModeStr(colorMode));
379 config.AddItem(AAFwk::GlobalConfigurationKey::COLORMODE_IS_SET_BY_APP,
380 AppExecFwk::ConfigurationInner::IS_SET_BY_APP);
381 if (!abilityConfigUpdateCallback_) {
382 TAG_LOGE(AAFwkTag::CONTEXT, "abilityConfigUpdateCallback_ nullptr");
383 return;
384 }
385 abilityConfigUpdateCallback_(config);
386 }
387
388 int32_t UIExtensionContext::curRequestCode_ = 0;
389 std::mutex UIExtensionContext::requestCodeMutex_;
390 } // namespace AbilityRuntime
391 } // namespace OHOS
392