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 */ 15if (!("finalizeConstruction" in ViewPU.prototype)) { 16 Reflect.set(ViewPU.prototype, "finalizeConstruction", () => { 17 }); 18} 19const hilog = requireNapi('hilog'); 20const abilityManager = requireNapi('app.ability.abilityManager'); 21const commonEventManager = requireNapi('commonEventManager'); 22const bundleManager = requireNapi('bundle.bundleManager'); 23const BusinessError = requireNapi('base'); 24const api20 = 20; 25const t = 100014; 26const u = 801; 27const requestComponentTerminateKey = 'ohos.param.key.requestComponentTerminate'; 28const atomicServiceDataTag = "ohos.atomicService.window"; 29 30export class FullScreenLaunchComponent extends ViewPU { 31 constructor(parent, params, __localStorage, elmtId = -1, paramsLambda = undefined, extraInfo) { 32 super(parent, __localStorage, elmtId, extraInfo); 33 if (typeof paramsLambda === "function") { 34 this.paramsGenerator_ = paramsLambda; 35 } 36 this.content = this.doNothingBuilder; 37 this.context = getContext(this); 38 this.appId = ""; 39 this.options = undefined; 40 this.__isShow = new ObservedPropertySimplePU(false, this, "isShow"); 41 this.subscriber = null; 42 this.apiVersion = 0; 43 this.onError = undefined; 44 this.onTerminated = undefined; 45 this.onReceive = undefined; 46 this.setInitiallyProvidedValue(params); 47 this.finalizeConstruction(); 48 } 49 setInitiallyProvidedValue(params) { 50 if (params.content !== undefined) { 51 this.content = params.content; 52 } 53 if (params.context !== undefined) { 54 this.context = params.context; 55 } 56 if (params.appId !== undefined) { 57 this.appId = params.appId; 58 } 59 if (params.options !== undefined) { 60 this.options = params.options; 61 } 62 if (params.isShow !== undefined) { 63 this.isShow = params.isShow; 64 } 65 if (params.subscriber !== undefined) { 66 this.subscriber = params.subscriber; 67 } 68 if (params.apiVersion !== undefined) { 69 this.apiVersion = params.apiVersion; 70 } 71 if (params.onError !== undefined) { 72 this.onError = params.onError; 73 } 74 if (params.onTerminated !== undefined) { 75 this.onTerminated = params.onTerminated; 76 } 77 if (params.onReceive !== undefined) { 78 this.onReceive = params.onReceive; 79 } 80 } 81 updateStateVars(params) { 82 } 83 purgeVariableDependenciesOnElmtId(rmElmtId) { 84 this.__isShow.purgeDependencyOnElmtId(rmElmtId); 85 } 86 aboutToBeDeleted() { 87 this.__isShow.aboutToBeDeleted(); 88 SubscriberManager.Get().delete(this.id__()); 89 this.aboutToBeDeletedInternal(); 90 } 91 get isShow() { 92 return this.__isShow.get(); 93 } 94 set isShow(newValue) { 95 this.__isShow.set(newValue); 96 } 97 aboutToAppear() { 98 let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION | 99 bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_METADATA; 100 try { 101 bundleManager.getBundleInfoForSelf(bundleFlags).then((data) => { 102 hilog.info(0x3900, 'FullScreenLaunchComponent', 'getBundleInfoForSelf success, data: %{public}s.', JSON.stringify(data.targetVersion % 1000)); 103 this.apiVersion = data.targetVersion % 1000; 104 }).catch((err) => { 105 hilog.error(0x3900, 'FullScreenLaunchComponent', 'getBundleInfoForSelf fail_1, cause: %{public}s.', err.message); 106 }); 107 } 108 catch (err) { 109 let message = err.message; 110 hilog.error(0x3900, 'FullScreenLaunchComponent', 'getBundleInfoForSelf fail_2, cause: %{public}s.', message); 111 } 112 let subscribeInfo = { 113 events: [commonEventManager.Support.COMMON_EVENT_DISTRIBUTED_ACCOUNT_LOGOUT], 114 }; 115 commonEventManager.createSubscriber(subscribeInfo, (err, data) => { 116 if (err) { 117 hilog.error(0x3900, 'FullScreenLaunchComponent', 'Failed to create subscriber, err: %{public}s.', JSON.stringify(err)); 118 return; 119 } 120 if (data == null || data == undefined) { 121 hilog.error(0x3900, 'FullScreenLaunchComponent', 'Failed to create subscriber, data is null.'); 122 return; 123 } 124 this.subscriber = data; 125 commonEventManager.subscribe(this.subscriber, (err, data) => { 126 if (err) { 127 hilog.error(0x3900, 'FullScreenLaunchComponent', 'Failed to subscribe common event, err: %{public}s.', JSON.stringify(err)); 128 return; 129 } 130 hilog.info(0x3900, 'FullScreenLaunchComponent', 'Received account logout event.'); 131 this.isShow = false; 132 }); 133 }); 134 } 135 aboutToDisappear() { 136 if (this.subscriber !== null) { 137 commonEventManager.unsubscribe(this.subscriber, (err) => { 138 if (err) { 139 hilog.error(0x3900, 'FullScreenLaunchComponent', 'UnsubscribeCallBack, err: %{public}s.', JSON.stringify(err)); 140 } 141 else { 142 hilog.info(0x3900, 'FullScreenLaunchComponent', 'Unsubscribe.'); 143 this.subscriber = null; 144 } 145 }); 146 } 147 } 148 doNothingBuilder(parent = null) { 149 } 150 resetOptions() { 151 if (this.options?.parameters) { 152 this.options.parameters['ohos.extra.param.key.showMode'] = 1; 153 this.options.parameters['ability.want.params.IsNotifyOccupiedAreaChange'] = true; 154 this.options.parameters['ability.want.params.IsModal'] = true; 155 this.options.parameters['ohos.extra.atomicservice.param.key.isFollowHostWindowMode'] = (this.apiVersion >= api20); 156 hilog.info(0x3900, 'FullScreenLaunchComponent', 'replaced options is %{public}s !', JSON.stringify(this.options)); 157 } 158 else { 159 this.options = { 160 parameters: { 161 'ohos.extra.param.key.showMode': 1, 162 'ability.want.params.IsNotifyOccupiedAreaChange': true, 163 'ability.want.params.IsModal': true, 164 'ohos.extra.atomicservice.param.key.isFollowHostWindowMode': (this.apiVersion >= api20) 165 } 166 }; 167 } 168 } 169 async checkAbility() { 170 this.resetOptions(); 171 abilityManager.queryAtomicServiceStartupRule(this.context, this.appId) 172 .then((data) => { 173 if (data.isOpenAllowed) { 174 if (data.isEmbeddedAllowed) { 175 this.isShow = true; 176 hilog.info(0x3900, 'FullScreenLaunchComponent', 'EmbeddedOpen is Allowed!'); 177 } 178 else { 179 this.popUp(); 180 hilog.info(0x3900, 'FullScreenLaunchComponent', 'popUp is Allowed!'); 181 } 182 } 183 else { 184 hilog.info(0x3900, 'FullScreenLaunchComponent', 'is not allowed open!'); 185 } 186 }).catch((err) => { 187 hilog.error(0x3900, 'FullScreenLaunchComponent', 'queryAtomicServiceStartupRule called error!%{public}d:%{public}s', err.code, err.message); 188 if (u === err.code) { 189 this.popUp(); 190 } 191 }); 192 } 193 async popUp() { 194 this.isShow = false; 195 try { 196 const ability = await this.context.openAtomicService(this.appId, this.options); 197 hilog.info(0x3900, 'FullScreenLaunchComponent', '%{public}s open service success!', ability.want); 198 } 199 catch (e) { 200 hilog.error(0x3900, 'FullScreenLaunchComponent', '%{public}s open service error!', e.message); 201 } 202 } 203 initialRender() { 204 this.observeComponentCreation2((elmtId, isInitialRender) => { 205 Row.create(); 206 Row.justifyContent(FlexAlign.Center); 207 Row.onClick(() => { 208 this.checkAbility(); 209 }); 210 Row.bindContentCover({ value: this.isShow, changeEvent: newValue => { this.isShow = newValue; } }, { builder: () => { 211 this.uiExtensionBuilder.call(this); 212 } }); 213 }, Row); 214 this.content.bind(this)(); 215 Row.pop(); 216 } 217 uiExtensionBuilder(parent = null) { 218 this.observeComponentCreation2((elmtId, isInitialRender) => { 219 UIExtensionComponent.create({ 220 bundleName: `com.atomicservice.${this.appId}`, 221 flags: this.options?.flags, 222 parameters: this.options?.parameters 223 }, { 224 windowModeFollowStrategy: this.apiVersion >= api20 ? WindowModeFollowStrategy.FOLLOW_HOST_WINDOW_MODE : 225 WindowModeFollowStrategy.FOLLOW_UI_EXTENSION_ABILITY_WINDOW_MODE 226 }); 227 UIExtensionComponent.height('100%'); 228 UIExtensionComponent.width('100%'); 229 UIExtensionComponent.onError(err => { 230 if (this.onError != undefined) { 231 this.onError(err); 232 } 233 this.isShow = false; 234 hilog.error(0x3900, 'FullScreenLaunchComponent', 'call up UIExtension error:%{public}d!%{public}s', err.code, err.message); 235 if (err.code != t) { 236 this.getUIContext().showAlertDialog({ 237 message: err.message 238 }); 239 } 240 }); 241 UIExtensionComponent.onTerminated(info => { 242 this.isShow = false; 243 if (this.onTerminated != undefined) { 244 this.onTerminated(info); 245 } 246 }); 247 UIExtensionComponent.onReceive(data => { 248 if (this.onReceive !== undefined) { 249 const sourceKeys = Object.keys(data); 250 let atomicServiceData = {}; 251 for (let i = 0; i < sourceKeys.length; i++) { 252 if (sourceKeys[i].includes(atomicServiceDataTag)) { 253 atomicServiceData[sourceKeys[i]] = data[sourceKeys[i]]; 254 } 255 } 256 this.onReceive(atomicServiceData); 257 } 258 if (data[requestComponentTerminateKey]) { 259 this.isShow = false; 260 } 261 }); 262 }, UIExtensionComponent); 263 } 264 rerender() { 265 this.updateDirtyElements(); 266 } 267} 268 269export default { FullScreenLaunchComponent }