summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jorge Gil <jorgegil@google.com> 2023-03-16 23:22:40 +0000
committer Jorge Gil <jorgegil@google.com> 2023-03-21 00:11:41 +0000
commitd5e48ae2362e02c2bf4ceee7719072edc3cbe3ab (patch)
tree8ab4bd58b47e8930badcda975193d518926c96be
parent2628c45e6b71b8d001ff6cd1ef55d95575a8e0b1 (diff)
Delegate window decor view binding / updating to *ViewHolders
Moves view binding and updates from the new task data in relayout to a *ViewHolder class made for each "type" of window decoration UI. This allows caching of findViewById calls and isolated view binding logic for different UI variants of the caption window decoration. Bug: 269618335 Test: use proto1/proto2 and switch between modes, no UI/behavior changes observed Change-Id: Ib2f1d194af72883653ac93bbd98ae4e9e7b4376a
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java116
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt94
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeFocusedWindowDecorationViewHolder.kt44
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeWindowDecorationViewHolder.kt28
4 files changed, 187 insertions, 95 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 73bd521fd2f2..01187ed94de5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -22,13 +22,10 @@ import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.graphics.Color;
import android.graphics.Point;
import android.graphics.PointF;
-import android.graphics.drawable.GradientDrawable;
import android.os.Handler;
import android.util.Log;
import android.view.Choreographer;
@@ -36,7 +33,6 @@ import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewConfiguration;
-import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.window.WindowContainerTransaction;
@@ -47,6 +43,9 @@ import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.desktopmode.DesktopModeStatus;
import com.android.wm.shell.desktopmode.DesktopTasksController;
+import com.android.wm.shell.windowdecor.viewholder.DesktopModeAppControlsWindowDecorationViewHolder;
+import com.android.wm.shell.windowdecor.viewholder.DesktopModeFocusedWindowDecorationViewHolder;
+import com.android.wm.shell.windowdecor.viewholder.DesktopModeWindowDecorationViewHolder;
/**
* Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with
@@ -61,6 +60,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
private final Choreographer mChoreographer;
private final SyncTransactionQueue mSyncQueue;
+ private DesktopModeWindowDecorationViewHolder mWindowDecorViewHolder;
private View.OnClickListener mOnCaptionButtonClickListener;
private View.OnTouchListener mOnCaptionTouchListener;
private DragPositioningCallback mDragPositioningCallback;
@@ -171,11 +171,24 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
return;
}
if (oldRootView != mResult.mRootView) {
- setupRootView();
+ if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_focused_window_decor) {
+ mWindowDecorViewHolder = new DesktopModeFocusedWindowDecorationViewHolder(
+ mResult.mRootView,
+ mOnCaptionTouchListener,
+ mOnCaptionButtonClickListener
+ );
+ } else if (mRelayoutParams.mLayoutResId
+ == R.layout.desktop_mode_app_controls_window_decor) {
+ mWindowDecorViewHolder = new DesktopModeAppControlsWindowDecorationViewHolder(
+ mResult.mRootView,
+ mOnCaptionTouchListener,
+ mOnCaptionButtonClickListener
+ );
+ } else {
+ throw new IllegalArgumentException("Unexpected layout resource id");
+ }
}
-
- updateAppInfo();
- setCaptionColor(taskInfo.taskDescription.getStatusBarColor());
+ mWindowDecorViewHolder.bindData(mTaskInfo);
if (!isDragResizeable) {
closeDragResizeListener();
@@ -205,27 +218,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mResult.mWidth, mResult.mHeight, resize_handle, resize_corner, touchSlop);
}
- /**
- * Sets up listeners when a new root view is created.
- */
- private void setupRootView() {
- final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
- caption.setOnTouchListener(mOnCaptionTouchListener);
- final View handle = caption.findViewById(R.id.caption_handle);
- handle.setOnTouchListener(mOnCaptionTouchListener);
- if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_focused_window_decor) {
- handle.setOnClickListener(mOnCaptionButtonClickListener);
- } else if (mRelayoutParams.mLayoutResId
- == R.layout.desktop_mode_app_controls_window_decor) {
- caption.findViewById(R.id.open_menu_button)
- .setOnClickListener(mOnCaptionButtonClickListener);
- caption.findViewById(R.id.close_window)
- .setOnClickListener(mOnCaptionButtonClickListener);
- } else {
- throw new IllegalArgumentException("Unexpected layout resource id");
- }
- }
-
private void setupHandleMenu() {
final View menu = mHandleMenu.mWindowViewHost.getView();
final View fullscreen = menu.findViewById(R.id.fullscreen_button);
@@ -249,17 +241,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
loadAppInfo(appName, appIcon);
}
- private void updateAppInfo() {
- if (mRelayoutParams.mLayoutResId
- != R.layout.desktop_mode_app_controls_window_decor) {
- // The app info views only apply to the app controls window decor type.
- return;
- }
- final TextView appNameTextView = mResult.mRootView.findViewById(R.id.application_name);
- final ImageView appIconImageView = mResult.mRootView.findViewById(R.id.application_icon);
- loadAppInfo(appNameTextView, appIconImageView);
- }
-
boolean isHandleMenuActive() {
return mHandleMenu != null;
}
@@ -278,61 +259,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
}
}
- private void setCaptionColor(int captionColor) {
- if (mResult.mRootView == null) {
- return;
- }
-
- final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
- final GradientDrawable captionDrawable = (GradientDrawable) caption.getBackground();
- captionDrawable.setColor(captionColor);
-
- final boolean shouldUseLightCaptionViews = Color.valueOf(captionColor).luminance() < 0.5;
- if (mRelayoutParams.mLayoutResId
- == R.layout.desktop_mode_focused_window_decor) {
- final ImageButton captionBar = caption.findViewById(R.id.caption_handle);
- captionBar.setImageTintList(ColorStateList.valueOf(
- getCaptionHandleBarColor(shouldUseLightCaptionViews)));
- } else if (mRelayoutParams.mLayoutResId
- == R.layout.desktop_mode_app_controls_window_decor) {
- final ImageButton closeBtn = caption.findViewById(R.id.close_window);
- final ImageButton expandBtn = caption.findViewById(R.id.expand_menu_button);
- final TextView appNameTextView = caption.findViewById(R.id.application_name);
- closeBtn.setImageTintList(ColorStateList.valueOf(
- getCaptionCloseButtonColor(shouldUseLightCaptionViews)));
- expandBtn.setImageTintList(ColorStateList.valueOf(
- getCaptionExpandButtonColor(shouldUseLightCaptionViews)));
- appNameTextView.setTextColor(
- getCaptionAppNameTextColor(shouldUseLightCaptionViews));
- } else {
- throw new IllegalArgumentException("Unexpected layout resource id");
- }
- }
-
- private int getCaptionHandleBarColor(boolean shouldUseLightCaptionViews) {
- return shouldUseLightCaptionViews
- ? mContext.getColor(R.color.desktop_mode_caption_handle_bar_light)
- : mContext.getColor(R.color.desktop_mode_caption_handle_bar_dark);
- }
-
- private int getCaptionAppNameTextColor(boolean shouldUseLightCaptionViews) {
- return shouldUseLightCaptionViews
- ? mContext.getColor(R.color.desktop_mode_caption_app_name_light)
- : mContext.getColor(R.color.desktop_mode_caption_app_name_dark);
- }
-
- private int getCaptionCloseButtonColor(boolean shouldUseLightCaptionViews) {
- return shouldUseLightCaptionViews
- ? mContext.getColor(R.color.desktop_mode_caption_close_button_light)
- : mContext.getColor(R.color.desktop_mode_caption_close_button_dark);
- }
-
- private int getCaptionExpandButtonColor(boolean shouldUseLightCaptionViews) {
- return shouldUseLightCaptionViews
- ? mContext.getColor(R.color.desktop_mode_caption_expand_button_light)
- : mContext.getColor(R.color.desktop_mode_caption_expand_button_dark);
- }
-
private void closeDragResizeListener() {
if (mDragResizeListener == null) {
return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt
new file mode 100644
index 000000000000..95b5051cb81d
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt
@@ -0,0 +1,94 @@
+package com.android.wm.shell.windowdecor.viewholder
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.content.pm.PackageManager
+import android.content.res.ColorStateList
+import android.graphics.drawable.GradientDrawable
+import android.util.Log
+import android.view.View
+import android.widget.ImageButton
+import android.widget.ImageView
+import android.widget.TextView
+import com.android.wm.shell.R
+
+/**
+ * A desktop mode window decoration used when the window is floating (i.e. freeform). It hosts
+ * finer controls such as a close window button and an "app info" section to pull up additional
+ * controls.
+ */
+internal class DesktopModeAppControlsWindowDecorationViewHolder(
+ rootView: View,
+ onCaptionTouchListener: View.OnTouchListener,
+ onCaptionButtonClickListener: View.OnClickListener
+) : DesktopModeWindowDecorationViewHolder(rootView) {
+
+ private val captionView: View = rootView.findViewById(R.id.desktop_mode_caption)
+ private val captionHandle: View = rootView.findViewById(R.id.caption_handle)
+ private val openMenuButton: View = rootView.findViewById(R.id.open_menu_button)
+ private val closeWindowButton: ImageButton = rootView.findViewById(R.id.close_window)
+ private val expandMenuButton: ImageButton = rootView.findViewById(R.id.expand_menu_button)
+ private val appNameTextView: TextView = rootView.findViewById(R.id.application_name)
+ private val appIconImageView: ImageView = rootView.findViewById(R.id.application_icon)
+
+ init {
+ captionView.setOnTouchListener(onCaptionTouchListener)
+ captionHandle.setOnTouchListener(onCaptionTouchListener)
+ openMenuButton.setOnClickListener(onCaptionButtonClickListener)
+ closeWindowButton.setOnClickListener(onCaptionButtonClickListener)
+ }
+
+ override fun bindData(taskInfo: RunningTaskInfo) {
+ bindAppInfo(taskInfo)
+
+ val captionDrawable = captionView.background as GradientDrawable
+ captionDrawable.setColor(taskInfo.taskDescription.statusBarColor)
+
+ closeWindowButton.imageTintList = ColorStateList.valueOf(
+ getCaptionCloseButtonColor(taskInfo))
+ expandMenuButton.imageTintList = ColorStateList.valueOf(
+ getCaptionExpandButtonColor(taskInfo))
+ appNameTextView.setTextColor(getCaptionAppNameTextColor(taskInfo))
+ }
+
+ private fun bindAppInfo(taskInfo: RunningTaskInfo) {
+ val packageName: String = taskInfo.realActivity.packageName
+ val pm: PackageManager = context.applicationContext.packageManager
+ try {
+ // TODO(b/268363572): Use IconProvider or BaseIconCache to set drawable/name.
+ val applicationInfo = pm.getApplicationInfo(packageName,
+ PackageManager.ApplicationInfoFlags.of(0))
+ appNameTextView.text = pm.getApplicationLabel(applicationInfo)
+ appIconImageView.setImageDrawable(pm.getApplicationIcon(applicationInfo))
+ } catch (e: PackageManager.NameNotFoundException) {
+ Log.w(TAG, "Package not found: $packageName", e)
+ }
+ }
+
+ private fun getCaptionAppNameTextColor(taskInfo: RunningTaskInfo): Int {
+ return if (shouldUseLightCaptionColors(taskInfo)) {
+ context.getColor(R.color.desktop_mode_caption_app_name_light)
+ } else {
+ context.getColor(R.color.desktop_mode_caption_app_name_dark)
+ }
+ }
+
+ private fun getCaptionCloseButtonColor(taskInfo: RunningTaskInfo): Int {
+ return if (shouldUseLightCaptionColors(taskInfo)) {
+ context.getColor(R.color.desktop_mode_caption_close_button_light)
+ } else {
+ context.getColor(R.color.desktop_mode_caption_close_button_dark)
+ }
+ }
+
+ private fun getCaptionExpandButtonColor(taskInfo: RunningTaskInfo): Int {
+ return if (shouldUseLightCaptionColors(taskInfo)) {
+ context.getColor(R.color.desktop_mode_caption_expand_button_light)
+ } else {
+ context.getColor(R.color.desktop_mode_caption_expand_button_dark)
+ }
+ }
+
+ companion object {
+ private const val TAG = "DesktopModeAppControlsWindowDecorationViewHolder"
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeFocusedWindowDecorationViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeFocusedWindowDecorationViewHolder.kt
new file mode 100644
index 000000000000..47a12a0cb71c
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeFocusedWindowDecorationViewHolder.kt
@@ -0,0 +1,44 @@
+package com.android.wm.shell.windowdecor.viewholder
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.content.res.ColorStateList
+import android.graphics.drawable.GradientDrawable
+import android.view.View
+import android.widget.ImageButton
+import com.android.wm.shell.R
+
+/**
+ * A desktop mode window decoration used when the window is in full "focus" (i.e. fullscreen). It
+ * hosts a simple handle bar from which to initiate a drag motion to enter desktop mode.
+ */
+internal class DesktopModeFocusedWindowDecorationViewHolder(
+ rootView: View,
+ onCaptionTouchListener: View.OnTouchListener,
+ onCaptionButtonClickListener: View.OnClickListener
+) : DesktopModeWindowDecorationViewHolder(rootView) {
+
+ private val captionView: View = rootView.findViewById(R.id.desktop_mode_caption)
+ private val captionHandle: ImageButton = rootView.findViewById(R.id.caption_handle)
+
+ init {
+ captionView.setOnTouchListener(onCaptionTouchListener)
+ captionHandle.setOnTouchListener(onCaptionTouchListener)
+ captionHandle.setOnClickListener(onCaptionButtonClickListener)
+ }
+
+ override fun bindData(taskInfo: RunningTaskInfo) {
+ val captionColor = taskInfo.taskDescription.statusBarColor
+ val captionDrawable = captionView.background as GradientDrawable
+ captionDrawable.setColor(captionColor)
+
+ captionHandle.imageTintList = ColorStateList.valueOf(getCaptionHandleBarColor(taskInfo))
+ }
+
+ private fun getCaptionHandleBarColor(taskInfo: RunningTaskInfo): Int {
+ return if (shouldUseLightCaptionColors(taskInfo)) {
+ context.getColor(R.color.desktop_mode_caption_handle_bar_light)
+ } else {
+ context.getColor(R.color.desktop_mode_caption_handle_bar_dark)
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeWindowDecorationViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeWindowDecorationViewHolder.kt
new file mode 100644
index 000000000000..514ea52cb8ae
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeWindowDecorationViewHolder.kt
@@ -0,0 +1,28 @@
+package com.android.wm.shell.windowdecor.viewholder
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.content.Context
+import android.graphics.Color
+import android.view.View
+
+/**
+ * Encapsulates the root [View] of a window decoration and its children to facilitate looking up
+ * children (via findViewById) and updating to the latest data from [RunningTaskInfo].
+ */
+internal abstract class DesktopModeWindowDecorationViewHolder(rootView: View) {
+ val context: Context = rootView.context
+
+ /**
+ * A signal to the view holder that new data is available and that the views should be updated
+ * to reflect it.
+ */
+ abstract fun bindData(taskInfo: RunningTaskInfo)
+
+ /**
+ * Whether the caption items should use the 'light' color variant so that there's good contrast
+ * with the caption background color.
+ */
+ protected fun shouldUseLightCaptionColors(taskInfo: RunningTaskInfo): Boolean {
+ return Color.valueOf(taskInfo.taskDescription.statusBarColor).luminance() < 0.5
+ }
+}