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:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
Reference in New Issue
Block a user