多屏异显需求,为接入的非主屏创建显示主屏壁纸窗口

Signed-off-by: ludao518 <dao.lu@archermind.com>
This commit is contained in:
ludao518 2024-01-31 17:08:20 +08:00
parent 49c84d8f10
commit 06a2dd7b6a
11 changed files with 235 additions and 6 deletions

View File

@ -61,7 +61,8 @@ export {
settingsDataManager,
launcherAbilityManager,
navigationBarCommonEventManager,
CloseAppManager
CloseAppManager,
DisplayManager
} from './src/main/ets/default/manager'
export {

View File

@ -0,0 +1,134 @@
/**
* Copyright (c) 2024 Archermind Technology (Nanjing) Co. Ltd.
* 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 window from '@ohos.window';
import display from '@ohos.display';
import { Log } from '../utils/Log';
const TAG = 'DisplayManager: ';
export class DisplayManager {
private readonly MAIN_WINDOW_PREFIX = 'customMainWindow_'
private readonly DEFAULT_MAIN_WINDOW_PAGE = 'pages/SubDisplayWallpaperPage'
public defaultDisplay: display.Display = undefined
private displayDevices: Array<display.Display> = []
private constructor() {
Log.showInfo(TAG, 'constructor called.')
this.loadDefaultDisplay()
this.loadAllDisplays()
this.initDisplayChangeListener()
}
public static getInstance(): DisplayManager {
return globalThis.DisplayManager ??= new DisplayManager()
}
private async loadDefaultDisplay() {
try {
this.defaultDisplay = display.getDefaultDisplaySync()
Log.showInfo(TAG, 'loadDefaultDisplay. defaultDisplay id: ' + this.defaultDisplay?.id)
} catch (err) {
Log.showError(TAG, 'loadDefaultDisplay occur error. errInfo: ' + JSON.stringify(err))
}
}
private async loadAllDisplays() {
let displays: Array<display.Display> = await display.getAllDisplays()
for await (let display of displays) {
if (this.displayDevices.findIndex(item => item.id === display.id) < 0) {
Log.showInfo(TAG, 'new display added. detail: ' + JSON.stringify(display))
this.displayDevices.push(display)
this.createMainWindow(display)
}
}
}
private initDisplayChangeListener() {
display.on('add', displayId => {
Log.showInfo(TAG, 'add new display. id: ' + JSON.stringify(displayId))
this.loadAllDisplays()
})
display.on('remove', displayId => {
Log.showInfo(TAG, 'remove display. id: ' + JSON.stringify(displayId))
let delIndex: number = this.displayDevices.findIndex(item => item.id === displayId)
if (delIndex > 0) {
this.destroyMainWindow(displayId)
this.displayDevices.splice(delIndex, 1)
}
})
}
/**
* window(;)
* @param display
*/
private async createMainWindow(display: display.Display) {
if (display.id === this.defaultDisplay?.id) {
//主屏不需要创建主窗口
return
}
window.createWindow({
ctx: globalThis.desktopContext,
name: this.MAIN_WINDOW_PREFIX + display.id,
windowType: window.WindowType.TYPE_DESKTOP,
displayId: display.id
}).then((resultWindow: window.Window) => {
resultWindow.resize(display.width, display.height)
resultWindow.setWindowMode(window.WindowMode.FULLSCREEN)
resultWindow.setUIContent(this.DEFAULT_MAIN_WINDOW_PAGE)
Log.showInfo(TAG, `create main window ${display.id} success.`)
resultWindow.showWithAnimation()
}).catch(err => {
Log.showError(TAG, 'create main window failed. reason: ' + JSON.stringify(err))
})
}
private async findWindow(displayId: number): Promise<window.Window> {
let resultWindow = undefined
try {
resultWindow = window.findWindow(this.MAIN_WINDOW_PREFIX + displayId)
} catch (err) {
Log.showError(TAG, 'findWindow occur err. errInfo: ' + JSON.stringify(err))
}
return resultWindow
}
private destroyMainWindow(displayId: number) {
if (displayId === this.defaultDisplay?.id) {
return
}
this.findWindow(displayId).then((resultWindow: window.Window) => {
if (resultWindow?.isWindowShowing()) {
resultWindow.hideWithAnimation()
}
resultWindow?.destroyWindow()
Log.showInfo(TAG, `destroy main window ${displayId} success.`)
})
}
public destroySubDisplayWindow() {
for (let display of this.displayDevices) {
this.destroyMainWindow(display.id)
}
display.off('add')
display.off('remove')
}
}

View File

@ -35,4 +35,6 @@ export { launcherAbilityManager } from './LauncherAbilityManager'
export { navigationBarCommonEventManager } from './NavigationBarCommonEventManager'
export { CloseAppManager } from './CloseAppManager'
export { CloseAppManager } from './CloseAppManager'
export { DisplayManager } from './DisplayManager'

View File

@ -27,7 +27,8 @@ import {
launcherAbilityManager,
navigationBarCommonEventManager,
localEventManager,
EventConstants
EventConstants,
DisplayManager
} from '@ohos/common';
import { GestureNavigationManager } from '@ohos/gesturenavigation';
import StyleConstants from '../common/constants/StyleConstants';
@ -39,6 +40,8 @@ import { KeyCode } from '@ohos.multimodalInput.keyCode';
const TAG = 'LauncherMainAbility';
export default class MainAbility extends ServiceExtension {
private displayManager: DisplayManager = undefined
onCreate(want: Want): void {
Log.showInfo(TAG,'onCreate start');
this.context.area = 0;
@ -80,6 +83,7 @@ export default class MainAbility extends ServiceExtension {
// load recent
windowManager.createRecentWindow();
this.registerInputConsumer();
this.displayManager = DisplayManager.getInstance();
}
private registerInputConsumer(): void {
@ -156,6 +160,7 @@ export default class MainAbility extends ServiceExtension {
windowManager.destroyWindow(windowManager.DESKTOP_WINDOW_NAME);
windowManager.destroyRecentWindow();
windowManager.destroyWindow(windowManager.APP_CENTER_WINDOW_NAME);
this.displayManager?.destroySubDisplayWindow();
Log.showInfo(TAG, 'onDestroy success');
}

View File

@ -0,0 +1,37 @@
/**
* Copyright (c) 2024 Archermind Technology (Nanjing) Co. Ltd.
* 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 wallpaper from '@ohos.wallpaper';
import image from '@ohos.multimedia.image';
import { StyleConstants } from '@ohos/common';
@Entry
@Component
struct SubDisplayWallpaperPage {
@State wallPaperImg: image.PixelMap | undefined = undefined
aboutToAppear() {
wallpaper.getImage(wallpaper.WallpaperType.WALLPAPER_SYSTEM).then(value => this.wallPaperImg = value)
}
build() {
Column() {
Image(this.wallPaperImg ?? StyleConstants.DEFAULT_BACKGROUND_IMAGE)
.size({ width: '100%', height: '100%' })
.objectFit(ImageFit.Cover)
}
.size({ width: '100%', height: '100%' })
}
}

View File

@ -70,6 +70,9 @@
},
{
"name": "ohos.permission.START_ABILITIES_FROM_BACKGROUND"
},
{
"name": "ohos.permission.GET_WALLPAPER"
}
]
}

View File

@ -3,6 +3,7 @@
"pages/AppCenterView",
"pages/EmptyPage",
"pages/EntryView",
"pages/RecentView"
"pages/RecentView",
"pages/SubDisplayWallpaperPage"
]
}

View File

@ -27,7 +27,8 @@ import {
launcherAbilityManager,
navigationBarCommonEventManager,
localEventManager,
EventConstants
EventConstants,
DisplayManager
} from '@ohos/common';
import { GestureNavigationManager } from '@ohos/gesturenavigation';
import StyleConstants from '../common/constants/StyleConstants';
@ -40,6 +41,8 @@ import window from '@ohos.window';
const TAG = 'LauncherMainAbility';
export default class MainAbility extends ServiceExtension {
private displayManager: DisplayManager = undefined
onCreate(want: Want): void {
Log.showInfo(TAG,'onCreate start');
this.context.area = 0;
@ -81,6 +84,7 @@ export default class MainAbility extends ServiceExtension {
// load recent
windowManager.createRecentWindow();
this.registerInputConsumer();
this.displayManager = DisplayManager.getInstance()
}
private registerInputConsumer(): void {
@ -156,6 +160,7 @@ export default class MainAbility extends ServiceExtension {
navigationBarCommonEventManager.unregisterNavigationBarEvent();
windowManager.destroyWindow(windowManager.DESKTOP_WINDOW_NAME);
windowManager.destroyRecentWindow();
this.displayManager?.destroySubDisplayWindow();
Log.showInfo(TAG, 'onDestroy success');
}

View File

@ -0,0 +1,37 @@
/**
* Copyright (c) 2024 Archermind Technology (Nanjing) Co. Ltd.
* 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 wallpaper from '@ohos.wallpaper';
import image from '@ohos.multimedia.image';
import { StyleConstants } from '@ohos/common';
@Entry
@Component
struct SubDisplayWallpaperPage {
@State wallPaperImg: image.PixelMap | undefined = undefined
aboutToAppear() {
wallpaper.getImage(wallpaper.WallpaperType.WALLPAPER_SYSTEM).then(value => this.wallPaperImg = value)
}
build() {
Column() {
Image(this.wallPaperImg ?? StyleConstants.DEFAULT_BACKGROUND_IMAGE)
.size({ width: '100%', height: '100%' })
.objectFit(ImageFit.Cover)
}
.size({ width: '100%', height: '100%' })
}
}

View File

@ -70,6 +70,9 @@
},
{
"name": "ohos.permission.START_ABILITIES_FROM_BACKGROUND"
},
{
"name": "ohos.permission.GET_WALLPAPER"
}
]
}

View File

@ -4,6 +4,7 @@
"pages/FormServiceView",
"pages/EmptyPage",
"pages/EntryView",
"pages/RecentView"
"pages/RecentView",
"pages/SubDisplayWallpaperPage"
]
}