1/* 2 * Copyright (c) 2022 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 16import extension from '@ohos.app.ability.ServiceExtensionAbility'; 17import window from '@ohos.window'; 18import display from '@ohos.display'; 19import rpc from '@ohos.rpc'; 20import { GlobalContext } from '../common/utils/globalContext'; 21import dialogRequest from '@ohos.app.ability.dialogRequest'; 22import deviceInfo from '@ohos.deviceInfo'; 23 24const TAG = 'PermissionManager_Log: '; 25const BG_COLOR = '#00000000'; 26const DEFAULT_CORNER_RADIUS_L = 16; 27const RESULT_CODE_1 = 1; 28const ACCESS_TOKEN = 'ohos.security.accesstoken.tokencallback'; 29 30export default class ServiceExtensionAbility extends extension { 31 /** 32 * Lifecycle function, called back when a service extension is started for initialization. 33 */ 34 onCreate(want): void { 35 console.info(TAG + 'ServiceExtensionAbility onCreate, ability name is ' + want.abilityName); 36 37 globalThis.windowNum = 0; 38 } 39 40 /** 41 * Lifecycle function, called back when a service extension is started or recall. 42 */ 43 onRequest(want, startId): void { 44 console.info(TAG + 'ServiceExtensionAbility onRequest. start id is ' + startId); 45 console.info(TAG + 'want: ' + JSON.stringify(want)); 46 if (deviceInfo.deviceType === 'wearable') { 47 this.context.terminateSelf(); 48 console.info(TAG + 'ServiceExtensionAbility terminateSelf'); 49 return; 50 } 51 52 try { 53 let dis = display.getDefaultDisplaySync(); 54 let navigationBarRect = { 55 left: 0, 56 top: 0, 57 width: dis.width, 58 height: dis.height 59 }; 60 this.createWindow('permissionDialog' + startId, window.WindowType.TYPE_DIALOG, navigationBarRect, want); 61 } catch (exception) { 62 console.error(TAG + 'Failed to obtain the default display object. Code: ' + JSON.stringify(exception)); 63 }; 64 } 65 66 /** 67 * Lifecycle function, called back before a service extension is destroyed. 68 */ 69 onDestroy(): void { 70 console.info(TAG + 'ServiceExtensionAbility onDestroy.'); 71 } 72 73 private async createWindow(name: string, windowType, rect, want): Promise<void> { 74 let requestInfo: dialogRequest.RequestInfo; 75 try { 76 requestInfo = dialogRequest.getRequestInfo(want); 77 } catch (err) { 78 console.error(`getRequestInfo err= ${JSON.stringify(err)}`); 79 } 80 81 console.info(TAG + 'create window start, requestInfo: ' + JSON.stringify(requestInfo)); 82 let rectInfo = requestInfo ? requestInfo.windowRect : rect; 83 rectInfo = rectInfo.width === 0 ? rect : rectInfo; 84 try { 85 const win = await window.createWindow({ ctx: this.context, name, windowType }); 86 console.info(TAG + 'createWindow end.'); 87 let storage: LocalStorage = new LocalStorage({ 'want': want, 'win': win }); 88 await this.BindDialogTarget(win, want); 89 console.info(TAG + 'bindDialogTarget end.'); 90 await win.moveWindowTo(rectInfo.left, rectInfo.top); 91 console.info(TAG + 'moveWindowTo end.'); 92 await win.resize(rectInfo.width, rectInfo.height); 93 console.info(TAG + 'resize end.'); 94 await win.loadContent('pages/dialogPlus', storage); 95 win.setWindowBackgroundColor(BG_COLOR); 96 if (rectInfo.width < rect.width) { 97 win.setCornerRadius(DEFAULT_CORNER_RADIUS_L); 98 } 99 await win.showWindow(); 100 console.info(TAG + 'showWindow end.'); 101 globalThis.windowNum ++; 102 GlobalContext.store('windowNum', globalThis.windowNum); 103 } catch (err) { 104 console.error(TAG + `window create failed! err: ${JSON.stringify(err)}`); 105 } 106 } 107 108 private async BindDialogTarget(win, want): Promise<void> { 109 let proxy = want.parameters['ohos.ability.params.callback'].value; 110 win.bindDialogTarget(want.parameters['ohos.ability.params.token'].value, () => { 111 let option = new rpc.MessageOption(); 112 let data = new rpc.MessageSequence(); 113 let reply = new rpc.MessageSequence(); 114 try { 115 data.writeInterfaceToken(ACCESS_TOKEN); 116 proxy.sendMessageRequest(RESULT_CODE_1, data, reply, option); 117 } catch (err) { 118 console.error(TAG + `write result failed: ${JSON.stringify(err)}`); 119 } finally { 120 data.reclaim(); 121 reply.reclaim(); 122 } 123 let windowNum = GlobalContext.load('windowNum'); 124 windowNum --; 125 GlobalContext.store('windowNum', windowNum); 126 win.destroyWindow(); 127 if (windowNum === 0) { 128 this.context.terminateSelf(); 129 } 130 }); 131 } 132};