• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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