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