1// @ts-nocheck 2/* 3 * Copyright (c) 2022 Huawei Device Co., Ltd. 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import bundleManager from '@ohos.bundle.bundleManager'; 18import commonEvent from '@ohos.commonEvent'; 19import { AbilityInfo } from 'bundleManager/AbilityInfo'; 20import { ExtensionAbilityInfo } from 'bundleManager/ExtensionAbilityInfo'; 21import { CustomizeData } from 'bundle/customizeData'; 22import { Metadata } from 'bundleManager/Metadata'; 23import Log from '../../default/Log'; 24import switchUserManager from '../../default/SwitchUserManager'; 25 26export type AbilityInfoWithId = (AbilityInfo | ExtensionAbilityInfo) & { itemId: string }; 27export type BundleListener = { 28 onBundleNotify: (bundleName: string, event: BundleEventType) => void; 29}; 30export type ListenerHandle = { 31 unRegister: () => void; 32}; 33export type PluginData = { 34 [key: string | number]: any; 35}; 36 37export enum BundleEventType { 38 BUNDLE_ADD, 39 BUNDLE_CHANGE, 40 BUNDLE_REMOVE, 41 UNKNOWN_EVENT, 42} 43 44const TAG = 'SourceLoader-BundleParseUtil'; 45const DEFAULT_BUNDLE_FLAG = 46 bundleManager.AbilityFlag.GET_ABILITY_INFO_WITH_METADATA | bundleManager.AbilityFlag.GET_ABILITY_INFO_WITH_PERMISSION; 47 48const BUNDLE_SUBSCRIBE_INFO = { 49 events: [ 50 commonEvent.Support.COMMON_EVENT_PACKAGE_ADDED, 51 commonEvent.Support.COMMON_EVENT_PACKAGE_REMOVED, 52 commonEvent.Support.COMMON_EVENT_PACKAGE_CHANGED, 53 ], 54}; 55 56export async function queryAbility(action: string, userId: number, bundleName?: string): Promise<(AbilityInfo | ExtensionAbilityInfo)[]> { 57 Log.showDebug(TAG, `queryAbility, action: ${action} , userId: ${userId}`); 58 if (bundleName) { 59 Log.showDebug(TAG, `queryAbility, bundleName: ${bundleName}`); 60 return await queryAbilityWithBundleName(action, userId, bundleName); 61 } 62 return await queryAbilityWithoutBundleName(action, userId); 63} 64 65async function queryAbilityWithBundleName(action: string, userId: number, bundleName: string): Promise<(AbilityInfo | ExtensionAbilityInfo)[]> { 66 Log.showInfo(TAG, `queryAbilityWithBundleName, action: ${action} bundleName: ${bundleName}`); 67 let abilitys: AbilityInfo[] = []; 68 try { 69 abilitys = await bundleManager.queryAbilityInfo( 70 { 71 action: action, 72 bundleName: bundleName, 73 }, 74 DEFAULT_BUNDLE_FLAG, 75 userId 76 ); 77 } catch (error) { 78 Log.showError(TAG, `queryAbilityWithBundleName, queryAbilityByWant error: ${JSON.stringify(error)}`); 79 } 80 let extensionAbilitys: ExtensionAbilityInfo[] = []; 81 try { 82 extensionAbilitys = await bundleManager.queryExtensionAbilityInfo( 83 { 84 action: action, 85 bundleName: bundleName, 86 }, 87 bundleManager.ExtensionAbilityType.UNSPECIFIED, 88 DEFAULT_BUNDLE_FLAG, 89 userId 90 ); 91 } catch (error) { 92 Log.showError(TAG, `queryAbilityWithBundleName, queryExtensionAbilityInfo error: ${JSON.stringify(error)}`); 93 } 94 Log.showDebug(TAG, 'queryAbilityWithBundleName, end'); 95 let rets = [...abilitys, ...extensionAbilitys]; 96 Log.showDebug(TAG, `queryAbilityWithBundleName, rets: ${JSON.stringify(rets)}`); 97 return rets; 98} 99 100async function queryAbilityWithoutBundleName(action: string, userId: number): Promise<(AbilityInfo | ExtensionAbilityInfo)[]> { 101 Log.showInfo(TAG, `queryAbilityWithoutBundleName, action: ${action}`); 102 let abilitys: AbilityInfo[] = []; 103 try { 104 abilitys = await bundleManager.queryAbilityInfo({ action: action }, DEFAULT_BUNDLE_FLAG, userId); 105 } catch (error) { 106 Log.showError(TAG, `queryAbilityWithoutBundleName, queryAbilityByWant error: ${JSON.stringify(error)}`); 107 } 108 let extensionAbilitys: ExtensionAbilityInfo[] = []; 109 try { 110 extensionAbilitys = await bundleManager.queryExtensionAbilityInfo({ 111 action: action 112 }, bundleManager.ExtensionAbilityType.UNSPECIFIED, DEFAULT_BUNDLE_FLAG, userId); 113 } catch (error) { 114 Log.showError(TAG, `queryAbilityWithoutBundleName, queryExtensionAbilityInfo error: ${JSON.stringify(error)}`); 115 } 116 Log.showDebug(TAG, 'queryAbilityWithoutBundleName, end'); 117 let rets = [...abilitys, ...extensionAbilitys]; 118 Log.showDebug(TAG, `queryAbilityWithoutBundleName, rets: ${JSON.stringify(rets)}`); 119 return rets; 120} 121 122export function filterAbilityInfo(info: AbilityInfoWithId, filterKey: string): PluginData | undefined { 123 Log.showInfo(TAG, `filterAbilityInfo, info: ${JSON.stringify(info)} filterKey: ${filterKey}`); 124 let pluginDatas: (CustomizeData | Metadata)[] = []; 125 if (info.metaData && info.metaData.length) { 126 pluginDatas = info.metaData.filter((data) => data.name == filterKey); 127 } else if (info.metadata && info.metadata.length) { 128 pluginDatas = info.metadata.filter((data) => data.name == filterKey); 129 } 130 Log.showInfo(TAG, `filterAbilityInfo, pluginDatas: ${JSON.stringify(pluginDatas)}`); 131 if (!pluginDatas.length) { 132 Log.showDebug(TAG, `filterKey: ${filterKey}, metadata: ${JSON.stringify(info.metadata.values)}`); 133 return undefined; 134 } 135 let pluginData: PluginData; 136 if (pluginDatas[0].value && pluginDatas[0].value.length > 0) { 137 pluginData = JSON.parse('{' + pluginDatas[0].value + '}') as PluginData; 138 } else if (pluginDatas[0].extra && pluginDatas[0].extra.length > 0) { 139 pluginData = JSON.parse('{' + pluginDatas[0].extra + '}') as PluginData; 140 } 141 if (!pluginData) { 142 Log.showError(TAG, `Can't parse pluginData: ${pluginDatas[0]}, filterKey: ${filterKey}`); 143 return undefined; 144 } 145 Log.showInfo(TAG, `filterAbilityInfo, pluginData: ${JSON.stringify(pluginData)}`); 146 return pluginData; 147} 148 149export function registerBundleListener(listener: BundleListener, callback: (handle: ListenerHandle) => void): void { 150 commonEvent.createSubscriber(BUNDLE_SUBSCRIBE_INFO, (err, handle) => { 151 Log.showDebug(TAG, `registerBundleListener, err: ${JSON.stringify(err)}, handle: ${handle}`); 152 if (err.code != 0) { 153 Log.showError(TAG, `Can't regitser bundle subscribe, err: ${JSON.stringify(err)}`); 154 return; 155 } 156 commonEvent.subscribe(handle, (err, data) => { 157 Log.showInfo(TAG, `bundle change, err: ${JSON.stringify(err)} data: ${JSON.stringify(data)}`); 158 if (err.code != 0) { 159 Log.showError(TAG, `Can't handle bundle change, err: ${JSON.stringify(err)}`); 160 return; 161 } 162 163 switchUserManager.getInstance() 164 .getCurrentUserInfo() 165 .then((userInfo) => { 166 if (data.parameters.userId != userInfo.userId) { 167 return; 168 } else { 169 let event = BundleEventType.UNKNOWN_EVENT; 170 switch (data.event) { 171 case commonEvent.Support.COMMON_EVENT_PACKAGE_ADDED: 172 event = BundleEventType.BUNDLE_ADD; 173 break; 174 case commonEvent.Support.COMMON_EVENT_PACKAGE_CHANGED: 175 event = BundleEventType.BUNDLE_CHANGE; 176 break; 177 case commonEvent.Support.COMMON_EVENT_PACKAGE_REMOVED: 178 event = BundleEventType.BUNDLE_REMOVE; 179 break; 180 default: 181 Log.showError(TAG, `unknow event: ${event}`); 182 } 183 listener.onBundleNotify(data.bundleName ?? 'unkown', event); 184 } 185 }); 186 }); 187 callback({ 188 unRegister: () => { 189 commonEvent.unsubscribe(handle, () => { 190 Log.showInfo(TAG, `unRegister bundle info listener, handle: ${handle}`); 191 }); 192 }, 193 }); 194 }); 195} 196