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 ServiceExtensionContext from "application/ServiceExtensionContext";
17import {Log} from "../Log";
18import {EventParser, START_ABILITY_EVENT, Event, LocalEvent} from "./EventUtil";
19import {Callback, createEventBus, EventBus} from "./EventBus";
20
21export type unsubscribe = () => void;
22export type Events = string | string[];
23
24const TAG = "EventManagerSc";
25
26export class EventManager {
27    mEventBus: EventBus<string>;
28    eventParser: EventParser;
29    mContext: ServiceExtensionContext | undefined;
30
31    static getInstance(): EventManager {
32        if (globalThis.EventManager == null) {
33            globalThis.EventManager = new EventManager();
34        }
35        return globalThis.EventManager;
36    }
37
38    constructor() {
39        this.mEventBus = createEventBus();
40        this.eventParser = {
41            local: this.publishLocalEvent,
42            ability: this.startAbility,
43            commonEvent: this.publishCommonEvent,
44            remote: this.publishRemoteEvent,
45        };
46    }
47
48    setContext(ctx: ServiceExtensionContext) {
49        this.mContext = ctx;
50    }
51
52    publish(event: Event): boolean {
53        return this.eventParser[event.target].call(this, event.data);
54    }
55
56    subscribe(eventType: Events, callback: Callback): unsubscribe {
57        return this.mEventBus.on(eventType, callback);
58    }
59
60    subscribeOnce(eventType: string, callback: Callback): unsubscribe {
61        return this.mEventBus.once(eventType, callback);
62    }
63
64    private publishLocalEvent(data: LocalEvent): boolean {
65        Log.showInfo(TAG, `publish localEvent type: ${data.eventName}`);
66        if (data.eventName) {
67            this.mEventBus.emit(data.eventName, data.args);
68            return true;
69        }
70        return false;
71    }
72
73    private startAbility(data: { [key: string]: any }): boolean {
74        Log.showInfo(TAG, `start Ability: ${data.abilityName}`);
75        if (data.bundleName && data.abilityName && this.mContext) {
76            this.mEventBus.emit(START_ABILITY_EVENT, { abilityName: data.abilityName });
77            this.mContext.startAbility({
78                bundleName: data.bundleName,
79                abilityName: data.abilityName,
80                parameters: data.args??undefined
81            });
82            return true;
83        }
84        return false;
85    }
86
87    private publishRemoteEvent(data: { [key: string]: any }): boolean {
88        return false;
89    }
90
91    private publishCommonEvent(data: { [key: string]: any }): boolean {
92        return false;
93    }
94}
95
96export let sEventManager = EventManager.getInstance();