diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 5ca8b0535dced..2ea0d82355484 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -65,6 +65,7 @@ import android.provider.DocumentsContract; import android.provider.DocumentsProvider; import android.provider.MediaStore; import android.provider.OpenableColumns; +import android.service.chooser.ChooserAction; import android.telecom.PhoneAccount; import android.telecom.TelecomManager; import android.text.TextUtils; @@ -5730,6 +5731,25 @@ public class Intent implements Parcelable, Cloneable { public static final String EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER = "android.intent.extra.CHOOSER_REFINEMENT_INTENT_SENDER"; + /** + * A Parcelable[] of {@link ChooserAction} objects to provide the Android Sharesheet with + * app-specific actions to be presented to the user when invoking {@link #ACTION_CHOOSER}. + * @hide + */ + public static final String EXTRA_CHOOSER_CUSTOM_ACTIONS = + "android.intent.extra.EXTRA_CHOOSER_CUSTOM_ACTIONS"; + + /** + * Optional argument to be used with {@link #ACTION_CHOOSER}. + * A {@link android.app.PendingIntent} to be sent when the user wants to do payload reselection + * in the sharesheet. + * A reselection action allows the user to return to the source app to change the content being + * shared. + * @hide + */ + public static final String EXTRA_CHOOSER_PAYLOAD_RESELECTION_ACTION = + "android.intent.extra.EXTRA_CHOOSER_PAYLOAD_RESELECTION_ACTION"; + /** * An {@code ArrayList} of {@code String} annotations describing content for * {@link #ACTION_CHOOSER}. diff --git a/core/java/android/service/chooser/ChooserAction.java b/core/java/android/service/chooser/ChooserAction.java new file mode 100644 index 0000000000000..3010049633d41 --- /dev/null +++ b/core/java/android/service/chooser/ChooserAction.java @@ -0,0 +1,144 @@ +/* + * 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. + */ + +package android.service.chooser; + +import android.annotation.NonNull; +import android.app.PendingIntent; +import android.graphics.drawable.Icon; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; + +import java.util.Objects; + +/** + * A ChooserAction is an app-defined action that can be provided to the Android Sharesheet to + * be shown to the user when {@link android.content.Intent.ACTION_CHOOSER} is invoked. + * + * @see android.content.Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS + * @see android.content.Intent.EXTRA_CHOOSER_PAYLOAD_RESELECTION_ACTION + * @hide + */ +public final class ChooserAction implements Parcelable { + private final Icon mIcon; + private final CharSequence mLabel; + private final PendingIntent mAction; + + private ChooserAction( + Icon icon, + CharSequence label, + PendingIntent action) { + mIcon = icon; + mLabel = label; + mAction = action; + } + + /** + * Return a user-readable label for this action. + */ + @NonNull + public CharSequence getLabel() { + return mLabel; + } + + /** + * Return an {@link Icon} representing this action. + */ + @NonNull + public Icon getIcon() { + return mIcon; + } + + /** + * Return the action intent. + */ + @NonNull + public PendingIntent getAction() { + return mAction; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + mIcon.writeToParcel(dest, flags); + TextUtils.writeToParcel(mLabel, dest, flags); + mAction.writeToParcel(dest, flags); + } + + @Override + public String toString() { + return "ChooserAction {" + "label=" + mLabel + ", intent=" + mAction + "}"; + } + + public static final Parcelable.Creator CREATOR = + new Creator() { + @Override + public ChooserAction createFromParcel(Parcel source) { + return new ChooserAction( + Icon.CREATOR.createFromParcel(source), + TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source), + PendingIntent.CREATOR.createFromParcel(source)); + } + + @Override + public ChooserAction[] newArray(int size) { + return new ChooserAction[size]; + } + }; + + /** + * Builder class for {@link ChooserAction} objects + */ + public static final class Builder { + private final Icon mIcon; + private final CharSequence mLabel; + private final PendingIntent mAction; + + /** + * Construct a new builder for {@link ChooserAction} object. + * + * @param icon an {@link Icon} representing this action, consisting of a white foreground + * atop a transparent background. + * @param label label the user-readable label for this action. + * @param action {@link PendingIntent} to be invoked when the action is selected. + */ + public Builder( + @NonNull Icon icon, + @NonNull CharSequence label, + @NonNull PendingIntent action) { + Objects.requireNonNull(icon, "icon can not be null"); + Objects.requireNonNull(label, "label can not be null"); + Objects.requireNonNull(action, "pending intent can not be null"); + mIcon = icon; + mLabel = label; + mAction = action; + } + + /** + * Combine all of the options that have been set and return a new {@link ChooserAction} + * object. + * @return the built action + */ + public ChooserAction build() { + return new ChooserAction(mIcon, mLabel, mAction); + } + } +} diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java index 39b9e217fce70..d8afe50d3af3f 100644 --- a/core/java/com/android/internal/jank/InteractionJankMonitor.java +++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java @@ -28,6 +28,8 @@ import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_IN import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_RECENTS; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_WIDGET; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_SWIPE_TO_RECENTS; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_SWIPE; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_TO_HOME; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_OPEN_ALL_APPS; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_QUICK_SWITCH; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_UNLOCK_ENTRANCE_ANIMATION; @@ -227,6 +229,8 @@ public class InteractionJankMonitor { public static final int CUJ_LOCKSCREEN_OCCLUSION = 64; public static final int CUJ_RECENTS_SCROLLING = 65; public static final int CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS = 66; + public static final int CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE = 67; + public static final int CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME = 68; private static final int NO_STATSD_LOGGING = -1; @@ -302,6 +306,8 @@ public class InteractionJankMonitor { UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_OCCLUSION, UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__RECENTS_SCROLLING, UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_SWIPE_TO_RECENTS, + UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_SWIPE, + UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_TO_HOME, }; private static volatile InteractionJankMonitor sInstance; @@ -388,7 +394,9 @@ public class InteractionJankMonitor { CUJ_LAUNCHER_UNLOCK_ENTRANCE_ANIMATION, CUJ_LOCKSCREEN_OCCLUSION, CUJ_RECENTS_SCROLLING, - CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS + CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS, + CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE, + CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME }) @Retention(RetentionPolicy.SOURCE) public @interface CujType { @@ -905,6 +913,10 @@ public class InteractionJankMonitor { return "RECENTS_SCROLLING"; case CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS: return "LAUNCHER_APP_SWIPE_TO_RECENTS"; + case CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE: + return "LAUNCHER_CLOSE_ALL_APPS_SWIPE"; + case CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME: + return "LAUNCHER_CLOSE_ALL_APPS_TO_HOME"; } return "UNKNOWN"; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index 701a3a42fadd3..d3b9fa5e628d6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -93,7 +93,7 @@ import com.android.wm.shell.unfold.animation.SplitTaskUnfoldAnimator; import com.android.wm.shell.unfold.animation.UnfoldTaskAnimator; import com.android.wm.shell.unfold.qualifier.UnfoldShellTransition; import com.android.wm.shell.unfold.qualifier.UnfoldTransition; -import com.android.wm.shell.windowdecor.CaptionWindowDecorViewModel; +import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel; import com.android.wm.shell.windowdecor.WindowDecorViewModel; import java.util.ArrayList; @@ -192,7 +192,7 @@ public abstract class WMShellModule { SyncTransactionQueue syncQueue, Optional desktopModeController, Optional desktopTasksController) { - return new CaptionWindowDecorViewModel( + return new DesktopModeWindowDecorViewModel( context, mainHandler, mainChoreographer, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java similarity index 92% rename from libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java rename to libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java index 299284f5bda6e..b500f5fb01550 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java @@ -61,12 +61,12 @@ import java.util.Optional; /** * View model for the window decoration with a caption and shadows. Works with - * {@link CaptionWindowDecoration}. + * {@link DesktopModeWindowDecoration}. */ -public class CaptionWindowDecorViewModel implements WindowDecorViewModel { - private static final String TAG = "CaptionViewModel"; - private final CaptionWindowDecoration.Factory mCaptionWindowDecorFactory; +public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { + private static final String TAG = "DesktopModeWindowDecorViewModel"; + private final DesktopModeWindowDecoration.Factory mDesktopModeWindowDecorFactory; private final ActivityTaskManager mActivityTaskManager; private final ShellTaskOrganizer mTaskOrganizer; private final Context mContext; @@ -81,11 +81,12 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { private SparseArray mEventReceiversByDisplay = new SparseArray<>(); - private final SparseArray mWindowDecorByTaskId = new SparseArray<>(); + private final SparseArray mWindowDecorByTaskId = + new SparseArray<>(); private final DragStartListenerImpl mDragStartListener = new DragStartListenerImpl(); private InputMonitorFactory mInputMonitorFactory; - public CaptionWindowDecorViewModel( + public DesktopModeWindowDecorViewModel( Context context, Handler mainHandler, Choreographer mainChoreographer, @@ -103,12 +104,12 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { syncQueue, desktopModeController, desktopTasksController, - new CaptionWindowDecoration.Factory(), + new DesktopModeWindowDecoration.Factory(), new InputMonitorFactory()); } @VisibleForTesting - CaptionWindowDecorViewModel( + DesktopModeWindowDecorViewModel( Context context, Handler mainHandler, Choreographer mainChoreographer, @@ -117,7 +118,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { SyncTransactionQueue syncQueue, Optional desktopModeController, Optional desktopTasksController, - CaptionWindowDecoration.Factory captionWindowDecorFactory, + DesktopModeWindowDecoration.Factory desktopModeWindowDecorFactory, InputMonitorFactory inputMonitorFactory) { mContext = context; mMainHandler = mainHandler; @@ -129,7 +130,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { mDesktopModeController = desktopModeController; mDesktopTasksController = desktopTasksController; - mCaptionWindowDecorFactory = captionWindowDecorFactory; + mDesktopModeWindowDecorFactory = desktopModeWindowDecorFactory; mInputMonitorFactory = inputMonitorFactory; } @@ -151,7 +152,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { @Override public void onTaskInfoChanged(RunningTaskInfo taskInfo) { - final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId); + final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId); if (decoration == null) return; @@ -170,7 +171,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { SurfaceControl taskSurface, SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT) { - final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId); + final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId); if (!shouldShowWindowDecor(taskInfo)) { if (decoration != null) { @@ -191,7 +192,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { RunningTaskInfo taskInfo, SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT) { - final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId); + final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId); if (decoration == null) return; decoration.relayout(taskInfo, startT, finishT); @@ -199,7 +200,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { @Override public void destroyWindowDecoration(RunningTaskInfo taskInfo) { - final CaptionWindowDecoration decoration = + final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.removeReturnOld(taskInfo.taskId); if (decoration == null) return; @@ -232,7 +233,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { @Override public void onClick(View v) { - CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId); + DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId); final int id = v.getId(); if (id == R.id.close_window) { WindowContainerTransaction wct = new WindowContainerTransaction(); @@ -373,7 +374,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { boolean handled = false; if (event instanceof MotionEvent) { handled = true; - CaptionWindowDecorViewModel.this + DesktopModeWindowDecorViewModel.this .handleReceivedMotionEvent((MotionEvent) event, mInputMonitor); } finishInputEvent(event, handled); @@ -433,7 +434,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { */ private void handleReceivedMotionEvent(MotionEvent ev, InputMonitor inputMonitor) { if (DesktopModeStatus.isProto2Enabled()) { - CaptionWindowDecoration focusedDecor = getFocusedDecor(); + DesktopModeWindowDecoration focusedDecor = getFocusedDecor(); if (focusedDecor == null || focusedDecor.mTaskInfo.getWindowingMode() != WINDOWING_MODE_FREEFORM) { handleCaptionThroughStatusBar(ev); @@ -460,7 +461,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { private void handleEventOutsideFocusedCaption(MotionEvent ev) { int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { - CaptionWindowDecoration focusedDecor = getFocusedDecor(); + DesktopModeWindowDecoration focusedDecor = getFocusedDecor(); if (focusedDecor == null) { return; } @@ -480,7 +481,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { switch (ev.getActionMasked()) { case MotionEvent.ACTION_DOWN: { // Begin drag through status bar if applicable. - CaptionWindowDecoration focusedDecor = getFocusedDecor(); + DesktopModeWindowDecoration focusedDecor = getFocusedDecor(); if (focusedDecor != null) { boolean dragFromStatusBarAllowed = false; if (DesktopModeStatus.isProto2Enabled()) { @@ -499,7 +500,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { break; } case MotionEvent.ACTION_UP: { - CaptionWindowDecoration focusedDecor = getFocusedDecor(); + DesktopModeWindowDecoration focusedDecor = getFocusedDecor(); if (focusedDecor == null) { mTransitionDragActive = false; return; @@ -529,11 +530,11 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { } @Nullable - private CaptionWindowDecoration getFocusedDecor() { + private DesktopModeWindowDecoration getFocusedDecor() { int size = mWindowDecorByTaskId.size(); - CaptionWindowDecoration focusedDecor = null; + DesktopModeWindowDecoration focusedDecor = null; for (int i = 0; i < size; i++) { - CaptionWindowDecoration decor = mWindowDecorByTaskId.valueAt(i); + DesktopModeWindowDecoration decor = mWindowDecorByTaskId.valueAt(i); if (decor != null && decor.isFocused()) { focusedDecor = decor; break; @@ -571,13 +572,13 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { SurfaceControl taskSurface, SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT) { - CaptionWindowDecoration oldDecoration = mWindowDecorByTaskId.get(taskInfo.taskId); + DesktopModeWindowDecoration oldDecoration = mWindowDecorByTaskId.get(taskInfo.taskId); if (oldDecoration != null) { // close the old decoration if it exists to avoid two window decorations being added oldDecoration.close(); } - final CaptionWindowDecoration windowDecoration = - mCaptionWindowDecorFactory.create( + final DesktopModeWindowDecoration windowDecoration = + mDesktopModeWindowDecorFactory.create( mContext, mDisplayController, mTaskOrganizer, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java similarity index 98% rename from libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java rename to libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java index f7c7a87e66596..467f374f2110f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java @@ -43,12 +43,12 @@ import com.android.wm.shell.desktopmode.DesktopModeStatus; /** * Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with - * {@link CaptionWindowDecorViewModel}. The caption bar contains a handle, back button, and close - * button. + * {@link DesktopModeWindowDecorViewModel}. The caption bar contains a handle, back button, and + * close button. * * The shadow's thickness is 20dp when the window is in focus and 5dp when the window isn't. */ -public class CaptionWindowDecoration extends WindowDecoration { +public class DesktopModeWindowDecoration extends WindowDecoration { private final Handler mHandler; private final Choreographer mChoreographer; private final SyncTransactionQueue mSyncQueue; @@ -69,7 +69,7 @@ public class CaptionWindowDecoration extends WindowDecoration mMockInputManagers = new ArrayList<>(); - private CaptionWindowDecorViewModel mCaptionWindowDecorViewModel; + private DesktopModeWindowDecorViewModel mDesktopModeWindowDecorViewModel; @Before public void setUp() { mMockInputManagers.add(mInputManager); - mCaptionWindowDecorViewModel = - new CaptionWindowDecorViewModel( + mDesktopModeWindowDecorViewModel = + new DesktopModeWindowDecorViewModel( mContext, mMainHandler, mMainChoreographer, @@ -98,12 +98,12 @@ public class CaptionWindowDecorViewModelTests extends ShellTestCase { mSyncQueue, Optional.of(mDesktopModeController), Optional.of(mDesktopTasksController), - mCaptionWindowDecorFactory, + mDesktopModeWindowDecorFactory, mMockInputMonitorFactory ); - doReturn(mCaptionWindowDecoration) - .when(mCaptionWindowDecorFactory) + doReturn(mDesktopModeWindowDecoration) + .when(mDesktopModeWindowDecorFactory) .create(any(), any(), any(), any(), any(), any(), any(), any()); when(mMockInputMonitorFactory.create(any(), any())).thenReturn(mInputMonitor); @@ -123,13 +123,15 @@ public class CaptionWindowDecorViewModelTests extends ShellTestCase { final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class); final SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class); - mCaptionWindowDecorViewModel.onTaskOpening(taskInfo, surfaceControl, startT, finishT); + mDesktopModeWindowDecorViewModel.onTaskOpening( + taskInfo, surfaceControl, startT, finishT); taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_UNDEFINED); taskInfo.configuration.windowConfiguration.setActivityType(ACTIVITY_TYPE_UNDEFINED); - mCaptionWindowDecorViewModel.onTaskChanging(taskInfo, surfaceControl, startT, finishT); + mDesktopModeWindowDecorViewModel.onTaskChanging( + taskInfo, surfaceControl, startT, finishT); }); - verify(mCaptionWindowDecorFactory) + verify(mDesktopModeWindowDecorFactory) .create( mContext, mDisplayController, @@ -139,7 +141,7 @@ public class CaptionWindowDecorViewModelTests extends ShellTestCase { mMainHandler, mMainChoreographer, mSyncQueue); - verify(mCaptionWindowDecoration).close(); + verify(mDesktopModeWindowDecoration).close(); } @Test @@ -153,14 +155,16 @@ public class CaptionWindowDecorViewModelTests extends ShellTestCase { final SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class); taskInfo.configuration.windowConfiguration.setActivityType(ACTIVITY_TYPE_UNDEFINED); - mCaptionWindowDecorViewModel.onTaskChanging(taskInfo, surfaceControl, startT, finishT); + mDesktopModeWindowDecorViewModel.onTaskChanging( + taskInfo, surfaceControl, startT, finishT); taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM); taskInfo.configuration.windowConfiguration.setActivityType(ACTIVITY_TYPE_STANDARD); - mCaptionWindowDecorViewModel.onTaskChanging(taskInfo, surfaceControl, startT, finishT); + mDesktopModeWindowDecorViewModel.onTaskChanging( + taskInfo, surfaceControl, startT, finishT); }); - verify(mCaptionWindowDecorFactory, times(1)) + verify(mDesktopModeWindowDecorFactory, times(1)) .create( mContext, mDisplayController, @@ -183,9 +187,10 @@ public class CaptionWindowDecorViewModelTests extends ShellTestCase { final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class); final SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class); - mCaptionWindowDecorViewModel.onTaskOpening(taskInfo, surfaceControl, startT, finishT); + mDesktopModeWindowDecorViewModel.onTaskOpening( + taskInfo, surfaceControl, startT, finishT); - mCaptionWindowDecorViewModel.destroyWindowDecoration(taskInfo); + mDesktopModeWindowDecorViewModel.destroyWindowDecoration(taskInfo); }); verify(mMockInputMonitorFactory).create(any(), any()); verify(mInputMonitor).dispose(); @@ -214,13 +219,14 @@ public class CaptionWindowDecorViewModelTests extends ShellTestCase { final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class); final SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class); - mCaptionWindowDecorViewModel.onTaskOpening(taskInfo, surfaceControl, startT, finishT); - mCaptionWindowDecorViewModel.onTaskOpening(secondTaskInfo, surfaceControl, + mDesktopModeWindowDecorViewModel.onTaskOpening(taskInfo, surfaceControl, startT, + finishT); + mDesktopModeWindowDecorViewModel.onTaskOpening(secondTaskInfo, surfaceControl, startT, finishT); - mCaptionWindowDecorViewModel.onTaskOpening(thirdTaskInfo, surfaceControl, + mDesktopModeWindowDecorViewModel.onTaskOpening(thirdTaskInfo, surfaceControl, startT, finishT); - mCaptionWindowDecorViewModel.destroyWindowDecoration(thirdTaskInfo); - mCaptionWindowDecorViewModel.destroyWindowDecoration(taskInfo); + mDesktopModeWindowDecorViewModel.destroyWindowDecoration(thirdTaskInfo); + mDesktopModeWindowDecorViewModel.destroyWindowDecoration(taskInfo); }); verify(mMockInputMonitorFactory, times(2)).create(any(), any()); verify(mInputMonitor, times(1)).dispose(); diff --git a/packages/SystemUI/res/drawable/media_ttt_chip_background_receiver.xml b/packages/SystemUI/res/drawable/media_ttt_chip_background_receiver.xml index 708bc1ac7e8a7..8aae276789d68 100644 --- a/packages/SystemUI/res/drawable/media_ttt_chip_background_receiver.xml +++ b/packages/SystemUI/res/drawable/media_ttt_chip_background_receiver.xml @@ -19,8 +19,8 @@ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" android:shape="oval"> - + diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 584823746662c..ecb6560914785 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1073,11 +1073,12 @@ 12dp - 100dp - 95dp + 112dp - 12dp - 20dp + + 36dp + 40dp 35dp diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java index 82d70116bbffb..e08a604338d2c 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java @@ -43,6 +43,10 @@ public final class InteractionJankMonitorWrapper { InteractionJankMonitor.CUJ_LAUNCHER_QUICK_SWITCH; public static final int CUJ_OPEN_ALL_APPS = InteractionJankMonitor.CUJ_LAUNCHER_OPEN_ALL_APPS; + public static final int CUJ_CLOSE_ALL_APPS_SWIPE = + InteractionJankMonitor.CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE; + public static final int CUJ_CLOSE_ALL_APPS_TO_HOME = + InteractionJankMonitor.CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME; public static final int CUJ_ALL_APPS_SCROLL = InteractionJankMonitor.CUJ_LAUNCHER_ALL_APPS_SCROLL; public static final int CUJ_APP_LAUNCH_FROM_WIDGET = @@ -65,7 +69,10 @@ public final class InteractionJankMonitorWrapper { CUJ_APP_LAUNCH_FROM_WIDGET, CUJ_LAUNCHER_UNLOCK_ENTRANCE_ANIMATION, CUJ_RECENTS_SCROLLING, - CUJ_APP_SWIPE_TO_RECENTS + CUJ_APP_SWIPE_TO_RECENTS, + CUJ_OPEN_ALL_APPS, + CUJ_CLOSE_ALL_APPS_SWIPE, + CUJ_CLOSE_ALL_APPS_TO_HOME }) @Retention(RetentionPolicy.SOURCE) public @interface CujType { diff --git a/services/people/java/com/android/server/people/data/ConversationInfo.java b/services/people/java/com/android/server/people/data/ConversationInfo.java index 6ead44a8cd1b8..a539fddc93814 100644 --- a/services/people/java/com/android/server/people/data/ConversationInfo.java +++ b/services/people/java/com/android/server/people/data/ConversationInfo.java @@ -424,6 +424,7 @@ public class ConversationInfo { case (int) ConversationInfoProto.CREATION_TIMESTAMP: builder.setCreationTimestamp(protoInputStream.readLong( ConversationInfoProto.CREATION_TIMESTAMP)); + break; case (int) ConversationInfoProto.SHORTCUT_FLAGS: builder.setShortcutFlags(protoInputStream.readInt( ConversationInfoProto.SHORTCUT_FLAGS)); diff --git a/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java b/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java index c90064eaa8107..9f914a1332b3f 100644 --- a/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java +++ b/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java @@ -30,6 +30,8 @@ import android.app.people.ConversationStatus; import android.content.LocusId; import android.content.pm.ShortcutInfo; import android.net.Uri; +import android.util.proto.ProtoInputStream; +import android.util.proto.ProtoOutputStream; import org.junit.Test; import org.junit.runner.RunWith; @@ -270,4 +272,58 @@ public final class ConversationInfoTest { assertTrue(conversationInfoFromBackup.isContactStarred()); // ConversationStatus is a transient object and not persisted } + + @Test + public void testBuildFromProtoPayload() throws Exception { + ConversationStatus cs = new ConversationStatus.Builder("id", ACTIVITY_ANNIVERSARY).build(); + ConversationStatus cs2 = new ConversationStatus.Builder("id2", ACTIVITY_GAME).build(); + + ConversationInfo conversationInfo = new ConversationInfo.Builder() + .setShortcutId(SHORTCUT_ID) + .setLocusId(LOCUS_ID) + .setContactUri(CONTACT_URI) + .setContactPhoneNumber(PHONE_NUMBER) + .setNotificationChannelId(NOTIFICATION_CHANNEL_ID) + .setParentNotificationChannelId(PARENT_NOTIFICATION_CHANNEL_ID) + .setLastEventTimestamp(100L) + .setCreationTimestamp(200L) + .setShortcutFlags(ShortcutInfo.FLAG_LONG_LIVED + | ShortcutInfo.FLAG_CACHED_NOTIFICATIONS) + .setImportant(true) + .setNotificationSilenced(true) + .setBubbled(true) + .setDemoted(true) + .setPersonImportant(true) + .setPersonBot(true) + .setContactStarred(true) + .addOrUpdateStatus(cs) + .addOrUpdateStatus(cs2) + .build(); + + final ProtoOutputStream protoOutputStream = new ProtoOutputStream(); + conversationInfo.writeToProto(protoOutputStream); + ConversationInfo conversationInfoFromBackup = + ConversationInfo.readFromProto(new ProtoInputStream(protoOutputStream.getBytes())); + + assertEquals(SHORTCUT_ID, conversationInfoFromBackup.getShortcutId()); + assertEquals(LOCUS_ID, conversationInfoFromBackup.getLocusId()); + assertEquals(CONTACT_URI, conversationInfoFromBackup.getContactUri()); + assertEquals(PHONE_NUMBER, conversationInfoFromBackup.getContactPhoneNumber()); + assertEquals( + NOTIFICATION_CHANNEL_ID, conversationInfoFromBackup.getNotificationChannelId()); + assertEquals(PARENT_NOTIFICATION_CHANNEL_ID, + conversationInfoFromBackup.getParentNotificationChannelId()); + assertEquals(100L, conversationInfoFromBackup.getLastEventTimestamp()); + assertEquals(200L, conversationInfoFromBackup.getCreationTimestamp()); + assertTrue(conversationInfoFromBackup.isShortcutLongLived()); + assertTrue(conversationInfoFromBackup.isShortcutCachedForNotification()); + assertTrue(conversationInfoFromBackup.isImportant()); + assertTrue(conversationInfoFromBackup.isNotificationSilenced()); + assertTrue(conversationInfoFromBackup.isBubbled()); + assertTrue(conversationInfoFromBackup.isDemoted()); + assertTrue(conversationInfoFromBackup.isPersonImportant()); + assertTrue(conversationInfoFromBackup.isPersonBot()); + assertTrue(conversationInfoFromBackup.isContactStarred()); + // ConversationStatus is a transient object and not persisted + } }