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 commonEvent from "@ohos.commonEvent";
17import {CommonEventData} from "commonEvent/commonEventData";
18import {sEventManager} from "../event/EventManager";
19import {Log} from "../Log";
20import {SCREEN_CHANGE_EVENT} from "../ScreenLockManager";
21
22export type CommonEventManager = {
23  subscriberCommonEvent: () => Promise<void>;
24  unSubscriberCommonEvent: () => void;
25  applyPolicy: (policys: Array<POLICY>) => void;
26  release: () => void;
27};
28
29export enum POLICY {
30  SCREEN_POLICY = "screenOnOffPolicy",
31}
32
33type ClearPolicy = () => void;
34type InnerManager = { subscriberCommonEvent: () => void; unSubscriberCommonEvent: () => void };
35const policyMap: { [key in POLICY]: (manager: InnerManager) => ClearPolicy } = {
36  screenOnOffPolicy: ScreenPolicy,
37};
38
39export function getCommonEventManager(
40  tag: string,
41  subscribeInfos: { events: Array<string> },
42  commonEventCallback: (data: CommonEventData) => void,
43  subscribeStateChange?: (isSubscribe: boolean) => void
44): CommonEventManager {
45  const TAG = `CommonEvent_${tag}`;
46  const SUBSCRIBE_INFOS = subscribeInfos;
47  let unSubcribers: Array<() => void> = [];
48  let policyClearCb: Map<POLICY, ClearPolicy> | undefined = undefined;
49
50  async function subscriberCommonEvent() {
51    Log.showDebug(TAG, "registerSubscriber start");
52    let subscriber = await commonEvent.createSubscriber(SUBSCRIBE_INFOS);
53    commonEvent.subscribe(subscriber, (err, data) => {
54      if (err.code != 0) {
55        Log.showError(TAG, `Can't handle common event, err: ${JSON.stringify(err)}`);
56        return;
57      }
58      Log.showInfo(TAG, `handle common event: ${data.event}`);
59      commonEventCallback(data);
60    });
61    unSubcribers.push(() => commonEvent.unsubscribe(subscriber));
62    subscribeStateChange && subscribeStateChange(true);
63    Log.showInfo(TAG, `registerSubscriber success, size: ${unSubcribers.length}`);
64  }
65
66  function unSubscriberCommonEvent() {
67    Log.showDebug(TAG, `UnSubcribers size: ${unSubcribers.length}`);
68    unSubcribers.forEach((unsubscribe) => unsubscribe());
69    unSubcribers.length = 0;
70    subscribeStateChange && subscribeStateChange(false);
71  }
72
73  function applyPolicy(policys: Array<POLICY>) {
74    const innerManager = { subscriberCommonEvent, unSubscriberCommonEvent };
75    policyClearCb = policyClearCb ?? new Map();
76    policys.forEach((policy) => {
77      if (policyClearCb) {
78        !policyClearCb.has(policy) && policyClearCb.set(policy, policyMap[policy](innerManager));
79        Log.showDebug(TAG, `apply policy: ${policy}`);
80      }
81    });
82  }
83
84  function release() {
85    policyClearCb?.forEach((cb) => cb());
86    policyClearCb?.clear();
87    unSubscriberCommonEvent();
88  }
89
90  return { subscriberCommonEvent, unSubscriberCommonEvent, applyPolicy, release };
91}
92
93function ScreenPolicy(manager: InnerManager): ClearPolicy {
94  return sEventManager.subscribe(SCREEN_CHANGE_EVENT, (isScreenOn: boolean) => {
95    isScreenOn ? manager.subscriberCommonEvent() : manager.unSubscriberCommonEvent();
96  });
97}
98