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 Window from '@ohos.window';
17import display from '@ohos.display';
18import Log from './Log';
19import { WindowType, Rect, getWindowName } from './Constants';
20import getSingleInstance from './SingleInstanceHelper';
21
22const TAG = 'TintStateManager';
23const LISTENER_SYSTEM_BAR_TINT_CHANGE = 'systemBarTintChange';
24
25export interface TintStateListener { onTintStateChange(state: TintState): void }
26
27export interface TintState {
28  isEnable?: boolean;
29  region?: Rect;
30  backgroundColor?: string;
31  contentColor?: string;
32}
33
34export class TintContentInfo {
35  contentColor = '#FFFFFFFF';
36}
37
38export function getOrCreateTintContentInfo(key: string): TintContentInfo {
39  let storageKey = 'SystemUI_TintContentInfo_' + key;
40  if (!AppStorage.Has(storageKey)) {
41    AppStorage.SetOrCreate(storageKey, new TintContentInfo());
42    Log.showInfo(TAG, `getOrCreateTintContentInfo, Create storageKey of ${storageKey}`);
43  }
44  return AppStorage.Get(storageKey);
45}
46
47export default class TintStateManager {
48  mListeners: Map<WindowType, TintStateListener> = new Map();
49  mStates: Map<WindowType, TintState> = new Map();
50
51  static getInstance(): TintStateManager {
52    return getSingleInstance(TintStateManager, TAG);
53  }
54
55  constructor() {
56    Log.showDebug(TAG, `init TintStateManager. ${LISTENER_SYSTEM_BAR_TINT_CHANGE}`);
57    Window.on(LISTENER_SYSTEM_BAR_TINT_CHANGE, this.onSystemBarTintChange.bind(this));
58  }
59
60  registerListener(windowType: WindowType, listener: TintStateListener): void {
61    let tintState = this.mStates.get(windowType);
62    tintState && listener.onTintStateChange(tintState);
63    let res = this.mListeners.set(windowType, listener);
64    Log.showDebug(TAG, `registser listenerSize: ${res.size}`);
65  }
66
67  unregisterListener(windowType: WindowType): void {
68    let res = this.mListeners.delete(windowType);
69    Log.showDebug(TAG, `unregistser ${windowType}, res: ${res}`);
70  }
71
72  onSystemBarTintChange(data): Promise<void> {
73    Log.showDebug(TAG, `onSystemBarTintChange, data: ${JSON.stringify(data)}`);
74    if (!Array.isArray(data.regionTint)) {
75      Log.showDebug(TAG, 'regionTint is not array.');
76      return;
77    }
78    let dis = display.getDefaultDisplaySync();
79    if (dis.id != data.displayId) {
80      Log.showDebug(TAG, `Needn't change, displayId: ${data.displayId}`);
81      return;
82    }
83    data.regionTint.forEach((regionTintData) => {
84      Log.showDebug(TAG, `onSystemBarTintChange, type: ${getWindowName(regionTintData['type'])}`);
85      let windowName = getWindowName(regionTintData['type']);
86      if (!windowName) {
87        return;
88      }
89      let tintState: TintState = {
90        isEnable: regionTintData.isEnable,
91        region: regionTintData.region,
92        backgroundColor: regionTintData.backgroundColor,
93        contentColor: regionTintData.contentColor,
94      };
95      Log.showDebug(TAG, `tintState: ${JSON.stringify(tintState)}`);
96      this.mStates.set(windowName, tintState);
97      this.mListeners.get(windowName)?.onTintStateChange(tintState);
98    });
99  }
100}
101