1// @ts-nocheck
2/*
3 * Copyright (c) 2021-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 Log from '../default/Log';
18import SourceLoaderFactory from './sourceloader/SourceLoaderFactory';
19import SourceLoader from './sourceloader/SourceLoader';
20import PluginSourceLoader from './sourceloader/PluginSourceLoader';
21import { FilterData, ItemComponentData, RootConfigInfo } from './common/Constants';
22import {
23  AbilityInfoWithId,
24  BundleEventType,
25  ListenerHandle,
26  queryAbility,
27  registerBundleListener,
28} from './common/BundleParseUtil';
29import { AbilityInfo } from 'bundle/abilityInfo';
30import { ExtensionAbilityInfo } from 'bundleManager/ExtensionAbilityInfo';
31
32export type PluginListener = {
33  onItemAdd: (itemData: ItemComponentData) => void;
34  onItemRemove: (itemData: ItemComponentData) => void;
35  onLoadPluginComponentData: (itemData: ItemComponentData) => void;
36};
37
38const TAG = 'PluginDataSourceManager';
39const INVALID_USERID = -1;
40
41export default class PluginDataSourceManager {
42  mAction = '';
43  mUserId: number = INVALID_USERID;
44  mListenerHandle: ListenerHandle | undefined = undefined;
45  mFilterDatas: Map<string, string> = new Map();
46  mLoaders: Map<string, SourceLoader> = new Map();
47  mFactory: SourceLoaderFactory;
48
49  constructor(listener: PluginListener) {
50    this.mFactory = new SourceLoaderFactory({
51      add: listener.onItemAdd,
52      remove: listener.onItemRemove,
53      onLoadPluginComponentData: listener.onLoadPluginComponentData,
54    });
55  }
56
57  initDataSource(configs: RootConfigInfo): void {
58    Log.showDebug(TAG, `initDataSource, configs: ${JSON.stringify(configs)}`);
59    this.mAction = configs.action;
60    configs.filterDatas.forEach((data: FilterData) => this.mFilterDatas.set(data.abilityName, data.id));
61    for (let pluginType in configs.loaderConfig) {
62      const sourceLoader = this.mFactory.getSourceLoader(pluginType, configs.loaderConfig[pluginType]);
63      if (sourceLoader instanceof SourceLoader) {
64        this.mLoaders.set(pluginType, sourceLoader);
65        Log.showInfo(TAG, `getSourceLoader plugin: ${pluginType}, loader${this.mLoaders.get(pluginType)}`);
66      }
67    }
68    Log.showDebug(TAG, `action:${this.mAction}, filterData: ${JSON.stringify(this.mFilterDatas)}`);
69    registerBundleListener(this, (handle) => {
70      this.mListenerHandle = handle;
71    });
72  }
73
74  async onBundleNotify(bundleName: string, event: BundleEventType): Promise<void> {
75    Log.showDebug(TAG, `onBundleNotify, bundleName: ${bundleName}, event: ${event}`);
76    if (event == BundleEventType.BUNDLE_CHANGE || event == BundleEventType.BUNDLE_REMOVE) {
77      this.mLoaders.forEach((loader) => loader.onBundleRemove(bundleName));
78    }
79    if (event == BundleEventType.BUNDLE_CHANGE || event == BundleEventType.BUNDLE_ADD) {
80      let abilityInfos = await queryAbility(this.mAction, this.mUserId, bundleName);
81      Log.showInfo(TAG, `abilityInfos: ${JSON.stringify(abilityInfos)}`);
82      abilityInfos.forEach((info) => this.notifyAbilityAdd(info));
83    }
84  }
85
86  clearAll(): void {
87    Log.showDebug(TAG, 'clearAll');
88    this.unregisterListener();
89    this.mLoaders.forEach((sourceLoader) => sourceLoader.clearData());
90  }
91
92  async loadData(userId: number): Promise<void> {
93    Log.showDebug(TAG, `loadData, userId: ${userId}, this.mUserId: ${this.mUserId}`);
94    if (this.mUserId != userId) {
95      Log.showDebug(TAG, `loadData, queryAbility`);
96      this.mUserId = userId;
97      this.mLoaders.forEach((sourceLoader) => sourceLoader.clearData());
98      let abilityInfos = await queryAbility(this.mAction, this.mUserId);
99      Log.showDebug(TAG, `loadData, abilityInfos: ${JSON.stringify(abilityInfos)}`);
100      abilityInfos.forEach((info) => this.notifyAbilityAdd(info));
101    }
102    this.mLoaders.forEach((sourceLoader) => sourceLoader.reloadData(this.mUserId));
103    Log.showDebug(TAG, `loadData, end`);
104  }
105
106  private notifyAbilityAdd(info: AbilityInfo | ExtensionAbilityInfo): void {
107    Log.showDebug(TAG, `notifyAbilityAdd, info: ${JSON.stringify(info)}`);
108    let itemId = this.mFilterDatas.get(info.name);
109    if (!itemId) {
110      Log.showError(TAG, `notifyAbilityAdd, can't find itemId, ability:${info.name}`);
111      return;
112    }
113    let abilityInfo: AbilityInfoWithId = {
114      ...info,
115      itemId: itemId,
116    };
117    if ((!abilityInfo.metaData || !abilityInfo.metaData.length) && (!abilityInfo.metadata || !abilityInfo.metadata.length)) {
118      Log.showError(TAG, `Can't find metadata, abilityId: ${abilityInfo.name}`);
119      return;
120    }
121    this.mLoaders.forEach((loader) => loader.onAbilityAdd(abilityInfo));
122  }
123
124  private unregisterListener(): void {
125    this.mListenerHandle?.unRegister();
126    this.mListenerHandle = undefined;
127  }
128
129  async updatePluginComponentData(pluginComponentData: ItemComponentData): Promise<void> {
130    Log.showInfo(TAG, 'updatePluginComponentData');
131    this.mLoaders.forEach((loader) => {
132      if (loader instanceof PluginSourceLoader) {
133        (loader as PluginSourceLoader).onUpdatePluginComponentData(pluginComponentData);
134      }
135    });
136  }
137}