Merge "Update caption handle menu to new spec." into tm-qpr-dev am: fd4db7662d

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21145636

Change-Id: I10fdc55c0141f67ad6499ebbb5b77f265b45ebd7
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Matt Sziklay
2023-02-10 03:01:04 +00:00
committed by Automerger Merge Worker
16 changed files with 408 additions and 77 deletions

View File

@@ -0,0 +1,30 @@
<?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 xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32.0dp"
android:height="32.0dp"
android:viewportWidth="32.0"
android:viewportHeight="32.0"
>
<group android:scaleX="0.5"
android:scaleY="0.5"
android:translateY="4.0">
<path
android:fillColor="#FFFF0000"
android:pathData="M12.45,38.35 L9.65,35.55 21.2,24 9.65,12.45 12.45,9.65 24,21.2 35.55,9.65 38.35,12.45 26.8,24 38.35,35.55 35.55,38.35 24,26.8Z"/>
</group>
</vector>

View File

@@ -0,0 +1,30 @@
<?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 xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24.0dp"
android:height="24.0dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
>
<group android:scaleX="1.25"
android:scaleY="1.75"
android:translateY="6.0">
<path
android:fillColor="@android:color/black"
android:pathData="M10.3937 6.93935L11.3337 5.99935L6.00033 0.666016L0.666992 5.99935L1.60699 6.93935L6.00033 2.55268"/>
</group>
</vector>

View File

@@ -0,0 +1,30 @@
<?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 xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32.0dp"
android:height="32.0dp"
android:viewportWidth="32.0"
android:viewportHeight="32.0"
>
<group android:scaleX="0.5"
android:scaleY="0.5"
android:translateY="4.0">
<path
android:fillColor="@android:color/black"
android:pathData="M10,38V28.35H13V35H19.65V38ZM10,19.65V10H19.65V13H13V19.65ZM28.35,38V35H35V28.35H38V38ZM35,19.65V13H28.35V10H38V19.65Z"/>
</group>
</vector>

View File

@@ -0,0 +1,30 @@
<?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 xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32.0dp"
android:height="32.0dp"
android:viewportWidth="32.0"
android:viewportHeight="32.0"
>
<group
android:translateX="4.0"
android:translateY="6.0">
<path
android:fillColor="@android:color/black"
android:pathData="M13.7021 12.5833L16.5676 15.5L15.426 16.7333L12.526 13.8333L10.4426 15.9167V10.5H15.9176L13.7021 12.5833ZM13.8343 3.83333H15.501V5.5H13.8343V3.83333ZM15.501 2.16667H13.8343V0.566667C14.751 0.566667 15.501 1.33333 15.501 2.16667ZM10.501 0.5H12.1676V2.16667H10.501V0.5ZM13.8343 7.16667H15.501V8.83333H13.8343V7.16667ZM5.50098 15.5H3.83431V13.8333H5.50098V15.5ZM2.16764 5.5H0.500977V3.83333H2.16764V5.5ZM2.16764 0.566667V2.16667H0.500977C0.500977 1.33333 1.33431 0.566667 2.16764 0.566667ZM2.16764 12.1667H0.500977V10.5H2.16764V12.1667ZM5.50098 2.16667H3.83431V0.5H5.50098V2.16667ZM8.83431 2.16667H7.16764V0.5H8.83431V2.16667ZM8.83431 15.5H7.16764V13.8333H8.83431V15.5ZM2.16764 8.83333H0.500977V7.16667H2.16764V8.83333ZM2.16764 15.5667C1.25098 15.5667 0.500977 14.6667 0.500977 13.8333H2.16764V15.5667Z"/>
</group>
</vector>

View File

@@ -17,9 +17,10 @@
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
android:viewportHeight="24"
android:tint="@color/decor_button_dark_color">
<group android:translateY="8.0">
<path
android:fillColor="@android:color/black" android:pathData="M3,5V3H21V5Z"/>
android:fillColor="@android:color/white" android:pathData="M3,5V3H21V5Z"/>
</group>
</vector>

View File

@@ -18,4 +18,5 @@
xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/white" />
<corners android:radius="20dp" />
<stroke android:width="1dp" android:color="#b3b3b3"/>
</shape>

View File

@@ -15,6 +15,8 @@
~ limitations under the License.
-->
<shape android:shape="rectangle"
android:tintMode="multiply"
android:tint="@color/decor_title_color"
xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/white" />
</shape>

View File

@@ -1,49 +1,129 @@
<?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.
-->
<!--
~ 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"
android:id="@+id/handle_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:background="@drawable/desktop_mode_decor_menu_background">
<Button
style="@style/CaptionButtonStyle"
android:id="@+id/fullscreen_button"
android:contentDescription="@string/fullscreen_text"
android:background="@drawable/caption_fullscreen_button"/>
<Button
style="@style/CaptionButtonStyle"
android:id="@+id/split_screen_button"
android:contentDescription="@string/split_screen_text"
android:background="@drawable/caption_split_screen_button"/>
<Button
style="@style/CaptionButtonStyle"
android:id="@+id/floating_button"
android:contentDescription="@string/float_button_text"
android:background="@drawable/caption_floating_button"/>
<Button
style="@style/CaptionButtonStyle"
android:id="@+id/desktop_button"
android:contentDescription="@string/desktop_text"
android:background="@drawable/caption_desktop_button"/>
<Button
style="@style/CaptionButtonStyle"
android:id="@+id/more_button"
android:contentDescription="@string/more_button_text"
android:background="@drawable/caption_more_button"/>
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/handle_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/desktop_mode_decor_menu_background"
android:elevation="@dimen/caption_menu_elevation"
android:divider="?android:attr/dividerHorizontal"
android:showDividers="middle"
android:dividerPadding="18dip">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/application_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_margin="12dp"
android:contentDescription="@string/app_icon_text"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"/>
<TextView
android:id="@+id/application_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@+id/application_icon"
android:layout_toStartOf="@+id/collapse_menu_button"
android:textColor="#FF000000"
android:layout_centerVertical="true"/>
<Button
android:id="@+id/collapse_menu_button"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="10dp"
android:contentDescription="@string/collapse_menu_text"
android:layout_alignParentEnd="true"
android:background="@drawable/caption_collapse_menu_button"
android:layout_centerVertical="true"/>
</RelativeLayout>
<LinearLayout
android:id="@+id/windowing_mode_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="0.5" />
<Button
style="@style/CaptionWindowingButtonStyle"
android:id="@+id/fullscreen_button"
android:contentDescription="@string/fullscreen_text"
android:background="@drawable/caption_fullscreen_button"/>
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<Button
style="@style/CaptionWindowingButtonStyle"
android:id="@+id/split_screen_button"
android:contentDescription="@string/split_screen_text"
android:background="@drawable/caption_split_screen_button"/>
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<Button
style="@style/CaptionWindowingButtonStyle"
android:id="@+id/floating_button"
android:contentDescription="@string/float_button_text"
android:background="@drawable/caption_floating_button"/>
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<Button
style="@style/CaptionWindowingButtonStyle"
android:id="@+id/desktop_button"
android:contentDescription="@string/desktop_text"
android:background="@drawable/caption_desktop_button"/>
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="0.5" />
</LinearLayout>
<LinearLayout
android:id="@+id/menu_buttons_misc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
style="@style/CaptionMenuButtonStyle"
android:id="@+id/screenshot_button"
android:contentDescription="@string/screenshot_text"
android:text="@string/screenshot_text"
android:drawableStart="@drawable/caption_screenshot_button"/>
<Button
style="@style/CaptionMenuButtonStyle"
android:id="@+id/select_button"
android:contentDescription="@string/select_text"
android:text="@string/select_text"
android:drawableStart="@drawable/caption_select_button"/>
<Button
style="@style/CaptionMenuButtonStyle"
android:id="@+id/close_button"
android:contentDescription="@string/close_text"
android:text="@string/close_text"
android:drawableStart="@drawable/caption_close_button"
android:textColor="#FFFF0000"/>
</LinearLayout>
</com.android.wm.shell.windowdecor.WindowDecorLinearLayout>

View File

@@ -21,10 +21,21 @@
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
android:id="@+id/caption_handle"
android:layout_width="128dp"
android:layout_height="32dp"
android:layout_margin="5dp"
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"/>
</com.android.wm.shell.windowdecor.WindowDecorLinearLayout>

View File

@@ -367,8 +367,12 @@
<!-- Width of buttons (32dp each) + padding (128dp total). -->
<dimen name="freeform_decor_caption_menu_width">256dp</dimen>
<dimen name="freeform_decor_caption_menu_height">250dp</dimen>
<dimen name="freeform_resize_handle">30dp</dimen>
<dimen name="freeform_resize_corner">44dp</dimen>
<dimen name="caption_menu_elevation">4dp</dimen>
</resources>

View File

@@ -225,6 +225,8 @@
<string name="back_button_text">Back</string>
<!-- Accessibility text for the caption handle [CHAR LIMIT=NONE] -->
<string name="handle_text">Handle</string>
<!-- Accessibility text for the handle menu app icon [CHAR LIMIT=NONE] -->
<string name="app_icon_text">App Icon</string>
<!-- Accessibility text for the handle fullscreen button [CHAR LIMIT=NONE] -->
<string name="fullscreen_text">Fullscreen</string>
<!-- Accessibility text for the handle desktop button [CHAR LIMIT=NONE] -->
@@ -235,4 +237,12 @@
<string name="more_button_text">More</string>
<!-- Accessibility text for the handle floating window button [CHAR LIMIT=NONE] -->
<string name="float_button_text">Float</string>
<!-- Accessibility text for the handle menu select button [CHAR LIMIT=NONE] -->
<string name="select_text">Select</string>
<!-- Accessibility text for the handle menu screenshot button [CHAR LIMIT=NONE] -->
<string name="screenshot_text">Screenshot</string>
<!-- Accessibility text for the handle menu close button [CHAR LIMIT=NONE] -->
<string name="close_text">Close</string>
<!-- Accessibility text for the handle menu close menu button [CHAR LIMIT=NONE] -->
<string name="collapse_menu_text">Close Menu</string>
</resources>

View File

@@ -37,6 +37,22 @@
<item name="android:padding">4dp</item>
</style>
<style name="CaptionWindowingButtonStyle">
<item name="android:layout_width">32dp</item>
<item name="android:layout_height">32dp</item>
<item name="android:padding">4dp</item>
<item name="android:layout_marginTop">5dp</item>
<item name="android:layout_marginBottom">5dp</item>
</style>
<style name="CaptionMenuButtonStyle" parent="@style/Widget.AppCompat.Button.Borderless">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">52dp</item>
<item name="android:layout_marginStart">10dp</item>
<item name="android:padding">4dp</item>
<item name="android:gravity">start|center_vertical</item>
</style>
<style name="DockedDividerBackground">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">@dimen/split_divider_bar_width</item>

View File

@@ -156,6 +156,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
}
decoration.relayout(taskInfo);
setupCaptionColor(taskInfo, decoration);
}
@Override
@@ -227,7 +228,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
public void onClick(View v) {
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
final int id = v.getId();
if (id == R.id.caption_handle) {
if (id == R.id.close_window || id == R.id.close_button) {
mTaskOperations.closeTask(mTaskToken);
} else if (id == R.id.back_button) {
mTaskOperations.injectBackKey();
} else if (id == R.id.caption_handle) {
decoration.createHandleMenu();
} else if (id == R.id.desktop_button) {
mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
@@ -238,6 +243,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mDesktopTasksController.ifPresent(c -> c.moveToFullscreen(mTaskId));
decoration.closeHandleMenu();
decoration.setButtonVisibility(false);
} else if (id == R.id.collapse_menu_button) {
decoration.closeHandleMenu();
}
}
@@ -508,6 +515,13 @@ 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()
@@ -546,6 +560,7 @@ 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

@@ -20,18 +20,25 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
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.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;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.ImageView;
import android.widget.TextView;
import android.window.WindowContainerTransaction;
import com.android.wm.shell.R;
@@ -48,6 +55,7 @@ import com.android.wm.shell.desktopmode.DesktopModeStatus;
* 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;
@@ -59,12 +67,14 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
private DragDetector mDragDetector;
private RelayoutParams mRelayoutParams = new RelayoutParams();
private final int mCaptionMenuWidthId = R.dimen.freeform_decor_caption_menu_width;
private final int mCaptionMenuHeightId = R.dimen.freeform_decor_caption_menu_height;
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 PointF mHandleMenuPosition = new PointF();
DesktopModeWindowDecoration(
Context context,
@@ -211,21 +221,46 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
final View fullscreen = menu.findViewById(R.id.fullscreen_button);
fullscreen.setOnClickListener(mOnCaptionButtonClickListener);
final View desktop = menu.findViewById(R.id.desktop_button);
desktop.setOnClickListener(mOnCaptionButtonClickListener);
if (DesktopModeStatus.isProto2Enabled()) {
desktop.setOnClickListener(mOnCaptionButtonClickListener);
} else if (DesktopModeStatus.isProto1Enabled()) {
desktop.setVisibility(View.GONE);
}
final View split = menu.findViewById(R.id.split_screen_button);
split.setOnClickListener(mOnCaptionButtonClickListener);
final View close = menu.findViewById(R.id.close_button);
close.setOnClickListener(mOnCaptionButtonClickListener);
final View collapse = menu.findViewById(R.id.collapse_menu_button);
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);
}
}
/**
* 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);
if (!visible) closeHandleMenu();
}
/**
@@ -244,8 +279,13 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
* Show or hide buttons
*/
void setButtonVisibility(boolean visible) {
final int visibility = visible ? View.VISIBLE : View.GONE;
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;
@@ -254,13 +294,33 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
final View handle = caption.findViewById(R.id.caption_handle);
final VectorDrawable handleBackground = (VectorDrawable) handle.getBackground();
handleBackground.setTintList(buttonTintColor);
caption.getBackground().setTint(visible ? Color.WHITE : Color.TRANSPARENT);
}
boolean isHandleMenuActive() {
return mHandleMenu != null;
}
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 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);
}
private void closeDragResizeListener() {
if (mDragResizeListener == null) {
return;
@@ -277,16 +337,21 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
final Resources resources = mDecorWindowContext.getResources();
final int captionWidth = mTaskInfo.getConfiguration()
.windowConfiguration.getBounds().width();
final int menuWidth = loadDimensionPixelSize(
resources, mCaptionMenuWidthId);
final int height = loadDimensionPixelSize(
resources, mRelayoutParams.mCaptionHeightId);
final int menuWidth = loadDimensionPixelSize(resources, mHandleMenuWidthId);
final int menuHeight = loadDimensionPixelSize(resources, mCaptionMenuHeightId);
// Elevation gives the appearance of a changed x/y coordinate; this is to fix that
int elevationOffset = 2 * loadDimensionPixelSize(resources,
R.dimen.caption_menu_elevation);
final int x = mRelayoutParams.mCaptionX + (captionWidth / 2) - (menuWidth / 2)
- mResult.mDecorContainerOffsetX;
final int y = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY;
- mResult.mDecorContainerOffsetX - elevationOffset;
final int y =
mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY - elevationOffset;
mHandleMenuPosition.set(x, y);
String namePrefix = "Caption Menu";
mHandleMenu = addWindow(R.layout.desktop_mode_decor_handle_menu, namePrefix, t, x, y,
menuWidth, height);
menuWidth, menuHeight, 2 * elevationOffset);
mSyncQueue.runInSync(transaction -> {
transaction.merge(t);
t.close();
@@ -315,10 +380,17 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
* @param ev the tapped point to compare against
*/
void closeHandleMenuIfNeeded(MotionEvent ev) {
if (isHandleMenuActive()) {
if (!checkEventInCaptionView(ev, R.id.desktop_mode_caption)) {
closeHandleMenu();
}
if (!isHandleMenuActive()) return;
// When this is called before the layout is fully inflated, width will be 0.
// Menu is not visible in this scenario, so skip the check if that is the case.
if (mHandleMenu.mWindowViewHost.getView().getWidth() == 0) return;
PointF inputPoint = offsetCaptionLocation(ev);
if (!pointInView(mHandleMenu.mWindowViewHost.getView(),
inputPoint.x - mHandleMenuPosition.x - mResult.mDecorContainerOffsetX,
inputPoint.y - mHandleMenuPosition.y - mResult.mDecorContainerOffsetY)) {
closeHandleMenu();
}
}
@@ -380,12 +452,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
final int menuX = mRelayoutParams.mCaptionX + (captionWidth / 2)
- (menu.getWidth() / 2);
final PointF inputPoint = new PointF(ev.getX() - menuX, ev.getY());
final View fullscreen = menu.findViewById(R.id.fullscreen_button);
if (clickIfPointInView(inputPoint, fullscreen)) return;
final View desktop = menu.findViewById(R.id.desktop_button);
if (clickIfPointInView(inputPoint, desktop)) return;
final View split = menu.findViewById(R.id.split_screen_button);
if (clickIfPointInView(inputPoint, split)) return;
final View collapse = menu.findViewById(R.id.collapse_menu_button);
if (clickIfPointInView(inputPoint, collapse)) return;
}
}

View File

@@ -391,10 +391,11 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
* @param yPos y position of new window
* @param width width of new window
* @param height height of new window
* @param cropPadding padding to add to window crop to ensure shadows display properly
* @return
*/
AdditionalWindow addWindow(int layoutId, String namePrefix,
SurfaceControl.Transaction t, int xPos, int yPos, int width, int height) {
AdditionalWindow addWindow(int layoutId, String namePrefix, SurfaceControl.Transaction t,
int xPos, int yPos, int width, int height, int cropPadding) {
final SurfaceControl.Builder builder = mSurfaceControlBuilderSupplier.get();
SurfaceControl windowSurfaceControl = builder
.setName(namePrefix + " of Task=" + mTaskInfo.taskId)
@@ -405,7 +406,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
t.setPosition(
windowSurfaceControl, xPos, yPos)
.setWindowCrop(windowSurfaceControl, width, height)
.setWindowCrop(windowSurfaceControl, width + cropPadding, height + cropPadding)
.show(windowSurfaceControl);
final WindowManager.LayoutParams lp =
new WindowManager.LayoutParams(width, height,
@@ -426,6 +427,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
RunningTaskInfo mRunningTaskInfo;
int mLayoutResId;
int mCaptionHeightId;
int mCaptionWidthId;
int mShadowRadiusId;
int mOutsetTopId;
@@ -451,6 +453,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
void reset() {
mLayoutResId = Resources.ID_NULL;
mCaptionHeightId = Resources.ID_NULL;
mCaptionWidthId = Resources.ID_NULL;
mShadowRadiusId = Resources.ID_NULL;
mOutsetTopId = Resources.ID_NULL;

View File

@@ -431,7 +431,7 @@ public class WindowDecorationTests extends ShellTestCase {
verify(additionalWindowSurfaceBuilder).setParent(decorContainerSurface);
verify(additionalWindowSurfaceBuilder).build();
verify(mMockSurfaceControlAddWindowT).setPosition(additionalWindowSurface, 20, 40);
verify(mMockSurfaceControlAddWindowT).setWindowCrop(additionalWindowSurface, 432, 64);
verify(mMockSurfaceControlAddWindowT).setWindowCrop(additionalWindowSurface, 442, 74);
verify(mMockSurfaceControlAddWindowT).show(additionalWindowSurface);
verify(mMockSurfaceControlViewHostFactory, Mockito.times(2))
.create(any(), eq(defaultDisplay), any());
@@ -565,7 +565,7 @@ public class WindowDecorationTests extends ShellTestCase {
mMockSurfaceControlAddWindowT,
x - mRelayoutResult.mDecorContainerOffsetX,
y - mRelayoutResult.mDecorContainerOffsetY,
width, height);
width, height, 10);
return additionalWindow;
}
}