Update desktop mode caption bar to newest spec

Updates the caption bar layout in proto1/proto2 to a new model with a
close button and an app info view group. Also applies a small
refactor so that ALL views are updated only from relayout using the
latest task state instead of allowing certain views to be updated
independently (such as caption/color from onTaskInfoChange or button
clicks), which led to some synchronization issues leading to visual
errors.

Visual changes:
1. In proto 1 / proto 2 (desktop mode), the caption now has a close
button and the handle bar was replaced with a left-aligned view group
which contains the app icon, app name and an expand button which when
clicked opens the handle menu. The middle section of the caption bar
(between the app info and the close button) is now what allows
dragging and moving the task.
2. In proto2, the handle menu is aligned to the left when in
desktop mode. It continues to be centered when in fullscreen
3. Fixes issue where the app handle was sometimes invisible in proto2
on fullscreen tasks.
4. In proto1, the caption handle color was (sometimes) set based on
whether desktop mode was active (to dark or light). This conflicted
with other logic that sets it based on luminocity of the status bar
color to provide contrast. This CL removes the logic based on desktop
mode status since it didn't really make sense considering the whole
caption is invisible when desktop mode is inactive.
5. In proto1, the caption visibility was set based on the task focus
state. It is now always visible to match proto2 (desktop) behavior.

Non-visual changes:
1. Split the window decoration layout into two xml files (one for
each possible 'type' of caption): FOCUSED (used by proto1 and proto 2
when in fullscreen mode) and APP_CONTROLS (used by proto2 when in
desktop). This simplifies the visibility/color updates
that #relayout deals with. Instead of a single layout containing all
possible views of the caption and having to hide and show some
depending on which caption type was "active" at the time, the split
layouts now contain only the views that are relevant to that type,
so #relayout can check the type of caption and apply updates to only
the views that are actually affected by the current state.

Bug: 269618335
Bug: 270393915
Test: Enter desktop mode in proto2 and see new spec; Switch between
modes in proto1 and make sure the new spec is visible in desktop
mode only.

Change-Id: I28b8f2668d0ed6ddd4c71b16c44533c051a01bee
This commit is contained in:
Jorge Gil
2023-03-15 00:18:18 +00:00
parent 50ed6f3e19
commit 2628c45e6b
9 changed files with 255 additions and 142 deletions

View File

@@ -14,13 +14,12 @@
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="@color/decor_button_dark_color">
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group android:translateY="8.0">
<path
android:fillColor="@android:color/white" android:pathData="M3,5V3H21V5Z"/>
android:fillColor="@android:color/black" android:pathData="M3,5V3H21V5Z"/>
</group>
</vector>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 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
-->
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/black" android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"/>
</vector>

View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2022 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.
-->
<com.android.wm.shell.windowdecor.WindowDecorLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/desktop_mode_caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:background="@drawable/desktop_mode_decor_title">
<LinearLayout
android:id="@+id/open_menu_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
android:clickable="true"
android:focusable="true"
android:paddingStart="8dp"
android:background="?android:selectableItemBackgroundBorderless">
<ImageView
android:id="@+id/application_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_margin="4dp"
android:layout_gravity="center_vertical"
android:contentDescription="@string/app_icon_text" />
<TextView
android:id="@+id/application_name"
android:layout_width="0dp"
android:layout_height="match_parent"
android:minWidth="80dp"
android:textColor="@color/desktop_mode_caption_app_name_dark"
android:textSize="14sp"
android:textFontWeight="500"
android:gravity="center_vertical"
android:layout_weight="1"
android:paddingStart="4dp"
android:paddingEnd="4dp"
tools:text="Gmail"/>
<ImageButton
android:id="@+id/expand_menu_button"
android:layout_width="32dp"
android:layout_height="32dp"
android:padding="4dp"
android:contentDescription="@string/collapse_menu_text"
android:src="@drawable/ic_baseline_expand_more_24"
android:tint="@color/desktop_mode_caption_expand_button_dark"
android:background="@null"
android:scaleType="fitCenter"
android:clickable="false"
android:focusable="false"
android:layout_gravity="center_vertical"/>
</LinearLayout>
<View
android:id="@+id/caption_handle"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_weight="1"/>
<ImageButton
android:id="@+id/close_window"
android:layout_width="40dp"
android:layout_height="40dp"
android:padding="4dp"
android:layout_marginEnd="8dp"
android:contentDescription="@string/close_button_text"
android:src="@drawable/decor_close_button_dark"
android:scaleType="fitCenter"
android:gravity="end"
android:background="?android:selectableItemBackgroundBorderless"
android:tint="@color/desktop_mode_caption_close_button_dark"/>
</com.android.wm.shell.windowdecor.WindowDecorLinearLayout>

View File

@@ -50,7 +50,7 @@
android:layout_marginEnd="10dp"
android:contentDescription="@string/collapse_menu_text"
android:layout_alignParentEnd="true"
android:background="@drawable/caption_collapse_menu_button"
android:background="@drawable/ic_baseline_expand_more_24"
android:layout_centerVertical="true"/>
</RelativeLayout>
<LinearLayout

View File

@@ -16,26 +16,21 @@
-->
<com.android.wm.shell.windowdecor.WindowDecorLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/desktop_mode_caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:background="@drawable/desktop_mode_decor_title">
<Button
style="@style/CaptionButtonStyle"
android:id="@+id/back_button"
android:contentDescription="@string/back_button_text"
android:background="@drawable/decor_back_button_dark"/>
<Button
<ImageButton
android:id="@+id/caption_handle"
android:layout_width="128dp"
android:layout_height="32dp"
android:layout_margin="5dp"
android:layout_height="42dp"
android:contentDescription="@string/handle_text"
android:background="@drawable/decor_handle_dark"/>
<Button
style="@style/CaptionButtonStyle"
android:id="@+id/close_window"
android:contentDescription="@string/close_button_text"
android:background="@drawable/decor_close_button_dark"/>
android:src="@drawable/decor_handle_dark"
tools:tint="@color/desktop_mode_caption_handle_bar_dark"
android:scaleType="fitXY"
android:background="?android:selectableItemBackground"/>
</com.android.wm.shell.windowdecor.WindowDecorLinearLayout>

View File

@@ -54,4 +54,14 @@
<color name="splash_screen_bg_light">#FFFFFF</color>
<color name="splash_screen_bg_dark">#000000</color>
<color name="splash_window_background_default">@color/splash_screen_bg_light</color>
<!-- Desktop Mode -->
<color name="desktop_mode_caption_handle_bar_light">#EFF1F2</color>
<color name="desktop_mode_caption_handle_bar_dark">#1C1C17</color>
<color name="desktop_mode_caption_expand_button_light">#EFF1F2</color>
<color name="desktop_mode_caption_expand_button_dark">#48473A</color>
<color name="desktop_mode_caption_close_button_light">#EFF1F2</color>
<color name="desktop_mode_caption_close_button_dark">#1C1C17</color>
<color name="desktop_mode_caption_app_name_light">#EFF1F2</color>
<color name="desktop_mode_caption_app_name_dark">#1C1C17</color>
</resources>

View File

@@ -166,7 +166,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
}
decoration.relayout(taskInfo);
setupCaptionColor(taskInfo, decoration);
}
@Override
@@ -252,7 +251,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
}
} else if (id == R.id.back_button) {
mTaskOperations.injectBackKey();
} else if (id == R.id.caption_handle) {
} else if (id == R.id.caption_handle || id == R.id.open_menu_button) {
decoration.createHandleMenu();
} else if (id == R.id.desktop_button) {
mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
@@ -262,7 +261,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(false));
mDesktopTasksController.ifPresent(c -> c.moveToFullscreen(mTaskId));
decoration.closeHandleMenu();
decoration.setButtonVisibility(false);
} else if (id == R.id.collapse_menu_button) {
decoration.closeHandleMenu();
}
@@ -556,13 +554,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
}
}
private void setupCaptionColor(RunningTaskInfo taskInfo,
DesktopModeWindowDecoration decoration) {
if (taskInfo == null || taskInfo.taskDescription == null) return;
final int statusBarColor = taskInfo.taskDescription.getStatusBarColor();
decoration.setCaptionColor(statusBarColor);
}
private boolean shouldShowWindowDecor(RunningTaskInfo taskInfo) {
if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) return true;
return DesktopModeStatus.isProto2Enabled()
@@ -602,7 +593,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
windowDecoration.setDragPositioningCallback(taskPositioner);
windowDecoration.setDragDetector(touchEventListener.mDragDetector);
windowDecoration.relayout(taskInfo, startT, finishT);
setupCaptionColor(taskInfo, windowDecoration);
incrementEventReceiverTasks(taskInfo.displayId);
}

View File

@@ -28,9 +28,7 @@ import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.VectorDrawable;
import android.os.Handler;
import android.util.Log;
import android.view.Choreographer;
@@ -38,6 +36,7 @@ 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;
@@ -51,13 +50,13 @@ import com.android.wm.shell.desktopmode.DesktopTasksController;
/**
* Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with
* {@link DesktopModeWindowDecorViewModel}. The caption bar contains a handle, back button, and
* close button.
* {@link DesktopModeWindowDecorViewModel}.
*
* The shadow's thickness is 20dp when the window is in focus and 5dp when the window isn't.
*/
public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLinearLayout> {
private static final String TAG = "DesktopModeWindowDecoration";
private final Handler mHandler;
private final Choreographer mChoreographer;
private final SyncTransactionQueue mSyncQueue;
@@ -73,7 +72,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
private final WindowDecoration.RelayoutResult<WindowDecorLinearLayout> mResult =
new WindowDecoration.RelayoutResult<>();
private boolean mDesktopActive;
private AdditionalWindow mHandleMenu;
private final int mHandleMenuWidthId = R.dimen.freeform_decor_caption_menu_width;
private final int mHandleMenuShadowRadiusId = R.dimen.caption_menu_shadow_radius;
@@ -94,7 +92,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mHandler = handler;
mChoreographer = choreographer;
mSyncQueue = syncQueue;
mDesktopActive = DesktopModeStatus.isActive(mContext);
}
@Override
@@ -152,9 +149,11 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
final int outsetRightId = R.dimen.freeform_resize_handle;
final int outsetBottomId = R.dimen.freeform_resize_handle;
final int windowDecorLayoutId = getDesktopModeWindowDecorLayoutId(
taskInfo.getWindowingMode());
mRelayoutParams.reset();
mRelayoutParams.mRunningTaskInfo = taskInfo;
mRelayoutParams.mLayoutResId = R.layout.desktop_mode_window_decor;
mRelayoutParams.mLayoutResId = windowDecorLayoutId;
mRelayoutParams.mCaptionHeightId = R.dimen.freeform_decor_caption_height;
mRelayoutParams.mShadowRadiusId = shadowRadiusID;
if (isDragResizeable) {
@@ -175,21 +174,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
setupRootView();
}
// If this task is not focused, do not show caption.
setCaptionVisibility(mTaskInfo.isFocused);
if (mTaskInfo.isFocused) {
if (DesktopModeStatus.isProto2Enabled()) {
updateButtonVisibility();
} else if (DesktopModeStatus.isProto1Enabled()) {
// Only handle should show if Desktop Mode is inactive.
boolean desktopCurrentStatus = DesktopModeStatus.isActive(mContext);
if (mDesktopActive != desktopCurrentStatus) {
mDesktopActive = desktopCurrentStatus;
setButtonVisibility(mDesktopActive);
}
}
}
updateAppInfo();
setCaptionColor(taskInfo.taskDescription.getStatusBarColor());
if (!isDragResizeable) {
closeDragResizeListener();
@@ -227,14 +213,17 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
caption.setOnTouchListener(mOnCaptionTouchListener);
final View handle = caption.findViewById(R.id.caption_handle);
handle.setOnTouchListener(mOnCaptionTouchListener);
handle.setOnClickListener(mOnCaptionButtonClickListener);
if (DesktopModeStatus.isProto1Enabled()) {
final View back = caption.findViewById(R.id.back_button);
back.setOnClickListener(mOnCaptionButtonClickListener);
final View close = caption.findViewById(R.id.close_window);
close.setOnClickListener(mOnCaptionButtonClickListener);
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");
}
updateButtonVisibility();
}
private void setupHandleMenu() {
@@ -255,73 +244,41 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
collapse.setOnClickListener(mOnCaptionButtonClickListener);
menu.setOnTouchListener(mOnCaptionTouchListener);
String packageName = mTaskInfo.baseActivity.getPackageName();
PackageManager pm = mContext.getApplicationContext().getPackageManager();
// TODO(b/268363572): Use IconProvider or BaseIconCache to set drawable/name.
try {
ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName,
PackageManager.ApplicationInfoFlags.of(0));
final ImageView appIcon = menu.findViewById(R.id.application_icon);
appIcon.setImageDrawable(pm.getApplicationIcon(applicationInfo));
final TextView appName = menu.findViewById(R.id.application_name);
appName.setText(pm.getApplicationLabel(applicationInfo));
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Package not found: " + packageName, e);
final ImageView appIcon = menu.findViewById(R.id.application_icon);
final TextView appName = menu.findViewById(R.id.application_name);
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;
}
}
/**
* Sets caption visibility based on task focus.
* Note: Only applicable to Desktop Proto 1; Proto 2 only closes handle menu on focus loss
* @param visible whether or not the caption should be visible
*/
private void setCaptionVisibility(boolean visible) {
if (!visible) closeHandleMenu();
if (!DesktopModeStatus.isProto1Enabled()) return;
final int v = visible ? View.VISIBLE : View.GONE;
final View captionView = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
captionView.setVisibility(v);
}
/**
* Sets the visibility of buttons and color of caption based on desktop mode status
*/
void updateButtonVisibility() {
if (DesktopModeStatus.isProto2Enabled()) {
setButtonVisibility(mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM);
} else if (DesktopModeStatus.isProto1Enabled()) {
mDesktopActive = DesktopModeStatus.isActive(mContext);
setButtonVisibility(mDesktopActive);
}
}
/**
* Show or hide buttons
*/
void setButtonVisibility(boolean visible) {
final int visibility = visible && DesktopModeStatus.isProto1Enabled()
? View.VISIBLE : View.GONE;
final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
final View back = caption.findViewById(R.id.back_button);
final View close = caption.findViewById(R.id.close_window);
back.setVisibility(visibility);
close.setVisibility(visibility);
final int buttonTintColorRes =
mDesktopActive ? R.color.decor_button_dark_color
: R.color.decor_button_light_color;
final ColorStateList buttonTintColor =
caption.getResources().getColorStateList(buttonTintColorRes, null /* theme */);
final View handle = caption.findViewById(R.id.caption_handle);
final VectorDrawable handleBackground = (VectorDrawable) handle.getBackground();
handleBackground.setTintList(buttonTintColor);
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;
}
void setCaptionColor(int captionColor) {
private void loadAppInfo(TextView appNameTextView, ImageView appIconImageView) {
String packageName = mTaskInfo.realActivity.getPackageName();
PackageManager pm = mContext.getApplicationContext().getPackageManager();
try {
// TODO(b/268363572): Use IconProvider or BaseIconCache to set drawable/name.
ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName,
PackageManager.ApplicationInfoFlags.of(0));
appNameTextView.setText(pm.getApplicationLabel(applicationInfo));
appIconImageView.setImageDrawable(pm.getApplicationIcon(applicationInfo));
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Package not found: " + packageName, e);
}
}
private void setCaptionColor(int captionColor) {
if (mResult.mRootView == null) {
return;
}
@@ -330,26 +287,52 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
final GradientDrawable captionDrawable = (GradientDrawable) caption.getBackground();
captionDrawable.setColor(captionColor);
final int buttonTintColorRes =
Color.valueOf(captionColor).luminance() < 0.5
? R.color.decor_button_light_color
: R.color.decor_button_dark_color;
final ColorStateList buttonTintColor =
caption.getResources().getColorStateList(buttonTintColorRes, null /* theme */);
final View handle = caption.findViewById(R.id.caption_handle);
final Drawable handleBackground = handle.getBackground();
handleBackground.setTintList(buttonTintColor);
if (DesktopModeStatus.isProto1Enabled()) {
final View back = caption.findViewById(R.id.back_button);
final Drawable backBackground = back.getBackground();
backBackground.setTintList(buttonTintColor);
final View close = caption.findViewById(R.id.close_window);
final Drawable closeBackground = close.getBackground();
closeBackground.setTintList(buttonTintColor);
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;
@@ -371,9 +354,18 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
final int shadowRadius = loadDimensionPixelSize(resources, mHandleMenuShadowRadiusId);
final int cornerRadius = loadDimensionPixelSize(resources, mHandleMenuCornerRadiusId);
final int x = mRelayoutParams.mCaptionX + (captionWidth / 2) - (menuWidth / 2)
- mResult.mDecorContainerOffsetX;
final int y = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY;
final int x, y;
if (mRelayoutParams.mLayoutResId
== R.layout.desktop_mode_app_controls_window_decor) {
// Align the handle menu to the left of the caption.
x = mRelayoutParams.mCaptionX - mResult.mDecorContainerOffsetX;
y = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY;
} else {
// Position the handle menu at the center of the caption.
x = mRelayoutParams.mCaptionX + (captionWidth / 2) - (menuWidth / 2)
- mResult.mDecorContainerOffsetX;
y = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY;
}
mHandleMenuPosition.set(x, y);
String namePrefix = "Caption Menu";
mHandleMenu = addWindow(R.layout.desktop_mode_decor_handle_menu, namePrefix, t, x, y,
@@ -503,6 +495,15 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
super.close();
}
private int getDesktopModeWindowDecorLayoutId(int windowingMode) {
if (DesktopModeStatus.isProto1Enabled()) {
return R.layout.desktop_mode_app_controls_window_decor;
}
return windowingMode == WINDOWING_MODE_FREEFORM
? R.layout.desktop_mode_app_controls_window_decor
: R.layout.desktop_mode_focused_window_decor;
}
static class Factory {
DesktopModeWindowDecoration create(

View File

@@ -84,6 +84,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
};
RunningTaskInfo mTaskInfo;
int mLayoutResId;
final SurfaceControl mTaskSurface;
Display mDisplay;
@@ -162,6 +163,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
if (params.mRunningTaskInfo != null) {
mTaskInfo = params.mRunningTaskInfo;
}
final int oldLayoutResId = mLayoutResId;
mLayoutResId = params.mLayoutResId;
if (!mTaskInfo.isVisible) {
releaseViews();
@@ -178,7 +181,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
final Configuration taskConfig = getConfigurationWithOverrides(mTaskInfo);
if (oldTaskConfig.densityDpi != taskConfig.densityDpi
|| mDisplay == null
|| mDisplay.getDisplayId() != mTaskInfo.displayId) {
|| mDisplay.getDisplayId() != mTaskInfo.displayId
|| oldLayoutResId != mLayoutResId) {
releaseViews();
if (!obtainDisplayOrRegisterListener()) {