/*
* Copyright (c) Huawei Technologies 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 Want from '@ohos.app.ability.Want';
import router from '@ohos.router';
import window from '@ohos.window';
import EnvironmentCallback from '@ohos.app.ability.EnvironmentCallback';
import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant';
import { BusinessError } from '@ohos.base';
import { Configuration } from '@ohos.app.ability.Configuration';
import emitter from '@ohos.events.emitter';
import { LogUtil } from '../utils/LogUtil';
import { EVENT_ID_CLOSE_THEME_FULL_SCREEN_PAGE } from '../event/types'
/* instrument ignore file */
const TAG: string = 'SettingsNoNavigationPage : ';
const PAGE_NAME: string = 'SettingsNoNavigationPage';
const COLOR_WHITE: string = '#ffffffff';
const COLOR_BLACK: string = '#ff000000';
/**
* 路由携带参数
*/
interface NoNavigationPageParams {
want: Want;
isFull: boolean;
isBlackBG: boolean;
isDarkMode: boolean;
}
@Entry({ routeName: PAGE_NAME })
@Component
struct SettingsNoNavigationPage {
@State want: Want = {};
private isFull: boolean = false;
@State isBlackBG: boolean = false;
private isDarkMode: boolean = false;
private environmentCallbackId: number = -1;
/**
* 设置系统栏(状态栏、导航栏)的颜色模式。浅色模式:内容黑色,深色模式:内容白色
* @param colorMode 颜色模式:浅色模式、深色模式
*/
private async setSystemBarColorMode(colorMode: ConfigurationConstant.ColorMode): Promise<void> {
try {
const isDarkMode: boolean = colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
const lastWindow: window.Window = await window.getLastWindow(getContext(this));
const properties: window.SystemBarProperties = {
statusBarContentColor: isDarkMode ? COLOR_WHITE : COLOR_BLACK,
navigationBarContentColor: isDarkMode ? COLOR_WHITE : COLOR_BLACK,
};
await lastWindow.setWindowSystemBarProperties(properties);
} catch (error) {
const e = error as BusinessError;
LogUtil.error(`${TAG}Failed to set system bar color mode. Error = ${e?.name}, ${e?.code}, ${e?.message}`);
}
}
/**
* 重置系统栏颜色模式,保持和设置应用一致的颜色模式
*/
private async resetSystemBarColorMode(): Promise<void> {
try {
const configuration = AppStorage.get<Configuration>('envConfig');
if (configuration && configuration.colorMode !== undefined) {
this.setSystemBarColorMode(configuration.colorMode);
}
} catch (error) {
const e = error as BusinessError;
LogUtil.error(`${TAG}Failed to reset system bar color mode. Error = ${e?.name}, ${e?.code}, ${e?.message}`);
}
}
/**
* 是否启用系统栏(状态栏、导航栏、导航条),启用会显示系统栏,不启用会隐藏系统栏
* @param enable 是否启用
* @param enableAnimation 显示和隐藏系统栏,是否使用动效
*/
private async setSystemBarEnabled(enable: boolean, enableAnimation: boolean): Promise<void> {
try {
const lastWindow: window.Window = await window.getLastWindow(getContext(this));
await lastWindow.setSpecificSystemBarEnabled('status', enable, enableAnimation);
await lastWindow.setSpecificSystemBarEnabled('navigation', enable, enableAnimation);
await lastWindow.setSpecificSystemBarEnabled('navigationIndicator', enable, enableAnimation);
} catch (error) {
const e = error as BusinessError;
LogUtil.error(`${TAG}Failed to set system bar enabled. Error = ${e?.name}, ${e?.code}, ${e?.message}`);
}
}
/**
* 退出该页面时,恢复系统栏,确保不会影响到设置的其他页面
*/
private recoverSystemBar(): void {
this.resetSystemBarColorMode();
this.setSystemBarEnabled(true, false);
}
private initParams(): void {
const params: NoNavigationPageParams = router.getParams() as NoNavigationPageParams;
if (!params || !params.want) {
LogUtil.warn(`${TAG} params is error`);
return;
}
this.want = params.want;
this.isFull = params.isFull;
this.isBlackBG = params.isBlackBG;
this.isDarkMode = params.isDarkMode;
}
private handleFullScreen(): void {
if (!this.isFull) {
return;
}
// 全屏页面,不启用系统栏(状态栏、导航栏、导航条)
this.setSystemBarEnabled(false, false);
}
private handleDarkMode(): void {
if (!this.isDarkMode) {
return;
}
// 深色模式页面,修改系统栏(状态栏、导航栏)颜色
this.setSystemBarColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_DARK);
let systemColorMode: ConfigurationConstant.ColorMode = ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET;
const configuration = AppStorage.get<Configuration>('envConfig');
if (configuration && configuration.colorMode !== undefined) {
systemColorMode = configuration.colorMode;
}
const callback: EnvironmentCallback = {
onConfigurationUpdated(config: Configuration): void {
if (systemColorMode === config.colorMode) {
return;
}
systemColorMode = config.colorMode ?? ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET;
// 深色模式页面,无论系统是什么颜色模式,状态栏都是白色内容
try {
window.getLastWindow(getContext(this), (error: BusinessError, lastWindow: window.Window) => {
if (error.code) {
LogUtil.error(`${TAG}Failed to get last Window. Error = ${error.name}, ${error.code}, ${error.message}`);
return;
}
const properties: window.SystemBarProperties = {
statusBarContentColor: COLOR_WHITE,
navigationBarContentColor: COLOR_WHITE,
};
lastWindow.setWindowSystemBarProperties(properties).catch((error: BusinessError) => {
LogUtil.error(`${TAG}Failed to set white system bar = ${error?.name}, ${error?.code}, ${error?.message}`);
});
});
} catch (error) {
const e = error as BusinessError;
LogUtil.error(`${TAG}Failed to set white system bar. Error = ${e?.name}, ${e?.code}, ${e?.message}`);
}
},
onMemoryLevel(): void {
},
};
try {
this.environmentCallbackId = getContext(this).getApplicationContext().on('environment', callback);
} catch (error) {
const e = error as BusinessError;
LogUtil.error(`${TAG}Failed to subscribe environment change. Error = ${e?.name}, ${e?.code}, ${e?.message}`);
}
}
aboutToAppear(): void {
LogUtil.info(`${TAG} aboutToAppear`);
try {
this.initParams();
this.handleFullScreen();
this.handleDarkMode();
} catch (error) {
const e = error as BusinessError;
LogUtil.error(`${TAG}Failed to appear page. Error = ${e?.name}, ${e?.code}, ${e?.message}`);
}
// 监听关闭全屏页面的事件
emitter.on({
eventId: EVENT_ID_CLOSE_THEME_FULL_SCREEN_PAGE,
priority: emitter.EventPriority.IMMEDIATE,
}, () => {
router.back();
this.recoverSystemBar();
});
}
aboutToDisappear(): void {
LogUtil.info(`${TAG} aboutToDisappear`);
try {
getContext(this).getApplicationContext().off('environment', this.environmentCallbackId);
this.environmentCallbackId = -1;
this.recoverSystemBar();
} catch (error) {
const e = error as BusinessError;
LogUtil.error(`${TAG}Failed to disappear page. Error = ${e?.name}, ${e?.code}, ${e?.message}`);
}
emitter.off(EVENT_ID_CLOSE_THEME_FULL_SCREEN_PAGE);
}
build() {
Stack() {
UIExtensionComponent(this.want)
.defaultFocus(true)
.width('100%')
.height('100%')
.onError((error) => {
LogUtil.error(`${TAG} UIExtensionComponent onError ${error?.message}`);
})
.onReceive(this.onReceiveData)
.id('settings_full_extension')
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
.backgroundColor(this.isBlackBG ? Color.Black : $r('sys.color.background_secondary'))
}
.width('100%')
.height('100%')
.backgroundColor(this.isBlackBG ? Color.Black : $r('sys.color.background_secondary'))
}
private onReceiveData: (data: object) => void = (data: object) => {
LogUtil.info(`${TAG} onReceiveData`);
if (data === undefined) {
LogUtil.error(`${TAG} onReceiveData is undefined`);
return;
}
if (data['enterImmersion'] !== undefined) {
const isSystemBarEnabled: boolean = data['enterImmersion'] ? false : true;
this.setSystemBarEnabled(isSystemBarEnabled, true);
return;
}
if (data['hideStatusBar'] !== undefined) {
const isSystemBarEnabled: boolean = data['hideStatusBar'] ? false : true;
this.setSystemBarEnabled(isSystemBarEnabled, false);
}
if (data['back'] !== undefined) {
router.back();
this.recoverSystemBar();
}
if (data && data['systemBarColorChange'] !== undefined) {
LogUtil.showInfo(TAG, 'SCB UIExtension onReceive: systemBarColorChange');
if (data['systemBarColorChange'] == 'white') {
this.isBlackBG = true;
this.setSystemBarColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_DARK);
}
if (data['systemBarColorChange'] == 'reset') {
this.isBlackBG = false;
this.resetSystemBarColorMode();
}
}
};
}
/**
* 进入新的非Navigation页面,不分栏
* @param want 需要加载的外部UIExtensionComponent的want参数
* @param isFull 是否需要全屏,默认全屏,全屏会隐藏系统栏(状态栏、导航栏、导航条)
* @param isBlackBG 是否为黑色背景,默认不是
* @param isDarkMode 页面是否为深色模式,默认不是,深色模式会改变系统栏(状态栏、导航栏)颜色
*/
export function enterNoNavigationPage(want: Want, isFull: boolean = true, isBlackBG: boolean = false,
isDarkMode: boolean = false): void {
const pageParams: NoNavigationPageParams = {
want: want,
isFull: isFull,
isBlackBG: isBlackBG,
isDarkMode: isDarkMode,
};
router.pushNamedRoute({ name: PAGE_NAME, params: pageParams }, router.RouterMode.Standard, (err) => {
if (err) {
LogUtil.error(`${TAG} enterFullPage error:${err.message}`);
return;
}
});
}