/*
* 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 { ArrayUtils, LogDomain, LogHelper } from '@ohos/basicutils';
import {
EvtBus,
DeviceHelper,
PluginSlot,
EventManager,
OobeActivatedEvent
} from '@ohos/frameworkwrapper';
import { SCBOobeManager } from '@ohos/windowscene';
import {
NotificationIconEvent,
PureShowEvent,
RealTimeNetworkSpeedEvent,
} from '@ohos/systemuicommon';
import {
StatusBarType,
scbStatusBarStatusManager,
} from '@ohos/systemuicommon/Index';
import display from '@ohos.display';
// instrument ignore file
const TAG = 'PluginRootController';
const log: LogHelper = LogHelper.getLogHelper(LogDomain.SYS_UI, TAG);
export type PluginVisibleSettingCallback = (isVisible: boolean) => void;
export interface PluginRootControllerConstructor {
slot?: string;
statusBarType: number;
callback: PluginVisibleSettingCallback;
}
export class PluginRootController {
/**
* 默认状态栏(桌面和应用界面),纯净显示下,默认允许时间、WiFi、胶囊、信号、电量、超级隐私、定位、热点、通知、网速 显示
*/
private static readonly INCLUDE_PURE_SHOW_SLOT: Array<string> = [PluginSlot.SLOT_STATUS_CLOCK,
PluginSlot.SLOT_STATUS_WIFI, PluginSlot.LIVE_VIEW_CAPSULE, PluginSlot.SLOT_STATUS_SIGNAL,
PluginSlot.SLOT_STATUS_BATTERY, PluginSlot.SLOT_STATUS_SUPER_PRIVACY, PluginSlot.SLOT_STATUS_LOCATION,
PluginSlot.SLOT_STATUS_HOT_SPOT, PluginSlot.SLOT_STATUS_NOTIFICATION, PluginSlot.SLOT_STATUS_NET_SPEED,
PluginSlot.SLOT_STATUS_ETHERNET];
/**
* 锁屏状态栏,纯净显示下,默认允许显示 时间、WiFi、移动信号、电量,运营商信息、超级隐私、地理位置隐私指示器、网速
*/
private static readonly INCLUDE_PURE_SHOW_SLOT_KEYGUARD: Array<string> = [PluginSlot.SLOT_STATUS_CLOCK,
PluginSlot.SLOT_STATUS_WIFI, PluginSlot.SLOT_STATUS_SIGNAL, PluginSlot.SLOT_STATUS_BATTERY,
PluginSlot.SLOT_STATUS_OPERATOR, PluginSlot.SLOT_STATUS_SUPER_PRIVACY, PluginSlot.SLOT_STATUS_LOCATION,
PluginSlot.SLOT_STATUS_HOT_SPOT, PluginSlot.SLOT_STATUS_NET_SPEED, PluginSlot.SLOT_STATUS_ETHERNET];
/**
* 扩展新形态小折叠产品外屏所有显示的图标
*/
private static readonly PLUGINS_OUTER_HOME_OUTER_SCREEN: Array<string> = [PluginSlot.SLOT_STATUS_CLOCK,
PluginSlot.SLOT_STATUS_WIFI, PluginSlot.LIVE_VIEW_CAPSULE, PluginSlot.SLOT_STATUS_SIGNAL,
PluginSlot.SLOT_STATUS_BATTERY, PluginSlot.SLOT_STATUS_NOTIFICATION, PluginSlot.SLOT_STATUS_LOCATION,
PluginSlot.SLOT_STATUS_SUPER_PRIVACY, PluginSlot.SLOT_STATUS_HOT_SPOT, PluginSlot.SLOT_STATUS_ETHERNET];
/**
* 多事件管理器
*/
private eventMgr: EventManager = EvtBus.createEventManager();
/**
* plugin唯一标识
*/
private slot: string;
/**
* 状态栏类型,默认桌面状态栏
*/
private statusBarType: number;
/**
* 是否纯净显示
*/
private isPureShow?: boolean;
/**
* 判断是否处于OOBE阶段
*/
private isInOobe = false;
/**
* 是否显示通知图标
*/
private isNotificationIconEnable?: boolean;
/**
* 是否显示网速图标
*/
private isRealTimeNetworkIconEnable?: boolean;
/**
* 图标可见性
*/
private isPluginVisibleSetting: boolean = true;
private callback: PluginVisibleSettingCallback;
private isFoldStatusRegister = false;
// 仅在StatusBarGroup组件中不传slot
constructor(options: PluginRootControllerConstructor) {
this.slot = options.slot ?? '';
this.statusBarType = options.statusBarType;
this.callback = options.callback;
}
public static getPureShowPlugin(statusbarType?: number): Array<string> {
if (statusbarType === StatusBarType.TYPE_MAIN_PHONE_KEYGUARD) {
return PluginRootController.INCLUDE_PURE_SHOW_SLOT_KEYGUARD;
}
return PluginRootController.INCLUDE_PURE_SHOW_SLOT;
}
/**
* 初始化Controller
*/
onStart(): void {
log.showInfo(`PluginRootController(${this.slot}) onStart`);
this.initOobePureShow();
this.listenStatusBarSettingEvent();
this.registerFoldStatusListener();
}
/**
* 监听折叠屏状态
*/
public registerFoldStatusListener(): void {
if (!this.isAllowRegisterFoldListener()) {
return;
}
try {
display.on('foldStatusChange', this.foldStatusCallback);
this.isFoldStatusRegister = true;
} catch (error) {
log.showError('registerFoldStatusListener on error');
}
}
/**
* 注销监听
*/
public unRegisterFoldStatusListener(): void {
if (!this.isFoldStatusRegister) {
return;
}
try {
display.off('foldStatusChange', this.foldStatusCallback);
this.isFoldStatusRegister = false;
} catch (error) {
log.showError('unRegisterFoldStatusListener on error');
}
}
private isAllowRegisterFoldListener(): boolean {
if (this.slot !== PluginSlot.LIVE_VIEW_CAPSULE ||
this.isFoldStatusRegister) {
return false;
}
return true;
}
private foldStatusCallback = (newFoldStatus: display.FoldStatus) => {
// 锁屏折叠态需要刷新图标
if (newFoldStatus === display.FoldStatus.FOLD_STATUS_FOLDED &&
this.getStatusBarType() === StatusBarType.TYPE_MAIN_PHONE_KEYGUARD) {
this.pluginVisibleSetting();
}
};
private initOobePureShow(): void {
// OOBE阶段,状态栏需要处理纯净显示
this.isInOobe = SCBOobeManager.isOobeActivated();
log.showInfo(`PluginRootController(${this.slot}) init isOobe is ${this.isInOobe}.`);
this.pluginVisibleSetting();
}
/**
* 监听状态栏设置变化的事件
*/
private listenStatusBarSettingEvent() {
// 监听当前四种图标显示隐藏的事件,给图标父容器StatusBarGroup组件使用(如果不传slot)
if (!this.slot) {
this.eventMgr
.on(NotificationIconEvent, this.onEvents)// .on(RealTimeNetworkSpeedEvent, this.onEvents)
.on(PureShowEvent, this.onEvents)
.on(OobeActivatedEvent, this.onEvents)
return;
}
// 通知图标显示
if (this.slot === PluginSlot.SLOT_STATUS_NOTIFICATION) {
this.eventMgr.on(NotificationIconEvent, this.onNotificationIconEvent);
}
// 网速图标显示
if (this.slot === PluginSlot.SLOT_STATUS_NET_SPEED) {
this.eventMgr.on(RealTimeNetworkSpeedEvent, this.onRealTimeNetworkSpeedEvent);
}
this.listenPureShowEvent();
}
/**
* 监听纯净显示开关变化的事件
*/
private listenPureShowEvent(): void {
log.showInfo('listenPureShowEvent slot: ' + this.slot);
this.eventMgr
.on(PureShowEvent, this.onPureShowEvent)
.on(OobeActivatedEvent, this.onOobeChangeEvent);
}
/**
* 销毁Controller
*/
onStop(): void {
this.eventMgr.offAll();
this.unRegisterFoldStatusListener();
}
/**
* 获取状态栏类型
* ComponentCallback复写
*
* @return 状态栏类型
*/
getStatusBarType(): number {
return this.statusBarType;
}
/**
* OOBE阶段变化回调
*
* @param event OOBE阶段变化事件
*/
private onOobeChangeEvent = (event: OobeActivatedEvent): void => {
let isActivated: boolean = event.isActivated;
let isOobe = SCBOobeManager.isOobeActivated();
this.isInOobe = (isActivated || isOobe) ?? false;
log.showInfo(`onOobeChangeEvent(${this.slot}), isInOobe is ${this.isInOobe}`);
this.pluginVisibleSetting();
}
/**
* 纯净显示设置变化回调
*
* @param event 状态栏纯净显示开关事件
*/
private onPureShowEvent = (event: PureShowEvent): void => {
let isEnable = event.isPureShowEnable();
log.showInfo(`onPureShowEvent(${this.slot}) pureShow old: ${this.isPureShow} new: ${isEnable}`);
if (isEnable === undefined) {
return;
}
this.isPureShow = isEnable;
this.pluginVisibleSetting();
}
/**
* 显示通知图标设置变化回调
*
* @param event 状态栏显示通知图标开关事件
*/
private onNotificationIconEvent = (event: NotificationIconEvent): void => {
log.showInfo(`onNotificationIconEvent(${this.slot}),isEnable is ${event.isNotificationIconEnable()}`);
let isEnable = event.isNotificationIconEnable();
this.isNotificationIconEnable = isEnable;
this.pluginVisibleSetting();
}
/**
* 显示网速设置变化回调
*
* @param event 状态栏显示网速开关事件
*/
private onRealTimeNetworkSpeedEvent = (event: RealTimeNetworkSpeedEvent): void => {
let isEnable = event.isRealTimeNetworkSpeedEnable();
log.showInfo(`onRealTimeNetworkSpeedEvent(${this.slot}) isEnable: ${isEnable}.`);
this.isRealTimeNetworkIconEnable = isEnable;
this.pluginVisibleSetting();
}
refreshWhenStatusBarChange(statusBarType: number) {
this.statusBarType = statusBarType;
// 纯净模式下更新系统图标
log.showInfo(`refreshWhenStatusBarChange ${this.statusBarType}`)
this.pluginVisibleSetting();
}
/**
* 同时监听多种事件,仅触发回调
*/
private onEvents = (): void => {
this.callback(true);
}
private pluginVisibleSetting(): void {
let cacheVisible = this.isPluginVisibleSetting;
if (this.isInOobe && !this.isPluginOOBEShow()) {
// OOBE 图标显示过滤
this.isPluginVisibleSetting = false;
} else if (this.isPureShow && !this.isPluginPureShow()) {
// 纯净显示 图标显示过滤
this.isPluginVisibleSetting = false;
} else {
// 其余场景图标显示过滤
this.isPluginVisibleSetting = this.isNormalShow();
}
// 只有可见设置变化才调用 callback
if (cacheVisible !== this.isPluginVisibleSetting) {
this.callback(this.isPluginVisibleSetting);
}
// 设置通知图标是否显示
this.setNtfIconShow(this.isPluginVisibleSetting);
}
/**
* 设置当前通知图标是否显示
*/
private setNtfIconShow(isPluginVisibleSetting: boolean): void {
if (this.slot === PluginSlot.SLOT_STATUS_NOTIFICATION) {
scbStatusBarStatusManager.setNtfIconShow(isPluginVisibleSetting);
}
}
/**
* 计算当前图标是否应该在纯净模式下显示
*/
private isPluginPureShow(): boolean {
if (this.statusBarType === StatusBarType.TYPE_MAIN_PHONE_DROPDOWN) {
// 纯净显示在下拉时不生效
return true;
}
if (this.slot === PluginSlot.LIVE_VIEW_CAPSULE &&
this.statusBarType === StatusBarType.TYPE_MAIN_PHONE_LAUNCHER) {
// 桌面状态栏纯净显下要显示胶囊
return true;
}
let pureShowSlotArr: string[];
if (StatusBarType.isKeyguard(this.statusBarType)) {
pureShowSlotArr = this.getKeyguardPurePlugin(false);
} else {
pureShowSlotArr = PluginRootController.INCLUDE_PURE_SHOW_SLOT;
}
return ArrayUtils.contains(pureShowSlotArr, this.slot);
}
private getKeyguardPurePlugin(isOuterHomeFolded: boolean): Array<string> {
return PluginRootController.INCLUDE_PURE_SHOW_SLOT_KEYGUARD;
}
/**
* 计算当前图标是否应该在OOBE模式显示
*/
private isPluginOOBEShow(): boolean {
if (this.slot === PluginSlot.SLOT_STATUS_NOTIFICATION) {
// OOBE场景下不显示通知图标
return false;
}
return this.isPluginPureShow();
}
/**
* 判断图标当前是否要显示
*/
private isNormalShow(): boolean {
if (this.slot === PluginSlot.SLOT_STATUS_NOTIFICATION) {
return this.isNotificationIconEnable ?? true;
}
if (this.slot === PluginSlot.SLOT_STATUS_NET_SPEED) {
return this.isRealTimeNetworkIconEnable ?? false;
}
return true;
}
}