summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/WindowManager/Shell/res/layout/desktop_mode_focused_window_decor.xml5
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimation.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java19
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleImageButton.kt79
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuImageButton.kt2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java20
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java13
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java26
-rw-r--r--libs/hwui/renderthread/EglManager.cpp19
22 files changed, 257 insertions, 43 deletions
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_focused_window_decor.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_focused_window_decor.xml
index ef7478c04dda..c0ff1922edc8 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_focused_window_decor.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_focused_window_decor.xml
@@ -22,14 +22,15 @@
android:layout_height="wrap_content"
android:gravity="center_horizontal">
- <ImageButton
+ <com.android.wm.shell.windowdecor.HandleImageButton
android:id="@+id/caption_handle"
android:layout_width="@dimen/desktop_mode_fullscreen_decor_caption_width"
android:layout_height="@dimen/desktop_mode_fullscreen_decor_caption_height"
android:paddingVertical="16dp"
+ android:paddingHorizontal="10dp"
android:contentDescription="@string/handle_text"
android:src="@drawable/decor_handle_dark"
tools:tint="@color/desktop_mode_caption_handle_bar_dark"
android:scaleType="fitXY"
- android:background="?android:selectableItemBackground"/>
+ android:background="@android:color/transparent"/>
</com.android.wm.shell.windowdecor.WindowDecorLinearLayout> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 39dd4d3af98d..6d5bf6233366 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -423,8 +423,9 @@
<!-- Height of desktop mode caption for fullscreen tasks. -->
<dimen name="desktop_mode_fullscreen_decor_caption_height">36dp</dimen>
- <!-- Width of desktop mode caption for fullscreen tasks. -->
- <dimen name="desktop_mode_fullscreen_decor_caption_width">128dp</dimen>
+ <!-- Width of desktop mode caption for fullscreen tasks.
+ 80 dp for handle + 20 dp for room to grow on the sides when hovered. -->
+ <dimen name="desktop_mode_fullscreen_decor_caption_width">100dp</dimen>
<!-- Required empty space to be visible for partially offscreen tasks. -->
<dimen name="freeform_required_visible_empty_space_in_header">48dp</dimen>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index 97bf8f7bf459..73b2656d596a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -32,6 +32,7 @@ import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.res.Configuration;
import android.database.ContentObserver;
import android.hardware.input.InputManager;
import android.net.Uri;
@@ -71,6 +72,7 @@ import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
import com.android.wm.shell.shared.annotations.ShellMainThread;
+import com.android.wm.shell.sysui.ConfigurationChangeListener;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
@@ -81,7 +83,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
/**
* Controls the window animation run when a user initiates a back gesture.
*/
-public class BackAnimationController implements RemoteCallable<BackAnimationController> {
+public class BackAnimationController implements RemoteCallable<BackAnimationController>,
+ ConfigurationChangeListener {
private static final String TAG = "ShellBackPreview";
private static final int SETTING_VALUE_OFF = 0;
private static final int SETTING_VALUE_ON = 1;
@@ -248,6 +251,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
mShellController.addExternalInterface(KEY_EXTRA_SHELL_BACK_ANIMATION,
this::createExternalInterface, this);
mShellCommandHandler.addDumpCallback(this::dump, this);
+ mShellController.addConfigurationChangeListener(this);
}
private void setupAnimationDeveloperSettingsObserver(
@@ -297,6 +301,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
private final BackAnimationImpl mBackAnimation = new BackAnimationImpl();
@Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ mShellBackAnimationRegistry.onConfigurationChanged(newConfig);
+ }
+
+ @Override
public Context getContext() {
return mContext;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
index c6d46207b119..112ed0941122 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
@@ -68,7 +68,7 @@ class CrossActivityBackAnimation @Inject constructor(
private val backAnimRect = Rect()
- private val cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)
+ private var cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)
private val backAnimationRunner = BackAnimationRunner(
Callback(), Runner(), context, Cuj.CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY
@@ -94,6 +94,10 @@ class CrossActivityBackAnimation @Inject constructor(
private var scrimLayer: SurfaceControl? = null
private var maxScrimAlpha: Float = 0f
+ override fun onConfigurationChanged(newConfiguration: Configuration) {
+ cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)
+ }
+
override fun getRunner() = backAnimationRunner
private fun startBackAnimation(backMotionEvent: BackMotionEvent) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
index 987001d66219..c34f30df33a2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
@@ -29,6 +29,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.Rect;
@@ -80,7 +81,7 @@ public class CrossTaskBackAnimation extends ShellBackAnimation {
private static final int POST_ANIMATION_DURATION_MS = 500;
private final Rect mStartTaskRect = new Rect();
- private final float mCornerRadius;
+ private float mCornerRadius;
// The closing window properties.
private final Rect mClosingStartRect = new Rect();
@@ -120,6 +121,11 @@ public class CrossTaskBackAnimation extends ShellBackAnimation {
mContext = context;
}
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ mCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(mContext);
+ }
+
private static float mapRange(float value, float min, float max) {
return min + (value * (max - min));
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java
index e33aa7568d09..838dab43d6e8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java
@@ -29,6 +29,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.RemoteException;
@@ -63,7 +64,7 @@ import javax.inject.Inject;
public class CustomizeActivityAnimation extends ShellBackAnimation {
private final BackProgressAnimator mProgressAnimator = new BackProgressAnimator();
private final BackAnimationRunner mBackAnimationRunner;
- private final float mCornerRadius;
+ private float mCornerRadius;
private final SurfaceControl.Transaction mTransaction;
private final BackAnimationBackground mBackground;
private RemoteAnimationTarget mEnteringTarget;
@@ -88,6 +89,7 @@ public class CustomizeActivityAnimation extends ShellBackAnimation {
final Transformation mTransformation = new Transformation();
private final Choreographer mChoreographer;
+ private final Context mContext;
@Inject
public CustomizeActivityAnimation(Context context, BackAnimationBackground background) {
@@ -108,6 +110,12 @@ public class CustomizeActivityAnimation extends ShellBackAnimation {
.setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY));
mTransaction = transaction == null ? new SurfaceControl.Transaction() : transaction;
mChoreographer = choreographer != null ? choreographer : Choreographer.getInstance();
+ mContext = context;
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ mCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(mContext);
}
private float getLatestProgress() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimation.java
index dc659197848e..8a0daaa72e24 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimation.java
@@ -16,6 +16,7 @@
package com.android.wm.shell.back;
+import android.content.res.Configuration;
import android.window.BackNavigationInfo;
import javax.inject.Qualifier;
@@ -48,4 +49,8 @@ public abstract class ShellBackAnimation {
public boolean prepareNextAnimation(BackNavigationInfo.CustomAnimationInfo animationInfo) {
return false;
}
+
+ void onConfigurationChanged(Configuration newConfig) {
+
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java
index 26d20972c751..00daddc13346 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java
@@ -18,6 +18,7 @@ package com.android.wm.shell.back;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.res.Configuration;
import android.util.Log;
import android.util.SparseArray;
import android.window.BackNavigationInfo;
@@ -29,6 +30,7 @@ public class ShellBackAnimationRegistry {
private final SparseArray<BackAnimationRunner> mAnimationDefinition = new SparseArray<>();
private final ShellBackAnimation mDefaultCrossActivityAnimation;
private final ShellBackAnimation mCustomizeActivityAnimation;
+ private final ShellBackAnimation mCrossTaskAnimation;
public ShellBackAnimationRegistry(
@ShellBackAnimation.CrossActivity @Nullable ShellBackAnimation crossActivityAnimation,
@@ -57,6 +59,7 @@ public class ShellBackAnimationRegistry {
mDefaultCrossActivityAnimation = crossActivityAnimation;
mCustomizeActivityAnimation = customizeActivityAnimation;
+ mCrossTaskAnimation = crossTaskAnimation;
// TODO(b/236760237): register dialog close animation when it's completed.
}
@@ -125,6 +128,12 @@ public class ShellBackAnimationRegistry {
BackNavigationInfo.TYPE_CROSS_ACTIVITY, mDefaultCrossActivityAnimation.getRunner());
}
+ void onConfigurationChanged(Configuration newConfig) {
+ mCustomizeActivityAnimation.onConfigurationChanged(newConfig);
+ mDefaultCrossActivityAnimation.onConfigurationChanged(newConfig);
+ mCrossTaskAnimation.onConfigurationChanged(newConfig);
+ }
+
BackAnimationRunner getAnimationRunnerAndInit(BackNavigationInfo backNavigationInfo) {
int type = backNavigationInfo.getType();
// Initiate customized cross-activity animation, or fall back to cross activity animation
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 313d0d24b459..d2958779c0d4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -455,8 +455,7 @@ public class BubbleController implements ConfigurationChangeListener,
ProtoLog.d(WM_SHELL_BUBBLES,
"onActivityRestartAttempt - taskId=%d selecting matching bubble=%s",
task.taskId, b.getKey());
- mBubbleData.setSelectedBubble(b);
- mBubbleData.setExpanded(true);
+ mBubbleData.setSelectedBubbleAndExpandStack(b);
return;
}
}
@@ -593,13 +592,6 @@ public class BubbleController implements ConfigurationChangeListener,
}
}
- private void openBubbleOverflow() {
- ensureBubbleViewsAndWindowCreated();
- mBubbleData.setShowingOverflow(true);
- mBubbleData.setSelectedBubble(mBubbleData.getOverflow());
- mBubbleData.setExpanded(true);
- }
-
/**
* Called when the status bar has become visible or invisible (either permanently or
* temporarily).
@@ -1247,8 +1239,7 @@ public class BubbleController implements ConfigurationChangeListener,
}
if (mBubbleData.hasBubbleInStackWithKey(b.getKey())) {
// already in the stack
- mBubbleData.setSelectedBubble(b);
- mBubbleData.setExpanded(true);
+ mBubbleData.setSelectedBubbleAndExpandStack(b);
} else if (mBubbleData.hasOverflowBubbleWithKey(b.getKey())) {
// promote it out of the overflow
promoteBubbleFromOverflow(b);
@@ -1273,8 +1264,7 @@ public class BubbleController implements ConfigurationChangeListener,
String key = entry.getKey();
Bubble bubble = mBubbleData.getBubbleInStackWithKey(key);
if (bubble != null) {
- mBubbleData.setSelectedBubble(bubble);
- mBubbleData.setExpanded(true);
+ mBubbleData.setSelectedBubbleAndExpandStack(bubble);
} else {
bubble = mBubbleData.getOverflowBubbleWithKey(key);
if (bubble != null) {
@@ -1367,8 +1357,7 @@ public class BubbleController implements ConfigurationChangeListener,
} else {
// App bubble is not selected, select it & expand
Log.i(TAG, " showOrHideAppBubble, expand and select existing app bubble");
- mBubbleData.setSelectedBubble(existingAppBubble);
- mBubbleData.setExpanded(true);
+ mBubbleData.setSelectedBubbleAndExpandStack(existingAppBubble);
}
} else {
// Check if it exists in the overflow
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index 61f0ed22b537..ae3d0c559014 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -365,6 +365,19 @@ public class BubbleData {
mSelectedBubble = bubble;
}
+ /**
+ * Sets the selected bubble and expands it.
+ *
+ * <p>This dispatches a single state update for both changes and should be used instead of
+ * calling {@link #setSelectedBubble(BubbleViewProvider)} followed by
+ * {@link #setExpanded(boolean)} immediately after, which will generate 2 separate updates.
+ */
+ public void setSelectedBubbleAndExpandStack(BubbleViewProvider bubble) {
+ setSelectedBubbleInternal(bubble);
+ setExpandedInternal(true);
+ dispatchPendingChanges();
+ }
+
public void setSelectedBubble(BubbleViewProvider bubble) {
setSelectedBubbleInternal(bubble);
dispatchPendingChanges();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index e210ea731f7a..58942ec92a71 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -1354,6 +1354,13 @@ class DesktopTasksController(
"setTaskListener"
) { _ -> listener?.let { remoteListener.register(it) } ?: remoteListener.unregister() }
}
+
+ override fun moveToDesktop(taskId: Int) {
+ ExecutorUtils.executeRemoteCallWithTaskPermission(
+ controller,
+ "moveToDesktop"
+ ) { c -> c.moveToDesktop(taskId) }
+ }
}
companion object {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
index 6bdaf1eadb8a..fa4352241193 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
@@ -45,4 +45,7 @@ interface IDesktopMode {
/** Set listener that will receive callbacks about updates to desktop tasks */
oneway void setTaskListener(IDesktopTaskListener listener);
+
+ /** Move a task with given `taskId` to desktop */
+ void moveToDesktop(int taskId);
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
index 576219769e61..6aad4e2c9da4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
@@ -18,9 +18,14 @@ package com.android.wm.shell.splitscreen;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.graphics.Rect;
+import android.os.Bundle;
+import android.window.RemoteTransition;
+import com.android.internal.logging.InstanceId;
+import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
import com.android.wm.shell.shared.annotations.ExternalThread;
@@ -72,6 +77,12 @@ public interface SplitScreen {
}
}
+ /** Launches a pair of tasks into splitscreen */
+ void startTasks(int taskId1, @Nullable Bundle options1, int taskId2,
+ @Nullable Bundle options2, @SplitPosition int splitPosition,
+ @PersistentSnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition,
+ InstanceId instanceId);
+
/** Registers listener that gets split screen callback. */
void registerSplitScreenListener(@NonNull SplitScreenListener listener,
@NonNull Executor executor);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 088bb4814491..547457b018a1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -506,6 +506,15 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
return mStageCoordinator.getActivateSplitPosition(taskInfo);
}
+ /** Start two tasks in parallel as a splitscreen pair. */
+ public void startTasks(int taskId1, @Nullable Bundle options1, int taskId2,
+ @Nullable Bundle options2, @SplitPosition int splitPosition,
+ @PersistentSnapPosition int snapPosition,
+ @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
+ mStageCoordinator.startTasks(taskId1, options1, taskId2, options2, splitPosition,
+ snapPosition, remoteTransition, instanceId);
+ }
+
/**
* Move a task to split select
* @param taskInfo the task being moved to split select
@@ -1120,6 +1129,15 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
};
@Override
+ public void startTasks(int taskId1, @Nullable Bundle options1, int taskId2,
+ @Nullable Bundle options2, int splitPosition, int snapPosition,
+ @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
+ mMainExecutor.execute(() -> SplitScreenController.this.startTasks(
+ taskId1, options1, taskId2, options2, splitPosition, snapPosition,
+ remoteTransition, instanceId));
+ }
+
+ @Override
public void registerSplitScreenListener(SplitScreenListener listener, Executor executor) {
if (mExecutors.containsKey(listener)) return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
index c26604a84a61..7c2ba455c0c9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
@@ -293,7 +293,13 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene
@Override
public void onFoldStateChanged(boolean isFolded) {
if (isFolded) {
+ // Reset unfold animation finished flag on folding, so it could be used next time
+ // when we unfold the device as an indication that animation hasn't finished yet
mAnimationFinished = false;
+
+ // If we are currently animating unfold animation we should finish it because
+ // the animation might not start and finish as the device was folded
+ finishTransitionIfNeeded();
}
}
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 d0879434657d..b865d94b57ff 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
@@ -19,6 +19,7 @@ package com.android.wm.shell.windowdecor;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.windowingModeToString;
+import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;
@@ -752,7 +753,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
final int action = ev.getActionMasked();
// The comparison against ACTION_UP is needed for the cancel drag to desktop case.
handle.setHovered(inHandle && action != ACTION_UP);
- handle.setPressed(inHandle && action == ACTION_DOWN);
+ // We want handle to remain pressed if the pointer moves outside of it during a drag.
+ handle.setPressed((inHandle && action == ACTION_DOWN)
+ || (handle.isPressed() && action != ACTION_UP && action != ACTION_CANCEL));
if (isHandleMenuActive()) {
mHandleMenu.checkMotionEvent(ev);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleImageButton.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleImageButton.kt
new file mode 100644
index 000000000000..b21c3f522eab
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleImageButton.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor
+
+import android.animation.ValueAnimator
+import android.content.Context
+import android.util.AttributeSet
+import android.widget.ImageButton
+
+/**
+ * [ImageButton] for the handle at the top of fullscreen apps. Has custom hover
+ * and press handling to grow the handle on hover enter and shrink the handle on
+ * hover exit and press.
+ */
+class HandleImageButton (context: Context?, attrs: AttributeSet?) :
+ ImageButton(context, attrs) {
+ private val handleAnimator = ValueAnimator()
+
+ override fun onHoverChanged(hovered: Boolean) {
+ super.onHoverChanged(hovered)
+ if (hovered) {
+ animateHandle(HANDLE_HOVER_ANIM_DURATION, HANDLE_HOVER_ENTER_SCALE)
+ } else {
+ if (!isPressed) {
+ animateHandle(HANDLE_HOVER_ANIM_DURATION, HANDLE_DEFAULT_SCALE)
+ }
+ }
+ }
+
+ override fun setPressed(pressed: Boolean) {
+ if (isPressed != pressed) {
+ super.setPressed(pressed)
+ if (pressed) {
+ animateHandle(HANDLE_PRESS_ANIM_DURATION, HANDLE_PRESS_DOWN_SCALE)
+ } else {
+ animateHandle(HANDLE_PRESS_ANIM_DURATION, HANDLE_DEFAULT_SCALE)
+ }
+ }
+ }
+
+ private fun animateHandle(duration: Long, endScale: Float) {
+ if (handleAnimator.isRunning) {
+ handleAnimator.cancel()
+ }
+ handleAnimator.duration = duration
+ handleAnimator.setFloatValues(scaleX, endScale)
+ handleAnimator.addUpdateListener { animator ->
+ scaleX = animator.animatedValue as Float
+ }
+ handleAnimator.start()
+ }
+
+ companion object {
+ /** The duration of animations related to hover state. **/
+ private const val HANDLE_HOVER_ANIM_DURATION = 300L
+ /** The duration of animations related to pressed state. **/
+ private const val HANDLE_PRESS_ANIM_DURATION = 200L
+ /** Ending scale for hover enter. **/
+ private const val HANDLE_HOVER_ENTER_SCALE = 1.2f
+ /** Ending scale for press down. **/
+ private const val HANDLE_PRESS_DOWN_SCALE = 0.85f
+ /** Default scale for handle. **/
+ private const val HANDLE_DEFAULT_SCALE = 1f
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuImageButton.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuImageButton.kt
index 2fda3ea8daee..7898567b70e9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuImageButton.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuImageButton.kt
@@ -21,7 +21,7 @@ import android.view.MotionEvent
import android.widget.ImageButton
/**
- * A custom [ImageButton] that intentionally does not handle hover events.
+ * A custom [ImageButton] for buttons inside handle menu that intentionally doesn't handle hovers.
* This is due to the hover events being handled by [DesktopModeWindowDecorViewModel]
* in order to take the status bar layer into account. Handling it in both classes results in a
* flicker when the hover moves from outside to inside status bar layer.
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index 2ff1ddd8c0c8..9c623bd5b76f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -120,6 +120,8 @@ public class BackAnimationControllerTest extends ShellTestCase {
private TestableContentResolver mContentResolver;
private TestableLooper mTestableLooper;
+ private CrossActivityBackAnimation mCrossActivityBackAnimation;
+ private CrossTaskBackAnimation mCrossTaskBackAnimation;
private ShellBackAnimationRegistry mShellBackAnimationRegistry;
@Before
@@ -133,11 +135,11 @@ public class BackAnimationControllerTest extends ShellTestCase {
ANIMATION_ENABLED);
mTestableLooper = TestableLooper.get(this);
mShellInit = spy(new ShellInit(mShellExecutor));
+ mCrossActivityBackAnimation = new CrossActivityBackAnimation(mContext, mAnimationBackground,
+ mRootTaskDisplayAreaOrganizer);
+ mCrossTaskBackAnimation = new CrossTaskBackAnimation(mContext, mAnimationBackground);
mShellBackAnimationRegistry =
- new ShellBackAnimationRegistry(
- new CrossActivityBackAnimation(
- mContext, mAnimationBackground, mRootTaskDisplayAreaOrganizer),
- new CrossTaskBackAnimation(mContext, mAnimationBackground),
+ new ShellBackAnimationRegistry(mCrossActivityBackAnimation, mCrossTaskBackAnimation,
/* dialogCloseAnimation= */ null,
new CustomizeActivityAnimation(mContext, mAnimationBackground),
/* defaultBackToHomeAnimation= */ null);
@@ -576,16 +578,14 @@ public class BackAnimationControllerTest extends ShellTestCase {
@Test
public void testBackToActivity() throws RemoteException {
- final CrossActivityBackAnimation animation = new CrossActivityBackAnimation(
- mContext, mAnimationBackground, mRootTaskDisplayAreaOrganizer);
- verifySystemBackBehavior(BackNavigationInfo.TYPE_CROSS_ACTIVITY, animation.getRunner());
+ verifySystemBackBehavior(BackNavigationInfo.TYPE_CROSS_ACTIVITY,
+ mCrossActivityBackAnimation.getRunner());
}
@Test
public void testBackToTask() throws RemoteException {
- final CrossTaskBackAnimation animation = new CrossTaskBackAnimation(mContext,
- mAnimationBackground);
- verifySystemBackBehavior(BackNavigationInfo.TYPE_CROSS_TASK, animation.getRunner());
+ verifySystemBackBehavior(BackNavigationInfo.TYPE_CROSS_TASK,
+ mCrossTaskBackAnimation.getRunner());
}
private void verifySystemBackBehavior(int type, BackAnimationRunner animation)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
index 48e396a4817f..6be411dd81d0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
@@ -1222,6 +1222,19 @@ public class BubbleDataTest extends ShellTestCase {
assertThat(update.bubbleBarLocation).isEqualTo(BubbleBarLocation.LEFT);
}
+ @Test
+ public void setSelectedBubbleAndExpandStack() {
+ sendUpdatedEntryAtTime(mEntryA1, 1000);
+ sendUpdatedEntryAtTime(mEntryA2, 2000);
+ mBubbleData.setListener(mListener);
+
+ mBubbleData.setSelectedBubbleAndExpandStack(mBubbleA1);
+
+ verifyUpdateReceived();
+ assertSelectionChangedTo(mBubbleA1);
+ assertExpandedChangedTo(true);
+ }
+
private void verifyUpdateReceived() {
verify(mListener).applyUpdate(mUpdateCaptor.capture());
reset(mListener);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java
index c5e229feaba7..acc0bce5cce9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java
@@ -298,6 +298,32 @@ public class UnfoldTransitionHandlerTest {
}
@Test
+ public void fold_animationInProgress_finishesTransition() {
+ TransitionRequestInfo requestInfo = createUnfoldTransitionRequestInfo();
+ TransitionFinishCallback finishCallback = mock(TransitionFinishCallback.class);
+
+ // Unfold
+ mShellUnfoldProgressProvider.onFoldStateChanged(/* isFolded= */ false);
+ mUnfoldTransitionHandler.handleRequest(mTransition, requestInfo);
+ mUnfoldTransitionHandler.startAnimation(
+ mTransition,
+ mock(TransitionInfo.class),
+ mock(SurfaceControl.Transaction.class),
+ mock(SurfaceControl.Transaction.class),
+ finishCallback
+ );
+
+ // Start animation but don't finish it
+ mShellUnfoldProgressProvider.onStateChangeStarted();
+ mShellUnfoldProgressProvider.onStateChangeProgress(0.5f);
+
+ // Fold
+ mShellUnfoldProgressProvider.onFoldStateChanged(/* isFolded= */ true);
+
+ verify(finishCallback).onTransitionFinished(any());
+ }
+
+ @Test
public void mergeAnimation_eatsDisplayOnlyTransitions() {
TransitionRequestInfo requestInfo = createUnfoldTransitionRequestInfo();
mUnfoldTransitionHandler.handleRequest(mTransition, requestInfo);
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 2904dfe76f40..708b0113e13e 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -442,14 +442,17 @@ Result<EGLSurface, EGLint> EglManager::createSurface(EGLNativeWindowType window,
}
// TODO: maybe we want to get rid of the WCG check if overlay properties just works?
- const bool canUseFp16 = DeviceInfo::get()->isSupportFp16ForHdr() ||
- DeviceInfo::get()->getWideColorType() == kRGBA_F16_SkColorType;
-
- if (canUseFp16) {
- if (mEglConfigF16 == EGL_NO_CONFIG_KHR) {
- colorMode = ColorMode::Default;
- } else {
- config = mEglConfigF16;
+ bool canUseFp16 = DeviceInfo::get()->isSupportFp16ForHdr() ||
+ DeviceInfo::get()->getWideColorType() == kRGBA_F16_SkColorType;
+
+ if (colorMode == ColorMode::Hdr) {
+ if (canUseFp16 && !DeviceInfo::get()->isSupportRgba10101010ForHdr()) {
+ if (mEglConfigF16 == EGL_NO_CONFIG_KHR) {
+ // If the driver doesn't support fp16 then fallback to 8-bit
+ canUseFp16 = false;
+ } else {
+ config = mEglConfigF16;
+ }
}
}