/*
* Copyright (c) Huawei Device Co., Ltd. 2024-2025. All rights reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { LogDomain, LogHelper } from '@ohos/basicutils';
import { EvtBus, WindowEvent } from '@ohos/frameworkwrapper';
import { OccludeKeygaurdScene, SCBSceneSessionManager } from '@ohos/windowscene';
import { WindowConstants } from '@ohos/commonconstants';
import { AbstractObserverManager } from '../base/AbstractObserverManager';
import { KeyguardStatusService } from './KeyguardStatusService';
const TAG = 'OccludedStateManager';
const log: LogHelper = LogHelper.getLogHelper(LogDomain.KG, TAG);
/**
* 遮盖状态监听器
*/
export interface OccludedStateManagerListener {
/**
* 遮盖状态变化通知
*
* @param isOccluded 是否被遮盖
*/
onOccludedStateChange?: (isOccluded: boolean) => void;
}
/**
* 遮盖状态管理器(统一定义+收集+分发)
*/
export class OccludedStateManager extends AbstractObserverManager<OccludedStateManagerListener> {
private static sInstance: OccludedStateManager;
private readonly OCCLUDED_ON_BOUNCER: OccludeKeygaurdScene[] =
[OccludeKeygaurdScene.SPECIFIC_TYPE_VOICE_INTERACTION, OccludeKeygaurdScene.SYSTEM_DIALOG_UNOCCLUDE];
public static getInstance(): OccludedStateManager {
if (OccludedStateManager.sInstance == null) {
OccludedStateManager.sInstance = new OccludedStateManager();
}
return OccludedStateManager.sInstance;
}
private _windowOccludedState: number = 0; // 遮挡状态
private _isDropdownShow: boolean = false; // 是否双中心下拉
private _isMetaBallShow: boolean = false; // 充电动效
/**
* 是否遮盖
*
* @returns 是否遮盖
*/
public get isOccluded(): boolean {
return this.isWindowOccluded || this.isDropdownOccluded;
}
/**
* 是否窗口遮挡
*
* @returns 是否窗口遮挡
*/
public get isWindowOccluded(): boolean {
return this._windowOccludedState !== 0;
}
/**
* 获取窗口遮挡类型
*
* @returns 窗口遮挡类型
*/
public get windowOccludedState(): number {
return this._windowOccludedState;
}
private set windowOccludedState(occludedState: number) {
if (this._windowOccludedState !== occludedState) {
this._windowOccludedState = occludedState;
this.broadcastDataChange(observer => observer.onOccludedStateChange?.(this.isOccluded));
}
}
/**
* 是否双中心遮挡
*
* @returns 是否双中心遮挡
*/
public get isDropdownOccluded(): boolean {
return this._isDropdownShow;
}
/**
* 设置双中心遮挡状态
*
* @param 双中心遮挡状态
*/
public set isDropdownOccluded(isDropdownShow: boolean) {
if (this._isDropdownShow !== isDropdownShow) {
this._isDropdownShow = isDropdownShow;
this.broadcastDataChange(observer => observer.onOccludedStateChange?.(this.isOccluded));
}
}
/**
* 设置充电动效状态
*
* @param 充电动效状态
*/
public set isMetaBallOccluded(_isMetaBallShow: boolean) {
this._isMetaBallShow = _isMetaBallShow;
}
/**
* 是否充电动效遮挡
*
* @returns 是否充电动效遮挡
*/
public get isMetaBallOccluded(): boolean {
return this._isMetaBallShow;
}
/**
* 是否密码界面之上的遮挡
*
* @returns 是否密码界面之上的遮挡
*/
public get isOccludeOnBouncer(): boolean {
log.showInfo(`isOccludeOnBouncer ${this._windowOccludedState}, ${this._isMetaBallShow}`);
return this.OCCLUDED_ON_BOUNCER.includes(this._windowOccludedState) || this._isMetaBallShow;
}
protected doInit(): void {
log.showInfo('doInit');
SCBSceneSessionManager.getInstance().registerKeyguardOccludedChangeCallbacks(this.handleOccludedChange.bind(this));
EvtBus.on(WindowEvent, this.handleWindowEvent.bind(this));
}
protected doRelease(): void {
log.showInfo('doRelease');
SCBSceneSessionManager.getInstance().unRegisterKeyguardOccludedChangeCallbacks(
this.handleOccludedChange.bind(this));
EvtBus.off(WindowEvent, this.handleWindowEvent.bind(this));
}
private handleOccludedChange(occludedState: number): void {
if (this._windowOccludedState === occludedState) {
return;
}
log.showWarn(`receive occludedState: ${occludedState}.`);
KeyguardStatusService.switchToOccluded(occludedState);
this.windowOccludedState = occludedState;
}
private handleWindowEvent(event: WindowEvent): void {
if (event.windowName !== WindowConstants.WINDOW_NAME_DROPDOWN) {
return;
}
let isDropdownShow: boolean | undefined = undefined;
switch (event.eventType) {
case WindowEvent.EVENT_TYPE_SHOW:
isDropdownShow = true;
break;
case WindowEvent.EVENT_TYPE_HIDE:
isDropdownShow = false;
break;
default:
break;
}
if (isDropdownShow !== undefined && this._isDropdownShow !== isDropdownShow) {
log.showInfo(`receive isDropdownShow: ${isDropdownShow}`);
this.isDropdownOccluded = isDropdownShow;
}
}
}