Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +9 −2 Original line number Diff line number Diff line Loading @@ -114,6 +114,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private final Choreographer mChoreographer; private final SyncTransactionQueue mSyncQueue; private final SplitScreenController mSplitScreenController; private final WindowManagerWrapper mWindowManagerWrapper; private WindowDecorationViewHolder mWindowDecorViewHolder; private View.OnClickListener mOnCaptionButtonClickListener; Loading Loading @@ -188,7 +189,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin taskInfo, taskSurface, handler, bgExecutor, choreographer, syncQueue, rootTaskDisplayAreaOrganizer, genericLinksParser, SurfaceControl.Builder::new, SurfaceControl.Transaction::new, WindowContainerTransaction::new, SurfaceControl::new, new SurfaceControlViewHostFactory() {}, SurfaceControl::new, new WindowManagerWrapper( context.getSystemService(WindowManager.class)), new SurfaceControlViewHostFactory() {}, DefaultMaximizeMenuFactory.INSTANCE, DefaultHandleMenuFactory.INSTANCE, multiInstanceHelper); } Loading @@ -211,6 +214,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier, Supplier<WindowContainerTransaction> windowContainerTransactionSupplier, Supplier<SurfaceControl> surfaceControlSupplier, WindowManagerWrapper windowManagerWrapper, SurfaceControlViewHostFactory surfaceControlViewHostFactory, MaximizeMenuFactory maximizeMenuFactory, HandleMenuFactory handleMenuFactory, Loading @@ -229,6 +233,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mMaximizeMenuFactory = maximizeMenuFactory; mHandleMenuFactory = handleMenuFactory; mMultiInstanceHelper = multiInstanceHelper; mWindowManagerWrapper = windowManagerWrapper; } /** Loading Loading @@ -574,7 +579,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin return new AppHandleViewHolder( mResult.mRootView, mOnCaptionTouchListener, mOnCaptionButtonClickListener mOnCaptionButtonClickListener, mWindowManagerWrapper ); } else if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_app_header) { Loading Loading @@ -988,6 +994,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin updateGenericLink(); mHandleMenu = mHandleMenuFactory.create( this, mWindowManagerWrapper, mRelayoutParams.mLayoutResId, mAppIconBitmap, mAppName, Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt +5 −1 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import com.android.wm.shell.windowdecor.extension.isPinned */ class HandleMenu( private val parentDecor: DesktopModeWindowDecoration, private val windowManagerWrapper: WindowManagerWrapper, private val layoutResId: Int, private val appIconBitmap: Bitmap?, private val appName: CharSequence?, Loading Loading @@ -178,7 +179,7 @@ class HandleMenu( handleMenuViewContainer = if (!taskInfo.isFreeform && Flags.enableAdditionalWindowsAboveStatusBar()) { AdditionalSystemViewContainer( context = context, windowManagerWrapper = windowManagerWrapper, taskId = taskInfo.taskId, x = x, y = y, Loading Loading @@ -635,6 +636,7 @@ class HandleMenu( interface HandleMenuFactory { fun create( parentDecor: DesktopModeWindowDecoration, windowManagerWrapper: WindowManagerWrapper, layoutResId: Int, appIconBitmap: Bitmap?, appName: CharSequence?, Loading @@ -652,6 +654,7 @@ interface HandleMenuFactory { object DefaultHandleMenuFactory : HandleMenuFactory { override fun create( parentDecor: DesktopModeWindowDecoration, windowManagerWrapper: WindowManagerWrapper, layoutResId: Int, appIconBitmap: Bitmap?, appName: CharSequence?, Loading @@ -665,6 +668,7 @@ object DefaultHandleMenuFactory : HandleMenuFactory { ): HandleMenu { return HandleMenu( parentDecor, windowManagerWrapper, layoutResId, appIconBitmap, appName, Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowManagerWrapper.kt 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * 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. */ package com.android.wm.shell.windowdecor import android.view.View import android.view.WindowManager /** * A wrapper for [WindowManager] to make view manipulation operations related to window * decors more testable. */ class WindowManagerWrapper ( private val windowManager: WindowManager ){ fun addView(v: View, lp: WindowManager.LayoutParams) { windowManager.addView(v, lp) } fun removeViewImmediate(v: View) { windowManager.removeViewImmediate(v) } fun updateViewLayout(v: View, lp: WindowManager.LayoutParams) { windowManager.updateViewLayout(v, lp) } } No newline at end of file libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt +26 −19 Original line number Diff line number Diff line Loading @@ -24,13 +24,14 @@ import android.view.LayoutInflater import android.view.SurfaceControl import android.view.View import android.view.WindowManager import com.android.wm.shell.windowdecor.WindowManagerWrapper /** * An [AdditionalViewContainer] that uses the system [WindowManager] instance. Intended * for view containers that should be above the status bar layer. */ class AdditionalSystemViewContainer( context: Context, private val windowManagerWrapper: WindowManagerWrapper, taskId: Int, x: Int, y: Int, Loading @@ -39,9 +40,20 @@ class AdditionalSystemViewContainer( flags: Int, override val view: View ) : AdditionalViewContainer() { val lp: WindowManager.LayoutParams = WindowManager.LayoutParams( width, height, x, y, WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL, flags, PixelFormat.TRANSPARENT ).apply { title = "Additional view container of Task=$taskId" gravity = Gravity.LEFT or Gravity.TOP setTrustedOverlay() } constructor( context: Context, windowManagerWrapper: WindowManagerWrapper, taskId: Int, x: Int, y: Int, Loading @@ -50,7 +62,7 @@ class AdditionalSystemViewContainer( flags: Int, @LayoutRes layoutId: Int ) : this( context = context, windowManagerWrapper = windowManagerWrapper, taskId = taskId, x = x, y = y, Loading @@ -61,9 +73,16 @@ class AdditionalSystemViewContainer( ) constructor( context: Context, taskId: Int, x: Int, y: Int, width: Int, height: Int, flags: Int context: Context, windowManagerWrapper: WindowManagerWrapper, taskId: Int, x: Int, y: Int, width: Int, height: Int, flags: Int ) : this( context = context, windowManagerWrapper = windowManagerWrapper, taskId = taskId, x = x, y = y, Loading @@ -73,24 +92,12 @@ class AdditionalSystemViewContainer( view = View(context) ) val windowManager: WindowManager? = context.getSystemService(WindowManager::class.java) init { val lp = WindowManager.LayoutParams( width, height, x, y, WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL, flags, PixelFormat.TRANSPARENT ).apply { title = "Additional view container of Task=$taskId" gravity = Gravity.LEFT or Gravity.TOP setTrustedOverlay() } windowManager?.addView(view, lp) windowManagerWrapper.addView(view, lp) } override fun releaseView() { windowManager?.removeViewImmediate(view) windowManagerWrapper.removeViewImmediate(view) } override fun setPosition(t: SurfaceControl.Transaction, x: Float, y: Float) { Loading @@ -98,6 +105,6 @@ class AdditionalSystemViewContainer( this.x = x.toInt() this.y = y.toInt() } windowManager?.updateViewLayout(view, lp) windowManagerWrapper.updateViewLayout(view, lp) } } libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt +9 −7 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.widget.ImageButton import com.android.window.flags.Flags import com.android.wm.shell.R import com.android.wm.shell.shared.animation.Interpolators import com.android.wm.shell.windowdecor.WindowManagerWrapper import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer /** Loading @@ -41,14 +42,14 @@ import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystem internal class AppHandleViewHolder( rootView: View, onCaptionTouchListener: View.OnTouchListener, onCaptionButtonClickListener: OnClickListener onCaptionButtonClickListener: OnClickListener, private val windowManagerWrapper: WindowManagerWrapper ) : WindowDecorationViewHolder(rootView) { companion object { private const val CAPTION_HANDLE_ANIMATION_DURATION: Long = 100 } private lateinit var taskInfo: RunningTaskInfo private val windowManager = context.getSystemService(WindowManager::class.java) private val captionView: View = rootView.requireViewById(R.id.desktop_mode_caption) private val captionHandle: ImageButton = rootView.requireViewById(R.id.caption_handle) private val inputManager = context.getSystemService(InputManager::class.java) Loading Loading @@ -96,11 +97,12 @@ internal class AppHandleViewHolder( handleWidth: Int, handleHeight: Int) { if (!Flags.enableAdditionalWindowsAboveStatusBar()) return statusBarInputLayer = AdditionalSystemViewContainer(context, taskInfo.taskId, handlePosition.x, handlePosition.y, handleWidth, handleHeight, statusBarInputLayer = AdditionalSystemViewContainer(context, windowManagerWrapper, taskInfo.taskId, handlePosition.x, handlePosition.y, handleWidth, handleHeight, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) val view = statusBarInputLayer?.view val lp = view?.layoutParams as WindowManager.LayoutParams val view = statusBarInputLayer?.view ?: error("Unable to find statusBarInputLayer View") val lp = statusBarInputLayer?.lp ?: error("Unable to find statusBarInputLayer" + "LayoutParams") lp.title = "Handle Input Layer of task " + taskInfo.taskId lp.setTrustedOverlay() // Make this window a spy window to enable it to pilfer pointers from the system-wide Loading @@ -120,7 +122,7 @@ internal class AppHandleViewHolder( captionHandle.dispatchTouchEvent(event) true } windowManager.updateViewLayout(view, lp) windowManagerWrapper.updateViewLayout(view, lp) } private fun updateStatusBarInputLayer(globalPosition: Point) { Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +9 −2 Original line number Diff line number Diff line Loading @@ -114,6 +114,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private final Choreographer mChoreographer; private final SyncTransactionQueue mSyncQueue; private final SplitScreenController mSplitScreenController; private final WindowManagerWrapper mWindowManagerWrapper; private WindowDecorationViewHolder mWindowDecorViewHolder; private View.OnClickListener mOnCaptionButtonClickListener; Loading Loading @@ -188,7 +189,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin taskInfo, taskSurface, handler, bgExecutor, choreographer, syncQueue, rootTaskDisplayAreaOrganizer, genericLinksParser, SurfaceControl.Builder::new, SurfaceControl.Transaction::new, WindowContainerTransaction::new, SurfaceControl::new, new SurfaceControlViewHostFactory() {}, SurfaceControl::new, new WindowManagerWrapper( context.getSystemService(WindowManager.class)), new SurfaceControlViewHostFactory() {}, DefaultMaximizeMenuFactory.INSTANCE, DefaultHandleMenuFactory.INSTANCE, multiInstanceHelper); } Loading @@ -211,6 +214,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier, Supplier<WindowContainerTransaction> windowContainerTransactionSupplier, Supplier<SurfaceControl> surfaceControlSupplier, WindowManagerWrapper windowManagerWrapper, SurfaceControlViewHostFactory surfaceControlViewHostFactory, MaximizeMenuFactory maximizeMenuFactory, HandleMenuFactory handleMenuFactory, Loading @@ -229,6 +233,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mMaximizeMenuFactory = maximizeMenuFactory; mHandleMenuFactory = handleMenuFactory; mMultiInstanceHelper = multiInstanceHelper; mWindowManagerWrapper = windowManagerWrapper; } /** Loading Loading @@ -574,7 +579,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin return new AppHandleViewHolder( mResult.mRootView, mOnCaptionTouchListener, mOnCaptionButtonClickListener mOnCaptionButtonClickListener, mWindowManagerWrapper ); } else if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_app_header) { Loading Loading @@ -988,6 +994,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin updateGenericLink(); mHandleMenu = mHandleMenuFactory.create( this, mWindowManagerWrapper, mRelayoutParams.mLayoutResId, mAppIconBitmap, mAppName, Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt +5 −1 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import com.android.wm.shell.windowdecor.extension.isPinned */ class HandleMenu( private val parentDecor: DesktopModeWindowDecoration, private val windowManagerWrapper: WindowManagerWrapper, private val layoutResId: Int, private val appIconBitmap: Bitmap?, private val appName: CharSequence?, Loading Loading @@ -178,7 +179,7 @@ class HandleMenu( handleMenuViewContainer = if (!taskInfo.isFreeform && Flags.enableAdditionalWindowsAboveStatusBar()) { AdditionalSystemViewContainer( context = context, windowManagerWrapper = windowManagerWrapper, taskId = taskInfo.taskId, x = x, y = y, Loading Loading @@ -635,6 +636,7 @@ class HandleMenu( interface HandleMenuFactory { fun create( parentDecor: DesktopModeWindowDecoration, windowManagerWrapper: WindowManagerWrapper, layoutResId: Int, appIconBitmap: Bitmap?, appName: CharSequence?, Loading @@ -652,6 +654,7 @@ interface HandleMenuFactory { object DefaultHandleMenuFactory : HandleMenuFactory { override fun create( parentDecor: DesktopModeWindowDecoration, windowManagerWrapper: WindowManagerWrapper, layoutResId: Int, appIconBitmap: Bitmap?, appName: CharSequence?, Loading @@ -665,6 +668,7 @@ object DefaultHandleMenuFactory : HandleMenuFactory { ): HandleMenu { return HandleMenu( parentDecor, windowManagerWrapper, layoutResId, appIconBitmap, appName, Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowManagerWrapper.kt 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * 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. */ package com.android.wm.shell.windowdecor import android.view.View import android.view.WindowManager /** * A wrapper for [WindowManager] to make view manipulation operations related to window * decors more testable. */ class WindowManagerWrapper ( private val windowManager: WindowManager ){ fun addView(v: View, lp: WindowManager.LayoutParams) { windowManager.addView(v, lp) } fun removeViewImmediate(v: View) { windowManager.removeViewImmediate(v) } fun updateViewLayout(v: View, lp: WindowManager.LayoutParams) { windowManager.updateViewLayout(v, lp) } } No newline at end of file
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt +26 −19 Original line number Diff line number Diff line Loading @@ -24,13 +24,14 @@ import android.view.LayoutInflater import android.view.SurfaceControl import android.view.View import android.view.WindowManager import com.android.wm.shell.windowdecor.WindowManagerWrapper /** * An [AdditionalViewContainer] that uses the system [WindowManager] instance. Intended * for view containers that should be above the status bar layer. */ class AdditionalSystemViewContainer( context: Context, private val windowManagerWrapper: WindowManagerWrapper, taskId: Int, x: Int, y: Int, Loading @@ -39,9 +40,20 @@ class AdditionalSystemViewContainer( flags: Int, override val view: View ) : AdditionalViewContainer() { val lp: WindowManager.LayoutParams = WindowManager.LayoutParams( width, height, x, y, WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL, flags, PixelFormat.TRANSPARENT ).apply { title = "Additional view container of Task=$taskId" gravity = Gravity.LEFT or Gravity.TOP setTrustedOverlay() } constructor( context: Context, windowManagerWrapper: WindowManagerWrapper, taskId: Int, x: Int, y: Int, Loading @@ -50,7 +62,7 @@ class AdditionalSystemViewContainer( flags: Int, @LayoutRes layoutId: Int ) : this( context = context, windowManagerWrapper = windowManagerWrapper, taskId = taskId, x = x, y = y, Loading @@ -61,9 +73,16 @@ class AdditionalSystemViewContainer( ) constructor( context: Context, taskId: Int, x: Int, y: Int, width: Int, height: Int, flags: Int context: Context, windowManagerWrapper: WindowManagerWrapper, taskId: Int, x: Int, y: Int, width: Int, height: Int, flags: Int ) : this( context = context, windowManagerWrapper = windowManagerWrapper, taskId = taskId, x = x, y = y, Loading @@ -73,24 +92,12 @@ class AdditionalSystemViewContainer( view = View(context) ) val windowManager: WindowManager? = context.getSystemService(WindowManager::class.java) init { val lp = WindowManager.LayoutParams( width, height, x, y, WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL, flags, PixelFormat.TRANSPARENT ).apply { title = "Additional view container of Task=$taskId" gravity = Gravity.LEFT or Gravity.TOP setTrustedOverlay() } windowManager?.addView(view, lp) windowManagerWrapper.addView(view, lp) } override fun releaseView() { windowManager?.removeViewImmediate(view) windowManagerWrapper.removeViewImmediate(view) } override fun setPosition(t: SurfaceControl.Transaction, x: Float, y: Float) { Loading @@ -98,6 +105,6 @@ class AdditionalSystemViewContainer( this.x = x.toInt() this.y = y.toInt() } windowManager?.updateViewLayout(view, lp) windowManagerWrapper.updateViewLayout(view, lp) } }
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt +9 −7 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.widget.ImageButton import com.android.window.flags.Flags import com.android.wm.shell.R import com.android.wm.shell.shared.animation.Interpolators import com.android.wm.shell.windowdecor.WindowManagerWrapper import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer /** Loading @@ -41,14 +42,14 @@ import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystem internal class AppHandleViewHolder( rootView: View, onCaptionTouchListener: View.OnTouchListener, onCaptionButtonClickListener: OnClickListener onCaptionButtonClickListener: OnClickListener, private val windowManagerWrapper: WindowManagerWrapper ) : WindowDecorationViewHolder(rootView) { companion object { private const val CAPTION_HANDLE_ANIMATION_DURATION: Long = 100 } private lateinit var taskInfo: RunningTaskInfo private val windowManager = context.getSystemService(WindowManager::class.java) private val captionView: View = rootView.requireViewById(R.id.desktop_mode_caption) private val captionHandle: ImageButton = rootView.requireViewById(R.id.caption_handle) private val inputManager = context.getSystemService(InputManager::class.java) Loading Loading @@ -96,11 +97,12 @@ internal class AppHandleViewHolder( handleWidth: Int, handleHeight: Int) { if (!Flags.enableAdditionalWindowsAboveStatusBar()) return statusBarInputLayer = AdditionalSystemViewContainer(context, taskInfo.taskId, handlePosition.x, handlePosition.y, handleWidth, handleHeight, statusBarInputLayer = AdditionalSystemViewContainer(context, windowManagerWrapper, taskInfo.taskId, handlePosition.x, handlePosition.y, handleWidth, handleHeight, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) val view = statusBarInputLayer?.view val lp = view?.layoutParams as WindowManager.LayoutParams val view = statusBarInputLayer?.view ?: error("Unable to find statusBarInputLayer View") val lp = statusBarInputLayer?.lp ?: error("Unable to find statusBarInputLayer" + "LayoutParams") lp.title = "Handle Input Layer of task " + taskInfo.taskId lp.setTrustedOverlay() // Make this window a spy window to enable it to pilfer pointers from the system-wide Loading @@ -120,7 +122,7 @@ internal class AppHandleViewHolder( captionHandle.dispatchTouchEvent(event) true } windowManager.updateViewLayout(view, lp) windowManagerWrapper.updateViewLayout(view, lp) } private fun updateStatusBarInputLayer(globalPosition: Point) { Loading