diff --git a/common/index.ets b/common/index.ets index 257845fd389b7ac546b76b952820ed1e2d3b8637..29c43d02ad614f0bfd188f9f5e7c12b71918564c 100644 --- a/common/index.ets +++ b/common/index.ets @@ -91,7 +91,8 @@ export { SCBRootSceneSession } from './src/main/ets/WindowScene/scene/session/SC export { SCBSceneInfo } from './src/main/ets/WindowScene/scene/session/SCBSceneInfo' export { SCBDividerParam } from './src/main/ets/WindowScene/scene/session/SCBDividerParam' export { SCBSceneSession } from './src/main/ets/WindowScene/scene/session/SCBSceneSession' -export { SCBSceneSessionManager } from './src/main/ets/WindowScene/scene/session/SCBSceneSessionManager' +export { SCBSpecificSession } from './src/main/ets/WindowScene/scene/session/SCBSpecificSession' +export { SCBSceneSessionManager, SCBSpecificSceneSessionList } from './src/main/ets/WindowScene/scene/session/SCBSceneSessionManager' export { SCBScreenSession, SCBScreenProperty } from './src/main/ets/WindowScene/screen/session/SCBScreenSession' export { SCBSceneContainerSession } from './src/main/ets/WindowScene/scene/session/SCBSceneContainerSession' export { SCBSceneContainerSessionArray } from './src/main/ets/WindowScene/scene/session/SCBSceneContainerSession' diff --git a/common/src/main/ets/WindowScene/scene/session/SCBSceneSession.ts b/common/src/main/ets/WindowScene/scene/session/SCBSceneSession.ts index 7bca89441ec1614b924e55a076bc7aa45fbb4933..724386d231e7aab6de167b1d45a417481df84dd2 100644 --- a/common/src/main/ets/WindowScene/scene/session/SCBSceneSession.ts +++ b/common/src/main/ets/WindowScene/scene/session/SCBSceneSession.ts @@ -12,12 +12,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - import sceneSessionManager from '@ohos.sceneSessionManager' + +import { Log } from '../../../default/utils/Log' import { SCBSceneInfo } from './SCBSceneInfo' -import { SCBSceneSessionManager } from './SCBSceneSessionManager' +import { SCBSceneSessionManager, SCBSpecificSceneSessionList } from './SCBSceneSessionManager' import { SCBTransitionEffect } from '../../animation/SCBTransitionEffect' +const TAG = 'SCBSceneSession' + /** * Session of a scene. */ @@ -31,6 +34,12 @@ export class SCBSceneSession { scaleX: number = 1; scaleY: number = 1; + sessionState: sceneSessionManager.SessionState; + sessionRectChangeCallback: Function; + createSubSessionCallback: Function; + subSessionStateChangeCallback: Function; + subSessionList: SCBSpecificSceneSessionList = new SCBSpecificSceneSessionList(); + /** * Constructor. * @param session Session of the scene @@ -42,6 +51,20 @@ export class SCBSceneSession { this.session.on('pendingSceneSessionActivation', (info) => { this.onPendingSceneSessionActivation(info); }) + + this.session.on('sessionStateChange', (state) => { + this.onSessionStateChange(state); + }) + } + + public registerCreateSubSessionCallback(callback: Function) { + Log.showInfo(TAG, `registerCreateSubSessionCallback`); + this.createSubSessionCallback = callback; + } + + public registerSubSessionActiveStatueChangeCallback(callback: Function) { + Log.showInfo(TAG, `registerSubSessionActiveStatueChangeCallback`); + this.subSessionStateChangeCallback = callback; } private onPendingSceneSessionActivation(sceneInfo: sceneSessionManager.SceneInfo) { @@ -67,4 +90,23 @@ export class SCBSceneSession { this.isActive = false; sceneSessionManager.requestSceneSessionDestruction(this.session); } + + public handleSubSessionStateChange(state: sceneSessionManager.SessionState, sessionId: Number) { + Log.showInfo(TAG, `handleSubSessionStateChange, state: ${state}, sessionId: ${sessionId}`); + if (this.subSessionStateChangeCallback) { + this.subSessionStateChangeCallback(this, sessionId, state); + } + } + + private onCreateSpecificSession(specificSession: sceneSessionManager.SceneSession) { + Log.showInfo(TAG, 'onCreateSpecificSession'); + if (this.createSubSessionCallback) { + this.createSubSessionCallback(this, specificSession); + } + } + + private onSessionStateChange(state: sceneSessionManager.SessionState) { + Log.showDebug(TAG, `onSessionStageChange, state: ${state}`); + this.sessionState = state; + } } diff --git a/common/src/main/ets/WindowScene/scene/session/SCBSceneSessionManager.ts b/common/src/main/ets/WindowScene/scene/session/SCBSceneSessionManager.ts index 1df83208b09475c8effc237a53149e4b880e3ecf..d105d99655870773b0b26fbeb357fc744c1f36cf 100644 --- a/common/src/main/ets/WindowScene/scene/session/SCBSceneSessionManager.ts +++ b/common/src/main/ets/WindowScene/scene/session/SCBSceneSessionManager.ts @@ -13,13 +13,20 @@ * limitations under the License. */ +import sceneSessionManager from '@ohos.sceneSessionManager' import ServiceExtensionContext from 'application/ServiceExtensionContext' + import { SCBRootSceneSession } from './SCBRootSceneSession' import { SCBSceneInfo } from './SCBSceneInfo' +import { SCBSpecificSession } from './SCBSpecificSession' import { Log } from '../../../default/utils/Log' const TAG = 'SCBSceneSessionManager'; +@Observed +export class SCBSpecificSceneSessionList extends Array { +} + /** * Scene session manager */ @@ -29,10 +36,20 @@ export class SCBSceneSessionManager { private backgroundSceneFuncMap: Map = new Map(); private destroySceneFuncMap: Map = new Map(); private activateSceneFuncMap: Map = new Map(); + private createSpecificSceneCallback: Function; // callback of create system specific session public mainScreenId: number = -1; private constructor() { this.rootSceneSession = new SCBRootSceneSession(); + // register native function for create specific session + sceneSessionManager.on('createSpecificSession', (specificSession) => { + this.onCreateSpecificSession(specificSession); + }) + } + + private onCreateSpecificSession(specificSession: sceneSessionManager.SceneSession) { + Log.showError(TAG, `onCreateSpecificSession: persistentId: ${specificSession.persistentId}`); + this.createSpecificSceneCallback(specificSession); } /** @@ -108,6 +125,11 @@ export class SCBSceneSessionManager { this.destroySceneFuncMap.set(screenId, callback); } + public registerCreateSpecificSceneCallback(callback: Function) { + Log.showDebug(TAG, `registerCreateSpecificSceneCallback`); + this.createSpecificSceneCallback = callback; + } + /** * Start a scene. * @param sceneInfo The info of the scene which to be activated diff --git a/common/src/main/ets/WindowScene/scene/session/SCBSpecificSession.ts b/common/src/main/ets/WindowScene/scene/session/SCBSpecificSession.ts new file mode 100644 index 0000000000000000000000000000000000000000..febefb76ad9479aea115432f5cd0d109bd4b80f1 --- /dev/null +++ b/common/src/main/ets/WindowScene/scene/session/SCBSpecificSession.ts @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023 Huawei Device 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 sceneSessionManager from '@ohos.sceneSessionManager' +import { Log } from '../../../default/utils/Log' + +const TAG = 'SCBSpecificSession' + +/** + * Session of system scene or sub scene + */ +@Observed +export class SCBSpecificSession { + readonly session: sceneSessionManager.SceneSession; + isActive: boolean = false; + translateX: number = 0; + translateY: number = 0; + scaleX: number = 1; + scaleY: number = 1; + sessionState: sceneSessionManager.SessionState; + + /* + * callback of session state change + */ + stateChangeCallback: Function + + + /** + * Constructor. + * @param session Session of the scene + * @param sceneInfo Information of the scene + */ + constructor(session: sceneSessionManager.SceneSession, callback: Function) { + Log.showInfo(TAG, 'constructor'); + this.session = session; + this.stateChangeCallback = callback; + this.isActive = false; + this.sessionState = sceneSessionManager.SessionState.STATE_DISCONNECT; + this.session.on('sessionStateChange', (state) => { + this.onSessionStateChange(state); + }) + } + + private onSessionStateChange(state: sceneSessionManager.SessionState) { + if (this.stateChangeCallback) { + this.stateChangeCallback(state, this.session.persistentId); + } + }; +} diff --git a/product/phone/src/main/ets/SceneBoard/SCBDivider.ets b/product/phone/src/main/ets/SceneBoard/SCBDivider.ets index 4fe3749afbeef415efe1d88f12bdbad1b2a3edb5..b9db02deb7566d5b547232f8d209b9ef0dcdad17 100644 --- a/product/phone/src/main/ets/SceneBoard/SCBDivider.ets +++ b/product/phone/src/main/ets/SceneBoard/SCBDivider.ets @@ -29,7 +29,7 @@ export struct SCBDivider { buildLog1() { Log.showInfo(TAG, "Action begin primaryH: " + parseFloat(this.dividerParam.primaryH)) - return true + return true; } getSecondaryH(): string { diff --git a/product/phone/src/main/ets/SceneBoard/SCBScene.ets b/product/phone/src/main/ets/SceneBoard/SCBScene.ets index 924f564f1a8808bdacbef56a88b5f93cf14ff239..c48bf823b417ca13963ae7c69b28e6efcf7c1481 100644 --- a/product/phone/src/main/ets/SceneBoard/SCBScene.ets +++ b/product/phone/src/main/ets/SceneBoard/SCBScene.ets @@ -13,12 +13,13 @@ * limitations under the License. */ + +import sceneSessionManager from '@ohos.sceneSessionManager' import { SCBSceneSession, SCBDividerParam, SceneState, SCBGestureModel } from '@ohos/common' import { SCBGestureActionId, SCBGestureAction } from '@ohos/common' import { StyleConstants } from '@ohos/common' import { Log } from '@ohos/common' - const TAG = 'SCBScene' @Component @@ -27,6 +28,8 @@ export struct SCBScene { @Link dividerParam: SCBDividerParam @StorageLink('gestureModel') gestureModel: SCBGestureModel = new SCBGestureModel() onGestureChange: Function; + onCreateSubSession: Function; + onSubSessionChange: Function; buildLog(sceneSession: SCBSceneSession) { if (sceneSession) { @@ -35,32 +38,38 @@ export struct SCBScene { Log.showError(TAG, 'SCBSceneSession is null'); } Log.showInfo(TAG, 'SCBScene build: ' + this.sceneSession?.sceneInfo.bundleName + ' id: ' + this.sceneSession?.session.persistentId); - return true + return true; } buildLog1() { Log.showInfo(TAG, 'SCBScene panGesture end '); - return true + return true; } buildLog3() { Log.showInfo(TAG, 'SCBScene longPress begin'); - return true + return true; } enableShow() { - if (this.sceneSession) { - if (this.sceneSession.isActive) { - return true; - } - if (this.gestureModel.sceneState === SceneState.SLIDING_UP || this.gestureModel.sceneState === SceneState.RECENT) { - return true; - } + if (this.sceneSession && this.sceneSession.isActive) { + return true; + } + if (this.sceneSession && (this.gestureModel.sceneState === SceneState.SLIDING_UP || this.gestureModel.sceneState === SceneState.RECENT)) { + return true; } Log.showInfo(TAG, 'enable show is false'); return false; } + aboutToAppear() { + // registerCreateSubSessionCallback + this.sceneSession?.registerCreateSubSessionCallback(this.onCreateSubSession); + + // registerSubSessionActiveStatueChangeCallback + this.sceneSession?.registerSubSessionActiveStatueChangeCallback(this.onSubSessionChange); + } + build() { if (this.enableShow()) { Stack() { @@ -73,35 +82,35 @@ export struct SCBScene { } .size({ width: StyleConstants.PERCENTAGE_100, height: StyleConstants.PERCENTAGE_100 }) .priorityGesture( - GestureGroup(GestureMode.Sequence, - LongPressGesture({ repeat: true }) - .onAction((event: GestureEvent) => { - if (this.buildLog3()) { - } - }) - .onActionEnd(() => { - this.gestureModel.enableScroll = false - }), - PanGesture({ direction: PanDirection.Horizontal }) // when screen is vertical, use Vertical - .onActionStart((event: GestureEvent) => { - }) - .onActionUpdate((event: GestureEvent) => { - this.sceneSession.translateX = event.offsetX; - }) - .onActionEnd((event: GestureEvent) => { - if (this.buildLog1()) { - } - if (event.offsetX < -200 || event.offsetX > 200) { - let action = new SCBGestureAction({ - id: SCBGestureActionId.EXIT_SPILT, - sessionId: this.sceneSession.session.persistentId - }); - this.onGestureChange && this.onGestureChange(action); - } - this.dividerParam.init(); - this.sceneSession.translateX = 0; - }) - ) + GestureGroup(GestureMode.Sequence, + LongPressGesture({ repeat: true }) + .onAction((event: GestureEvent) => { + if (this.buildLog3()) { + } + }) + .onActionEnd(() => { + this.gestureModel.enableScroll = false + }), + PanGesture({ direction: PanDirection.Horizontal }) // when screen is vertical, use Vertical + .onActionStart((event: GestureEvent) => { + }) + .onActionUpdate((event: GestureEvent) => { + this.sceneSession.translateX = event.offsetX; + }) + .onActionEnd((event: GestureEvent) => { + if (this.buildLog1()) { + } + if (event.offsetX < -200 || event.offsetX > 200) { + let action = new SCBGestureAction({ + id: SCBGestureActionId.EXIT_SPILT, + sessionId: this.sceneSession.session.persistentId + }); + this.onGestureChange && this.onGestureChange(action); + } + this.dividerParam.init(); + this.sceneSession.translateX = 0; + }) + ) ) } } diff --git a/product/phone/src/main/ets/SceneBoard/SCBSceneContainer.ets b/product/phone/src/main/ets/SceneBoard/SCBSceneContainer.ets index 60b55a8ff83bdd3a3680cdd91718a1d8d8a3f356..80f844d1b749f87f0096e63db8300cbe5f785d80 100644 --- a/product/phone/src/main/ets/SceneBoard/SCBSceneContainer.ets +++ b/product/phone/src/main/ets/SceneBoard/SCBSceneContainer.ets @@ -14,22 +14,36 @@ */ import curves from '@ohos.curves' -import { SCBSceneContainerSession, SCBDividerParam, SCBGestureModel } from '@ohos/common' +import sceneSessionManager from '@ohos.sceneSessionManager' +import { SCBSceneContainerSession, SCBDividerParam, SCBGestureModel, SCBSceneSession } from '@ohos/common' +import { SCBSpecificSession, SCBSpecificSceneSessionList } from '@ohos/common' import { SceneState } from '@ohos/common'; import { SCBSceneSessionManager, SCBGestureAction, SCBGestureActionId, SCBScreenProperty } from '@ohos/common'; import { SCBScene } from './SCBScene' +import { SCBSpecificScene } from './SCBSpecificScene' import { SCBDivider } from './SCBDivider' import { Log } from '@ohos/common' import { StyleConstants } from '@ohos/common' const TAG = 'SCBSceneContainer' +export const ACTIVE_STATUS_MAP: Map = new Map([ + [sceneSessionManager.SessionState.STATE_CONNECT, false], + [sceneSessionManager.SessionState.STATE_FOREGROUND, true], + [sceneSessionManager.SessionState.STATE_ACTIVE, true], + [sceneSessionManager.SessionState.STATE_INACTIVE, true], + [sceneSessionManager.SessionState.STATE_BACKGROUND, false], + [sceneSessionManager.SessionState.STATE_DISCONNECT, false], +]); + @Component export struct SCBSceneContainer { @ObjectLink sceneContainerSession: SCBSceneContainerSession; @ObjectLink dividerParam: SCBDividerParam; @Link screenProperty: SCBScreenProperty; @StorageLink('gestureModel') gestureModel: SCBGestureModel = new SCBGestureModel(); + @State priSubList: SCBSpecificSceneSessionList = new SCBSpecificSceneSessionList(); + @State secSubList: SCBSpecificSceneSessionList = new SCBSpecificSceneSessionList(); containerIdx : number; onGestureChange: Function; @@ -38,7 +52,7 @@ export struct SCBSceneContainer { Log.showInfo(TAG, " containerIdx: "+ this.containerIdx + " containerId: " + this.sceneContainerSession.containerId + ' transX: ' + this.sceneContainerSession.translateX + ' transY: ' + this.sceneContainerSession.translateY + ' scaleX: ' + this.sceneContainerSession.scaleX + ' scaleY: ' + this.sceneContainerSession.scaleY) - return true + return true; } buildLog() { @@ -50,12 +64,76 @@ export struct SCBSceneContainer { return false; } if (this.sceneContainerSession && this.sceneContainerSession.isActive) { - return true + return true; } if (this.gestureModel.sceneState === SceneState.SLIDING_UP || this.gestureModel.sceneState === SceneState.RECENT) { - return true + return true; + } + return false; + } + + onCreateSubSession(sceneSession: SCBSceneSession, specificSession: sceneSessionManager.SceneSession) { + var subList; + if (this.sceneContainerSession.primarySession && + this.sceneContainerSession.primarySession.session.persistentId == sceneSession.session.persistentId) { + subList = this.priSubList; + Log.showInfo(TAG,'Parent of subSession is primary'); + } else if (this.sceneContainerSession.secondarySession && + this.sceneContainerSession.secondarySession.session.persistentId == sceneSession.session.persistentId) { + subList = this.secSubList; + Log.showInfo(TAG,'Parent of subSession is secondary'); + } else { + Log.showError(TAG, 'Invalid scene session'); + return; + } + const indexInAll = subList.findIndex(item => { + return item.session.persistentId === specificSession.persistentId; + }); + if (indexInAll == -1) { + let hwSceneSession = new SCBSpecificSession(specificSession, sceneSession.handleSubSessionStateChange.bind(sceneSession)); + subList.push(hwSceneSession); + } else { + Log.showInfo(TAG, `Session is already in subList, id: ${specificSession.persistentId}, index: ${indexInAll}`); + } + } + + onSubSessionActiveStatueChange(sceneSession: SCBSceneSession, persistentId: number, state: sceneSessionManager.SessionState) { + var subList; + if (this.sceneContainerSession.primarySession && + this.sceneContainerSession.primarySession.session.persistentId == sceneSession.session.persistentId) { + subList = this.priSubList; + Log.showInfo(TAG,'Parent of subSession is primary'); + } else if (this.sceneContainerSession.secondarySession && + this.sceneContainerSession.secondarySession.session.persistentId == sceneSession.session.persistentId) { + subList = this.secSubList; + Log.showInfo(TAG,'Parent of subSession is secondary'); + } else { + Log.showError(TAG, 'Invalid scene session'); + return; + } + const index = subList.findIndex(item => { + return item.session.persistentId == persistentId; + }); + if (index != -1) { + let isActive = ACTIVE_STATUS_MAP.get(state) + if (isActive == undefined || !subList[index]) { + return; + } + if (state == sceneSessionManager.SessionState.STATE_DISCONNECT) { + subList.splice(index, 1); + return; + } + subList[index].isActive = isActive; + subList[index].sessionState = state; + Log.showInfo(TAG, `Session avtive status change, persistentId: ${persistentId}, isActive: ${subList[index].isActive}, length: ${subList.length}}`); } - return false + } + + aboutToAppear() { + this.priSubList = this.sceneContainerSession.primarySession?.subSessionList; + this.secSubList = this.sceneContainerSession.secondarySession?.subSessionList; + this.onCreateSubSession = this.onCreateSubSession.bind(this); + this.onSubSessionActiveStatueChange = this.onSubSessionActiveStatueChange.bind(this); } build() { @@ -64,11 +142,25 @@ export struct SCBSceneContainer { Column() { if (this.buildLog2()) {} if (this.sceneContainerSession.primarySession) { - SCBScene({ sceneSession: this.sceneContainerSession.primarySession, dividerParam: $dividerParam, onGestureChange: this.onGestureChange }) - .width('100%') - .height(this.dividerParam.primaryH) - .scale({ y: this.dividerParam.primaryScaleY, centerY: 0 }) - .blur(this.dividerParam.blurRadius) + Stack() { + // Scene Session + SCBScene({ + sceneSession: this.sceneContainerSession.primarySession, + dividerParam: $dividerParam, + onGestureChange: this.onGestureChange, + onCreateSubSession: this.onCreateSubSession, + onSubSessionChange: this.onSubSessionActiveStatueChange + }) + .width('100%') + .height(this.dividerParam.primaryH) + .scale({ y: this.dividerParam.primaryScaleY, centerY: 0 }) + .blur(this.dividerParam.blurRadius) + + // Sub SceneSession + ForEach(this.priSubList, (item: SCBSpecificSession) => { + SCBSpecificScene({ specificSession: item, screenProperty: $screenProperty}) + }, (item: SCBSpecificSession) => item.session.persistentId.toString()) + } } // divider @@ -79,11 +171,25 @@ export struct SCBSceneContainer { // When primary Exit if (this.sceneContainerSession.secondarySession) { - SCBScene({ sceneSession: this.sceneContainerSession.secondarySession, dividerParam: $dividerParam, onGestureChange: this.onGestureChange }) - .scale({ y: this.dividerParam.secondaryScaleY, centerY: 0 }) - .blur(this.dividerParam.blurRadius) - .translate({ y: this.dividerParam.secTransY }) - .flexShrink(1) + Stack() { + // Scene Session + SCBScene({ + sceneSession: this.sceneContainerSession.secondarySession, + dividerParam: $dividerParam, + onGestureChange: this.onGestureChange, + onCreateSubSession: this.onCreateSubSession, + onSubSessionChange: this.onSubSessionActiveStatueChange + }) + .scale({ y: this.dividerParam.secondaryScaleY, centerY: 0 }) + .blur(this.dividerParam.blurRadius) + .translate({ y: this.dividerParam.secTransY }) + .flexShrink(1) + + // Sub SceneSession + ForEach(this.secSubList, (item: SCBSpecificSession) => { + SCBSpecificScene({ specificSession: item, screenProperty: $screenProperty}) + }, (item: SCBSpecificSession) => item.session.persistentId.toString()) + } } } .size({ width: StyleConstants.PERCENTAGE_100, height: StyleConstants.PERCENTAGE_100 }) diff --git a/product/phone/src/main/ets/SceneBoard/SCBScenePanel.ets b/product/phone/src/main/ets/SceneBoard/SCBScenePanel.ets index 2357b204a1e6c9d2cdfd4c66129a4077de321879..7b01f49858b4e7b7ecb7f68f7ff3297f09272967 100644 --- a/product/phone/src/main/ets/SceneBoard/SCBScenePanel.ets +++ b/product/phone/src/main/ets/SceneBoard/SCBScenePanel.ets @@ -50,7 +50,7 @@ export struct SCBScenePanel { return true; } - // sceneSessionManager 当前屏幕的scene的添加 + // sceneSessionManager Add scene of current screen isRecent(): boolean { Log.showInfo(TAG,"isRecent = " +(this.gestureModel.sceneState === SceneState.RECENT)) Log.showInfo(TAG, "this.gestureModel.flexOffsetX: " + (this.gestureModel.flexOffsetX) + ' flexWidth: ' + (this.gestureModel.flexWidth)) diff --git a/product/phone/src/main/ets/SceneBoard/SCBScreen.ets b/product/phone/src/main/ets/SceneBoard/SCBScreen.ets index 85c78061e0f6e28830e9abdb5fc685453c4cd5f1..c69fabb137f754def4ec2c0bd7cd67dc3da23868 100644 --- a/product/phone/src/main/ets/SceneBoard/SCBScreen.ets +++ b/product/phone/src/main/ets/SceneBoard/SCBScreen.ets @@ -15,6 +15,7 @@ import { SCBScenePanel } from './SCBScenePanel' import { SCBScreenSession, SCBScreenProperty } from '@ohos/common' +import { SCBSpecificSceneSessionList, SCBSceneSessionManager, SCBSpecificSession } from '@ohos/common' import { SCBDesktop } from './SCBDesktop' import { SCBWallpaper } from './SCBWallpaper' import { SCBStatusBar } from './statusbar/SCBStatusBar'; @@ -31,6 +32,9 @@ import WindowPanelManager, { SystemUi_BannerNotice, SystemUi_VolumePanel } from '@ohos/common/src/main/ets/default/manager/WindowPanelManager'; +import { SCBSpecificScenePanel } from './SCBSpecificScenePanel' +import sceneSessionManager from '@ohos.sceneSessionManager' +import { ACTIVE_STATUS_MAP } from './SCBSceneContainer' const MODULE_NAME = "phone-sceneboard"; const TAG = 'SCBScreen'; @@ -42,13 +46,46 @@ export struct SCBScreen { @StorageLink(SystemUi_DropdownPanel) mDropDownInfo: WindowInfo = WindowPanelManager.getWindowInfo(WindowType.DROPDOWN_PANEL); @StorageLink(SystemUi_BannerNotice) mBannerInfo: WindowInfo = WindowPanelManager.getWindowInfo(WindowType.BANNER_NOTICE); @StorageLink(SystemUi_VolumePanel) mVolumeInfo: WindowInfo = WindowPanelManager.getWindowInfo(WindowType.VOLUME_PANEL); + @State systemSceneList: SCBSpecificSceneSessionList = new SCBSpecificSceneSessionList(); - // screen 数据改变 + // screen property change onScreenPropertyChange(screenProperty: screenSessionManager.ScreenProperty) { Log.showInfo(TAG, 'scbScreenProperty'); this.scbScreenProperty.update(screenProperty); this.scbScreenProperty.screenId = this.screenSession.session.screenId; - Log.showInfo(TAG, `Update scbScreenProperty[${this.scbScreenProperty.left}, ${this.scbScreenProperty.top}, ${this.scbScreenProperty.width}, ${this.scbScreenProperty.height}]`) + Log.showInfo(TAG, `Update scbScreenProperty[${this.scbScreenProperty.left}, ${this.scbScreenProperty.top}, + ${this.scbScreenProperty.width}, ${this.scbScreenProperty.height}]`) + } + + onSessionStateChange(state: sceneSessionManager.SessionState, sessionId: Number) { + const index = this.systemSceneList.findIndex(item => { + return item.session.persistentId == sessionId; + }); + if (index != -1) { + let isActive = ACTIVE_STATUS_MAP.get(state) + if (isActive == undefined || !this.systemSceneList[index]) { + return; + } + this.systemSceneList[index].isActive = isActive; + if (state == sceneSessionManager.SessionState.STATE_DISCONNECT) { + this.systemSceneList.splice(index, 1); + return; + } + Log.showInfo(TAG, `onSubSessionActiveStatueChange persistentId: ${sessionId}, isActive: ${this.systemSceneList[index].isActive}, length: ${this.systemSceneList.length}}`); + } + } + + onCreateSpecificScene(specificSession: sceneSessionManager.SceneSession) { + const indexInAll = this.systemSceneList.findIndex(item => { + return item.session?.persistentId === specificSession?.persistentId; + }); + if (indexInAll == -1) { + let hwSceneSession = new SCBSpecificSession(specificSession, this.onSessionStateChange); + this.systemSceneList.push(hwSceneSession); + } else { + Log.showInfo(TAG, `Session is already in subList, id: ${specificSession.persistentId}, index: ${indexInAll}`); + } + Log.showInfo(TAG, `onCreateSpecificScene`); } aboutToAppear() { @@ -56,6 +93,10 @@ export struct SCBScreen { this.screenSession.registerPropertyChange((screenProperty: screenSessionManager.ScreenProperty) => { this.onScreenPropertyChange(screenProperty); }) + this.onSessionStateChange = this.onSessionStateChange.bind(this); + SCBSceneSessionManager.getInstance().registerCreateSpecificSceneCallback((specificSession: sceneSessionManager.SceneSession) => { + this.onCreateSpecificScene(specificSession); + }) } build() { @@ -71,6 +112,9 @@ export struct SCBScreen { screenProperty: $scbScreenProperty }) + // system app + SCBSpecificScenePanel({systemSceneList: this.systemSceneList, screenProperty: $scbScreenProperty}) + // status bar SCBStatusBar({bounds : this.screenSession.bounds, moduleName: MODULE_NAME}) .position({x: 0, y: 0}) diff --git a/product/phone/src/main/ets/SceneBoard/SCBSpecificScene.ets b/product/phone/src/main/ets/SceneBoard/SCBSpecificScene.ets new file mode 100644 index 0000000000000000000000000000000000000000..1bfaafd29adeb5b06ab54b17af905204fbac8e8b --- /dev/null +++ b/product/phone/src/main/ets/SceneBoard/SCBSpecificScene.ets @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023 Huawei Device 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 { Log } from '@ohos/common' +import { SCBSpecificSession, SCBScreenProperty } from '@ohos/common' +import { StyleConstants } from '@ohos/common' + +const TAG = 'SCBSpecificScene' + +@Component +export struct SCBSpecificScene { + @ObjectLink @Watch("BuildSCBSpecificScene") specificSession: SCBSpecificSession; + @Link screenProperty: SCBScreenProperty; + + BuildSCBSpecificScene() { + Log.showInfo(TAG, 'Build BuildSCBSpecificScene'); + } + + buildLog(specificSession: SCBSpecificSession) { + if (specificSession) { + Log.showDebug(TAG, 'Build SCBSpecificSession' + ' id: ' + this.specificSession?.session.persistentId); + } else { + Log.showError(TAG, 'SCBSceneSession is null'); + } + return true; + } + + enableShow() { + if (this.specificSession && this.specificSession.isActive) { + Log.showDebug(TAG, 'enable show is true'); + return true; + } + Log.showError(TAG, 'enable show is false'); + return false; + } + + build() { + if (this.enableShow()) { + if (this.buildLog(this.specificSession)) { + } + HostWindowScene(this.specificSession?.session.persistentId) + .size({ width: StyleConstants.PERCENTAGE_100, height: StyleConstants.PERCENTAGE_100 }) + } + } +} diff --git a/product/phone/src/main/ets/SceneBoard/SCBSpecificScenePanel.ets b/product/phone/src/main/ets/SceneBoard/SCBSpecificScenePanel.ets new file mode 100644 index 0000000000000000000000000000000000000000..832207c92d003050164760615d45209629984e62 --- /dev/null +++ b/product/phone/src/main/ets/SceneBoard/SCBSpecificScenePanel.ets @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 Huawei Device 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 { Log } from '@ohos/common' +import { SCBSpecificSession, SCBSpecificSceneSessionList, SCBScreenProperty } from '@ohos/common' +import { SCBSpecificScene } from './SCBSpecificScene' + +const TAG = 'SCBSpecificScenePanel' + +@Component +export struct SCBSpecificScenePanel { + @ObjectLink @Watch("BuildSCBSpecificScenePanel") systemSceneList: SCBSpecificSceneSessionList; + @Link screenProperty: SCBScreenProperty; + + BuildSCBSpecificScenePanel() { + Log.showInfo(TAG, 'Build SCBSpecificScenePanel'); + } + + build() { + Stack() { + ForEach(this.systemSceneList, (item: SCBSpecificSession) => { + SCBSpecificScene({ specificSession: item, screenProperty: $screenProperty }) + }, (item: SCBSpecificSession) => item.session?.persistentId.toString()) + } + } +}