1/* 2 * Copyright (c) 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 */ 15import hilog from '@ohos.hilog'; 16import abilityManager from '@ohos.app.ability.abilityManager'; 17import common from '@ohos.app.ability.common'; 18import { Callback } from '@ohos.base'; 19import AtomicServiceOptions from '@ohos.app.ability.AtomicServiceOptions'; 20import commonEventManager from '@ohos.commonEventManager'; 21import Base from '@ohos.base'; 22 23export class LaunchController { 24 public launchAtomicService = (appId: string, options?: AtomicServiceOptions) => {}; 25} 26 27const EMBEDDED_FULL_MODE: number = 1; 28 29@Component 30export struct InnerFullScreenLaunchComponent { 31 @BuilderParam content: Callback<void> = this.doNothingBuilder; 32 private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; 33 controller: LaunchController = new LaunchController(); 34 private appId: string = ''; 35 private options?: AtomicServiceOptions; 36 @State private isShow: boolean = false; 37 private subscriber: commonEventManager.CommonEventSubscriber | null = null; 38 private launchAtomicService = (appId: string, options?: AtomicServiceOptions) => { 39 hilog.info(0x3900, 'InnerFullScreenLaunchComponent', 40 'launchAtomicService, appId: %{public}s.', appId); 41 this.appId = appId; 42 this.options = options; 43 this.checkAbility(); 44 } 45 46 aboutToAppear() { 47 let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = { 48 events: [commonEventManager.Support.COMMON_EVENT_DISTRIBUTED_ACCOUNT_LOGOUT], 49 }; 50 51 commonEventManager.createSubscriber(subscribeInfo, 52 (err:Base.BusinessError, data: commonEventManager.CommonEventSubscriber) => { 53 if (err) { 54 hilog.error(0x3900, 'InnerFullScreenLaunchComponent', 55 'Failed to create subscriber, err: %{public}s.', err.message); 56 return; 57 } 58 59 if (data == null || data == undefined) { 60 hilog.error(0x3900, 'InnerFullScreenLaunchComponent', 'Failed to create subscriber, data is null.'); 61 return; 62 } 63 64 this.subscriber = data; 65 commonEventManager.subscribe(this.subscriber, 66 (err: Base.BusinessError, data: commonEventManager.CommonEventData) => { 67 if (err) { 68 hilog.error(0x3900, 'InnerFullScreenLaunchComponent', 69 'Failed to subscribe common event, err: %{public}s.', err.message); 70 return; 71 } 72 73 hilog.info(0x3900, 'InnerFullScreenLaunchComponent', 'Received account logout event.'); 74 this.isShow = false; 75 }) 76 }) 77 this.controller.launchAtomicService = this.launchAtomicService; 78 } 79 80 aboutToDisappear() { 81 if (this.subscriber !== null) { 82 commonEventManager.unsubscribe(this.subscriber, (err) => { 83 if (err) { 84 hilog.error(0x3900, 'InnerFullScreenLaunchComponent', 85 'UnsubscribeCallBack, err: %{public}s.', err.message); 86 } else { 87 hilog.info(0x3900, 'InnerFullScreenLaunchComponent', 'Unsubscribe.'); 88 this.subscriber = null; 89 } 90 }) 91 } 92 } 93 94 @Builder 95 doNothingBuilder() { 96 }; 97 98 resetOptions() { 99 if (this.options?.parameters) { 100 this.options.parameters['ohos.extra.param.key.showMode'] = EMBEDDED_FULL_MODE; 101 this.options.parameters['ability.want.params.IsNotifyOccupiedAreaChange'] = true; 102 hilog.info(0x3900, 'InnerFullScreenLaunchComponent', 'replaced options is %{public}s !', JSON.stringify(this.options)); 103 } else { 104 this.options = { 105 parameters: { 106 'ohos.extra.param.key.showMode': EMBEDDED_FULL_MODE, 107 'ability.want.params.IsNotifyOccupiedAreaChange': true, 108 } 109 }; 110 } 111 } 112 113 async checkAbility() { 114 this.resetOptions(); 115 try { 116 const res: boolean = await abilityManager.isEmbeddedOpenAllowed(this.context, this.appId); 117 if (res) { 118 this.isShow = true; 119 hilog.info(0x3900, 'InnerFullScreenLaunchComponent', ' EmbeddedOpen is Allowed!'); 120 } else { 121 hilog.info(0x3900, 'InnerFullScreenLaunchComponent', ' EmbeddedOpen is not Allowed!'); 122 this.popUp(); 123 } 124 } catch (e) { 125 hilog.error(0x3900, 'InnerFullScreenLaunchComponent', 'isEmbeddedOpenAllowed called error!%{public}s', e.message); 126 } 127 } 128 129 async popUp() { 130 this.isShow = false; 131 try { 132 const ability = await this.context.openAtomicService(this.appId, this.options); 133 hilog.info(0x3900, 'InnerFullScreenLaunchComponent', '%{public}s open service success!', ability.want); 134 } catch (e) { 135 hilog.error(0x3900, 'InnerFullScreenLaunchComponent', '%{public}s open service error!', e.message); 136 } 137 } 138 139 build() { 140 Row() { 141 this.content(); 142 } 143 .justifyContent(FlexAlign.Center) 144 .bindContentCover($$this.isShow, this.uiExtensionBuilder()) 145 } 146 147 @Builder 148 uiExtensionBuilder() { 149 UIExtensionComponent({ 150 bundleName: `com.atomicservice.${this.appId}`, 151 flags: this.options?.flags, 152 parameters: this.options?.parameters 153 }) 154 .backgroundColor($r('sys.color.ohos_id_color_titlebar_bg')) 155 .defaultFocus(true) 156 .height('100%') 157 .width('100%') 158 .onRelease( 159 () => { 160 hilog.error(0x3900, 'InnerFullScreenLaunchComponent', 'onRelease'); 161 this.isShow = false; 162 } 163 ).onError( 164 err => { 165 this.isShow = false; 166 hilog.error(0x3900, 'InnerFullScreenLaunchComponent', 'call up UIExtension error! %{public}s', err.message); 167 this.getUIContext().showAlertDialog({ 168 message: err.message 169 }); 170 } 171 ) 172 } 173}