diff --git a/Android.bp b/Android.bp index bab02b8f28..ac7e136dd9 100644 --- a/Android.bp +++ b/Android.bp @@ -258,9 +258,9 @@ android_library { "go/quickstep/res", ], static_libs: [ + "Launcher3CommonDepsLib", "QuickstepResLib", "androidx.room_room-runtime", - "Launcher3CommonDepsLib", ], plugins: ["androidx.room_room-compiler-plugin"], manifest: "quickstep/AndroidManifest-launcher.xml", @@ -280,15 +280,16 @@ android_library { srcs: [ ":launcher-src-no-build-config", ], - resource_dirs: [], + resource_dirs: [ + "quickstep/res", + ], libs: [ "framework-statsd", ], static_libs: [ - "QuickstepResLib", "SystemUI-statsd", "SystemUISharedLib", - "Launcher3CommonDepsLib", + "Launcher3CommonDepsLib" ], manifest: "quickstep/AndroidManifest.xml", platform_apis: true, diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 22c3131832..398489044e 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -50,7 +50,7 @@ android:stateNotNeeded="true" android:windowSoftInputMode="adjustPan" android:screenOrientation="unspecified" - android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density" + android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize" android:resizeableActivity="true" android:resumeWhilePausing="true" android:taskAffinity="" diff --git a/go/AndroidManifest-launcher.xml b/go/AndroidManifest-launcher.xml index 6a8f715bb2..2223036a7a 100644 --- a/go/AndroidManifest-launcher.xml +++ b/go/AndroidManifest-launcher.xml @@ -49,7 +49,7 @@ android:stateNotNeeded="true" android:windowSoftInputMode="adjustPan" android:screenOrientation="unspecified" - android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density|uiMode" + android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|uiMode" android:resizeableActivity="true" android:resumeWhilePausing="true" android:taskAffinity="" diff --git a/quickstep/AndroidManifest-launcher.xml b/quickstep/AndroidManifest-launcher.xml index 6808222258..53910e344b 100644 --- a/quickstep/AndroidManifest-launcher.xml +++ b/quickstep/AndroidManifest-launcher.xml @@ -49,7 +49,7 @@ android:stateNotNeeded="true" android:windowSoftInputMode="adjustPan" android:screenOrientation="unspecified" - android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density" + android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize" android:resizeableActivity="true" android:resumeWhilePausing="true" android:taskAffinity="" diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml index 124cd57bce..0f9227457a 100644 --- a/quickstep/AndroidManifest.xml +++ b/quickstep/AndroidManifest.xml @@ -65,7 +65,7 @@ android:stateNotNeeded="true" android:theme="@style/LauncherTheme" android:screenOrientation="unspecified" - android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density" + android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize" android:resizeableActivity="true" android:resumeWhilePausing="true" android:taskAffinity=""/> diff --git a/quickstep/res/drawable/bg_overview_clear_all_button.xml b/quickstep/res/drawable/bg_overview_clear_all_button.xml index 47cbd9faba..fb014f75b1 100644 --- a/quickstep/res/drawable/bg_overview_clear_all_button.xml +++ b/quickstep/res/drawable/bg_overview_clear_all_button.xml @@ -20,7 +20,7 @@ - + diff --git a/quickstep/res/drawable/task_menu_item_bg.xml b/quickstep/res/drawable/task_menu_item_bg.xml index 16c13ebebc..b6a8b909ee 100644 --- a/quickstep/res/drawable/task_menu_item_bg.xml +++ b/quickstep/res/drawable/task_menu_item_bg.xml @@ -15,8 +15,7 @@ limitations under the License. --> - - - + + + diff --git a/quickstep/res/layout/task_menu_with_arrow.xml b/quickstep/res/layout/task_menu_with_arrow.xml deleted file mode 100644 index 38573fd1e5..0000000000 --- a/quickstep/res/layout/task_menu_with_arrow.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/quickstep/res/layout/task_view_menu_option.xml b/quickstep/res/layout/task_view_menu_option.xml index 8a8fc36b84..5978b97dd4 100644 --- a/quickstep/res/layout/task_view_menu_option.xml +++ b/quickstep/res/layout/task_view_menu_option.xml @@ -18,7 +18,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:orientation="horizontal" + android:orientation="vertical" android:paddingTop="@dimen/task_card_menu_option_vertical_padding" android:paddingBottom="@dimen/task_card_menu_option_vertical_padding" android:background="@drawable/task_menu_item_bg" diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 8649a1d56c..0b534e31e9 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -27,7 +27,7 @@ 22dp 4dp 2dp - 234dp + 200dp 48dp 16dp @@ -46,7 +46,8 @@ 8dp 16dp - 50dp + 60dp + 52dp 17.13dp 13.38dp 0dp @@ -90,7 +91,7 @@ 8dp 8dp 3dp - 16dp + 12dp 10dp diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml index 40e18ec11f..2efe72e651 100644 --- a/quickstep/res/values/styles.xml +++ b/quickstep/res/values/styles.xml @@ -137,8 +137,8 @@ diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 2ccec44fe2..a83f51ade9 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -175,6 +175,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener public static final int RECENTS_LAUNCH_DURATION = 336; private static final int LAUNCHER_RESUME_START_DELAY = 100; private static final int CLOSING_TRANSITION_DURATION_MS = 250; + public static final int SPLIT_LAUNCH_DURATION = 370; public static final int CONTENT_ALPHA_DURATION = 217; protected static final int CONTENT_SCALE_DURATION = 350; diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 5bc454ec89..a2e4c225d9 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -166,7 +166,8 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ new StashedHandleViewController(this, stashedHandleView), new TaskbarStashController(this), new TaskbarEduController(this), - new TaskbarAutohideSuspendController(this)); + new TaskbarAutohideSuspendController(this), + new TaskbarPopupController()); } public void init(TaskbarSharedState sharedState) { @@ -202,9 +203,7 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ updateSysuiStateFlags(sharedState.sysuiStateFlags, true /* fromInit */); mWindowManager.addView(mDragLayer, mWindowLayoutParams); - if (TestProtocol.sDebugTracing) { - Log.e(TASKBAR_WINDOW_CRASH, "Adding taskbar window"); - } + Log.d(TASKBAR_WINDOW_CRASH, "Adding taskbar window"); } public boolean isThreeButtonNav() { @@ -257,6 +256,11 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ return false; } + @Override + public View.OnClickListener getItemOnClickListener() { + return this::onTaskbarIconClicked; + } + /** * Change from hotseat/predicted hotseat to taskbar container. */ @@ -335,9 +339,7 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ setUIController(TaskbarUIController.DEFAULT); mControllers.onDestroy(); mWindowManager.removeViewImmediate(mDragLayer); - if (TestProtocol.sDebugTracing) { - Log.e(TASKBAR_WINDOW_CRASH, "Removing taskbar window"); - } + Log.d(TASKBAR_WINDOW_CRASH, "Removing taskbar window"); } public void updateSysuiStateFlags(int systemUiStateFlags, boolean fromInit) { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java index 08a79c064d..56730dbd70 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java @@ -38,6 +38,7 @@ public class TaskbarControllers { public final TaskbarStashController taskbarStashController; public final TaskbarEduController taskbarEduController; public final TaskbarAutohideSuspendController taskbarAutohideSuspendController; + public final TaskbarPopupController taskbarPopupController; /** Do not store this controller, as it may change at runtime. */ @NonNull public TaskbarUIController uiController = TaskbarUIController.DEFAULT; @@ -55,7 +56,8 @@ public class TaskbarControllers { StashedHandleViewController stashedHandleViewController, TaskbarStashController taskbarStashController, TaskbarEduController taskbarEduController, - TaskbarAutohideSuspendController taskbarAutoHideSuspendController) { + TaskbarAutohideSuspendController taskbarAutoHideSuspendController, + TaskbarPopupController taskbarPopupController) { this.taskbarActivityContext = taskbarActivityContext; this.taskbarDragController = taskbarDragController; this.navButtonController = navButtonController; @@ -70,6 +72,7 @@ public class TaskbarControllers { this.taskbarStashController = taskbarStashController; this.taskbarEduController = taskbarEduController; this.taskbarAutohideSuspendController = taskbarAutoHideSuspendController; + this.taskbarPopupController = taskbarPopupController; } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java index 3bcacb6c8a..b3a9f8db7c 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java @@ -40,6 +40,7 @@ import com.android.launcher3.DropTarget; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.accessibility.DragViewStateAnnouncer; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragDriver; import com.android.launcher3.dragndrop.DragOptions; @@ -49,6 +50,7 @@ import com.android.launcher3.graphics.DragPreviewProvider; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; +import com.android.launcher3.popup.PopupContainerWithArrow; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ClipDescriptionCompat; import com.android.systemui.shared.system.LauncherAppsCompat; @@ -139,11 +141,13 @@ public class TaskbarDragController extends DragController popupContainer = + mControllers.taskbarPopupController.showForIcon(btv); + if (popupContainer != null) { + dragOptions.preDragCondition = popupContainer.createPreDragCondition(); + } + } startDrag( drawable, diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java index 53feaad9e6..b2b078cb4f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java @@ -207,10 +207,8 @@ public class TaskbarManager implements DisplayController.DisplayInfoChangeListen } private void recreateTaskbar() { - if (TestProtocol.sDebugTracing) { - Log.e(TASKBAR_WINDOW_CRASH, "Recreating taskbar: mTaskbarActivityContext=" - + mTaskbarActivityContext); - } + Log.d(TASKBAR_WINDOW_CRASH, "Recreating taskbar: mTaskbarActivityContext=" + + mTaskbarActivityContext); destroyExistingTaskbar(); DeviceProfile dp = @@ -233,9 +231,7 @@ public class TaskbarManager implements DisplayController.DisplayInfoChangeListen mTaskbarActivityContext.setUIController( createTaskbarUIControllerForActivity(mActivity)); } - if (TestProtocol.sDebugTracing) { - Log.e(TASKBAR_WINDOW_CRASH, "Finished recreating taskbar"); - } + Log.d(TASKBAR_WINDOW_CRASH, "Finished recreating taskbar"); } public void onSystemUiFlagsChanged(int systemUiStateFlags) { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java index 5e76b960fd..6dcfe564a6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java @@ -23,6 +23,7 @@ import com.android.launcher3.model.BgDataModel; import com.android.launcher3.model.BgDataModel.FixedContainerItems; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; +import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.ItemInfoMatcher; @@ -30,6 +31,7 @@ import com.android.launcher3.util.LauncherBindableItemsContainer; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -186,4 +188,9 @@ public class TaskbarModelCallbacks implements TaskbarStashController.FLAG_STASHED_IN_APP_EMPTY, isHotseatEmpty); mControllers.taskbarStashController.applyState(); } + + @Override + public void bindDeepShortcutMap(HashMap deepShortcutMapCopy) { + mControllers.taskbarPopupController.setDeepShortcutMap(deepShortcutMapCopy); + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java new file mode 100644 index 0000000000..952f597f72 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2021 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.launcher3.taskbar; + +import androidx.annotation.NonNull; + +import com.android.launcher3.BubbleTextView; +import com.android.launcher3.R; +import com.android.launcher3.model.data.ItemInfo; +import com.android.launcher3.popup.PopupContainerWithArrow; +import com.android.launcher3.popup.PopupDataProvider; +import com.android.launcher3.popup.SystemShortcut; +import com.android.launcher3.util.ComponentKey; +import com.android.launcher3.views.ActivityContext; + +import java.util.HashMap; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Implements interfaces required to show and allow interacting with a PopupContainerWithArrow. + */ +public class TaskbarPopupController { + + private static final SystemShortcut.Factory + APP_INFO = SystemShortcut.AppInfo::new; + + private final PopupDataProvider mPopupDataProvider; + + public TaskbarPopupController() { + // TODO (b/198438631): add notifications dots change listener + mPopupDataProvider = new PopupDataProvider(packageUserKey -> {}); + } + + @NonNull + public PopupDataProvider getPopupDataProvider() { + return mPopupDataProvider; + } + + public void setDeepShortcutMap(HashMap deepShortcutMapCopy) { + mPopupDataProvider.setDeepShortcutMap(deepShortcutMapCopy); + } + + /** + * Shows the notifications and deep shortcuts associated with a Taskbar {@param icon}. + * @return the container if shown or null. + */ + public PopupContainerWithArrow showForIcon(BubbleTextView icon) { + TaskbarActivityContext context = ActivityContext.lookupContext(icon.getContext()); + if (PopupContainerWithArrow.getOpen(context) != null) { + // There is already an items container open, so don't open this one. + icon.clearFocus(); + return null; + } + ItemInfo item = (ItemInfo) icon.getTag(); + if (!PopupContainerWithArrow.canShow(icon, item)) { + return null; + } + + final PopupContainerWithArrow container = + (PopupContainerWithArrow) context.getLayoutInflater().inflate( + R.layout.popup_container, context.getDragLayer(), false); + // TODO (b/198438631): configure for taskbar/context + + container.populateAndShow(icon, + mPopupDataProvider.getShortcutCountForItem(item), + mPopupDataProvider.getNotificationKeysForItem(item), + // TODO (b/198438631): add support for INSTALL shortcut factory + Stream.of(APP_INFO) + .map(s -> s.getShortcut(context, item)) + .filter(Objects::nonNull) + .collect(Collectors.toList())); + container.requestFocus(); + return container; + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 09197c3240..c47bde9dcd 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -261,7 +261,7 @@ public class TaskbarViewController { private boolean mCanceledStashHint; public View.OnClickListener getIconOnClickListener() { - return mActivity::onTaskbarIconClicked; + return mActivity.getItemOnClickListener(); } public View.OnLongClickListener getIconOnLongClickListener() { diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java index cf06036ffa..944fb48c36 100644 --- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java +++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java @@ -308,7 +308,7 @@ public abstract class BaseActivityInterface { float progress = valueAnimator.getAnimatedFraction(); for (SurfaceControl leash: openingTargets) { @@ -559,7 +561,7 @@ public final class TaskViewUtils { anim.addListener(windowAnimEndListener); } - static void setSplitAuxiliarySurfacesShown(RemoteAnimationTargetCompat[] nonApps, + public static void setSplitAuxiliarySurfacesShown(RemoteAnimationTargetCompat[] nonApps, boolean shown) { // TODO(b/182592057): make this part of the animations instead. if (nonApps != null && nonApps.length > 0) { diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 502ab68fd5..5828a6d47d 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -347,9 +347,7 @@ public class TouchInteractionService extends Service @Override public void onCreate() { super.onCreate(); - if (TestProtocol.sDebugTracing) { - Log.e(TASKBAR_WINDOW_CRASH, "TIS created"); - } + Log.d(TASKBAR_WINDOW_CRASH, "TIS created"); // Initialize anything here that is needed in direct boot mode. // Everything else should be initialized in onUserUnlocked() below. mMainChoreographer = Choreographer.getInstance(); @@ -511,9 +509,7 @@ public class TouchInteractionService extends Service @Override public void onDestroy() { Log.d(TAG, "Touch service destroyed: user=" + getUserId()); - if (TestProtocol.sDebugTracing) { - Log.e(TASKBAR_WINDOW_CRASH, "TIS destroyed"); - } + Log.d(TASKBAR_WINDOW_CRASH, "TIS destroyed"); sIsInitialized = false; if (mDeviceState.isUserUnlocked()) { mInputConsumer.unregisterInputConsumer(); diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java index 86be2109ad..4f2ed4cd82 100644 --- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java +++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java @@ -21,6 +21,7 @@ import android.util.AttributeSet; import android.util.FloatProperty; import android.widget.Button; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.touch.PagedOrientationHandler; @@ -245,6 +246,9 @@ public class ClearAllButton extends Button { * Get the Y translation that is set in the original layout position, before scrolling. */ private float getOriginalTranslationY() { - return mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx / 2.0f; + DeviceProfile deviceProfile = mActivity.getDeviceProfile(); + return deviceProfile.overviewShowAsGrid + ? deviceProfile.overviewRowSpacing + : deviceProfile.overviewTaskThumbnailTopMarginPx / 2.0f; } } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index b5238c64b7..33ba7dd9e7 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -4241,6 +4241,10 @@ public abstract class RecentsView { if (isSuccess) { + if (tv.getTaskIds()[1] != -1) { + TaskViewUtils.setSplitAuxiliarySurfacesShown(mRemoteTargetHandles[0] + .getTransformParams().getTargetSet().nonApps, true); + } if (ENABLE_QUICKSTEP_LIVE_TILE.get() && tv.isRunningTask()) { finishRecentsAnimation(false /* toRecents */, null); onTaskLaunchAnimationEnd(true /* success */); diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java index 2690a2a054..77ac373827 100644 --- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java +++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java @@ -270,9 +270,15 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams(); int padding = getResources() .getDimensionPixelSize(R.dimen.task_menu_vertical_padding); - params.width = orientationHandler - .getTaskMenuWidth(taskContainer.getThumbnailView(), - deviceProfile) - (2 * padding); + if (deviceProfile.overviewShowAsGrid) { + // TODO(b/193432925) temporary so it doesn't look terrible on large screen + params.width = + getContext().getResources().getDimensionPixelSize(R.dimen.task_menu_width_grid); + } else { + params.width = orientationHandler + .getTaskMenuWidth(taskContainer.getThumbnailView(), + deviceProfile) - (2 * padding); + } // Gravity set to Left instead of Start as sTempRect.left measures Left distance not Start params.gravity = Gravity.LEFT; setLayoutParams(params); diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt index 39a6fc4668..9b86c73170 100644 --- a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt +++ b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt @@ -1,150 +1,14 @@ package com.android.quickstep.views -import android.animation.AnimatorSet -import android.animation.ObjectAnimator -import android.content.Context -import android.graphics.Rect -import android.graphics.drawable.ShapeDrawable -import android.graphics.drawable.shapes.RectShape -import android.util.AttributeSet -import android.view.MotionEvent -import android.view.View -import android.view.ViewGroup -import android.widget.LinearLayout -import com.android.launcher3.BaseDraggingActivity -import com.android.launcher3.DeviceProfile -import com.android.launcher3.R -import com.android.launcher3.popup.ArrowPopup -import com.android.launcher3.popup.SystemShortcut -import com.android.launcher3.util.Themes -import com.android.quickstep.TaskOverlayFactory -import com.android.quickstep.views.TaskView.TaskIdAttributeContainer +import android.util.Log -class TaskMenuViewWithArrow : ArrowPopup { +// TODO(http://b/193432925) +class TaskMenuViewWithArrow { companion object { const val TAG = "TaskMenuViewWithArrow" - fun showForTask(taskContainer: TaskIdAttributeContainer): Boolean { - val activity = BaseDraggingActivity - .fromContext(taskContainer.taskView.context) - val taskMenuViewWithArrow = activity.layoutInflater - .inflate(R.layout.task_menu_with_arrow, activity.dragLayer, false) as TaskMenuViewWithArrow<*> - - return taskMenuViewWithArrow.populateAndShowForTask(taskContainer) + fun logSomething() { + Log.d(TAG, "It worked!") } } - - constructor(context: Context) : super(context) - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) - - init { - clipToOutline = true - } - - private val menuWidth = context.resources.getDimensionPixelSize(R.dimen.task_menu_width_grid) - - private lateinit var taskView: TaskView - private lateinit var optionLayout: LinearLayout - private lateinit var taskContainer: TaskIdAttributeContainer - - override fun isOfType(type: Int): Boolean = type and TYPE_TASK_MENU != 0 - - override fun getTargetObjectLocation(outPos: Rect?) { - popupContainer.getDescendantRectRelativeToSelf(taskView.iconView, outPos) - } - - override fun onControllerInterceptTouchEvent(ev: MotionEvent?): Boolean { - if (ev?.action == MotionEvent.ACTION_DOWN) { - if (!popupContainer.isEventOverView(this, ev)) { - close(true) - return true - } - } - return false - } - - override fun onFinishInflate() { - super.onFinishInflate() - optionLayout = findViewById(R.id.menu_option_layout) - } - - private fun populateAndShowForTask(taskContainer: TaskIdAttributeContainer): Boolean { - if (isAttachedToWindow) { - return false - } - - taskView = taskContainer.taskView - this.taskContainer = taskContainer - if (!populateMenu()) return false - show() - return true - } - - /** @return true if successfully able to populate task view menu, false otherwise - */ - private fun populateMenu(): Boolean { - // Icon may not be loaded - if (taskContainer.task.icon == null) return false - - addMenuOptions() - return true - } - - private fun addMenuOptions() { - // Add the options - TaskOverlayFactory - .getEnabledShortcuts(taskView, mActivityContext.deviceProfile, taskContainer) - .forEach { this.addMenuOption(it) } - - // Add the spaces between items - val divider = ShapeDrawable(RectShape()) - divider.paint.color = resources.getColor(android.R.color.transparent) - val dividerSpacing = resources.getDimension(R.dimen.task_menu_spacing).toInt() - optionLayout.showDividers = SHOW_DIVIDER_MIDDLE - - // Set the orientation, which makes the menu show - val recentsView: RecentsView<*, *> = mActivityContext.getOverviewPanel() - val orientationHandler = recentsView.pagedOrientationHandler - val deviceProfile: DeviceProfile = mActivityContext.deviceProfile - orientationHandler.setTaskOptionsMenuLayoutOrientation( - deviceProfile, - optionLayout, - dividerSpacing, - divider - ) - } - - private fun addMenuOption(menuOption: SystemShortcut<*>) { - val menuOptionView = mActivityContext.layoutInflater.inflate( - R.layout.task_view_menu_option, this, false - ) as LinearLayout - menuOption.setIconAndLabelFor( - menuOptionView.findViewById(R.id.icon), - menuOptionView.findViewById(R.id.text) - ) - val lp = menuOptionView.layoutParams as LayoutParams - lp.width = menuWidth - menuOptionView.setOnClickListener { view: View? -> menuOption.onClick(view) } - optionLayout.addView(menuOptionView) - } - - override fun assignMarginsAndBackgrounds(viewGroup: ViewGroup) { - assignMarginsAndBackgrounds(this, Themes.getAttrColor(context, com.android.internal.R.attr.colorSurface)) - } - - override fun onCreateOpenAnimation(anim: AnimatorSet) { - anim.play( - ObjectAnimator.ofFloat( - taskContainer.thumbnailView, TaskThumbnailView.DIM_ALPHA, - TaskView.MAX_PAGE_SCRIM_ALPHA - ) - ) - } - - override fun onCreateCloseAnimation(anim: AnimatorSet) { - anim.play( - ObjectAnimator.ofFloat(taskContainer.thumbnailView, TaskThumbnailView.DIM_ALPHA, 0f) - ) - } } \ No newline at end of file diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index df1817ed1c..f88b243cab 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -824,11 +824,9 @@ public class TaskView extends FrameLayout implements Reusable { } protected boolean showTaskMenuWithContainer(IconView iconView) { - if (mActivity.getDeviceProfile().overviewShowAsGrid) { - return TaskMenuViewWithArrow.Companion.showForTask(mTaskIdAttributeContainer[0]); - } else { - return TaskMenuView.showForTask(mTaskIdAttributeContainer[0]); - } + // TODO(http://b/193432925) + if (DEBUG) TaskMenuViewWithArrow.Companion.logSomething(); + return TaskMenuView.showForTask(mTaskIdAttributeContainer[0]); } protected void setIcon(IconView iconView, Drawable icon) { diff --git a/res/values/dimens.xml b/res/values/dimens.xml index dfdd4199f4..4a6e5d525e 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -341,6 +341,8 @@ 0dp 0dp 0dp + 0dp + 0dp 0dp 0dp 0dp diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index e29cd559ae..e8d68024e0 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -193,6 +193,7 @@ public class DeviceProfile { public final int overviewActionsBottomMarginGesturePx; public int overviewPageSpacing; public int overviewRowSpacing; + public int overviewGridSideMargin; // Widgets public final PointF appWidgetScale = new PointF(1.0f, 1.0f); @@ -400,6 +401,9 @@ public class DeviceProfile { overviewRowSpacing = isLandscape ? res.getDimensionPixelSize(R.dimen.overview_grid_row_spacing_landscape) : res.getDimensionPixelSize(R.dimen.overview_grid_row_spacing_portrait); + overviewGridSideMargin = isLandscape + ? res.getDimensionPixelSize(R.dimen.overview_grid_side_margin_landscape) + : res.getDimensionPixelSize(R.dimen.overview_grid_side_margin_portrait); // Calculate all of the remaining variables. extraSpace = updateAvailableDimensions(res); diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 13583874b9..d3629947c8 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -204,6 +204,10 @@ public final class FeatureFlags { public static final BooleanFlag ENABLE_TASKBAR_EDU = getDebugFlag("ENABLE_TASKBAR_EDU", true, "Enables showing taskbar education the first time an app is opened."); + public static final BooleanFlag ENABLE_TASKBAR_POPUP_MENU = getDebugFlag( + "ENABLE_TASKBAR_POPUP_MENU", false, "Enables long pressing taskbar icons to show the" + + " popup menu."); + public static final BooleanFlag ENABLE_OVERVIEW_GRID = getDebugFlag( "ENABLE_OVERVIEW_GRID", true, "Uses grid overview layout. " + "Only applicable on large screen devices."); diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java index 5a1e4bf27e..223091485c 100644 --- a/src/com/android/launcher3/popup/ArrowPopup.java +++ b/src/com/android/launcher3/popup/ArrowPopup.java @@ -234,7 +234,7 @@ public abstract class ArrowPopup * @param backgroundColor When Color.TRANSPARENT, we get color from {@link #mColorIds}. * Otherwise, we will use this color for all child views. */ - protected void assignMarginsAndBackgrounds(ViewGroup viewGroup, int backgroundColor) { + private void assignMarginsAndBackgrounds(ViewGroup viewGroup, int backgroundColor) { int[] colors = null; if (backgroundColor == Color.TRANSPARENT) { // Lazily get the colors so they match the current wallpaper colors. @@ -445,7 +445,7 @@ public abstract class ArrowPopup animateOpen(); } - protected void setupForDisplay() { + private void setupForDisplay() { setVisibility(View.INVISIBLE); mIsOpen = true; getPopupContainer().addView(this); @@ -482,7 +482,7 @@ public abstract class ArrowPopup mArrow.setVisibility(show && shouldAddArrow() ? VISIBLE : INVISIBLE); } - protected void addArrow() { + private void addArrow() { getPopupContainer().addView(mArrow); mArrow.setX(getX() + getArrowLeft()); @@ -686,13 +686,12 @@ public abstract class ArrowPopup return getChildCount() > 0 ? getChildAt(0) : this; } - protected void animateOpen() { + private void animateOpen() { setVisibility(View.VISIBLE); mOpenCloseAnimator = getOpenCloseAnimator(true, OPEN_DURATION, OPEN_FADE_START_DELAY, OPEN_FADE_DURATION, OPEN_CHILD_FADE_START_DELAY, OPEN_CHILD_FADE_DURATION, DECELERATED_EASE); - onCreateOpenAnimation(mOpenCloseAnimator); mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -785,11 +784,6 @@ public abstract class ArrowPopup mOpenCloseAnimator.start(); } - /** - * Called when creating the open transition allowing subclass can add additional animations. - */ - protected void onCreateOpenAnimation(AnimatorSet anim) { } - /** * Called when creating the close transition allowing subclass can add additional animations. */ diff --git a/src/com/android/launcher3/statemanager/StateManager.java b/src/com/android/launcher3/statemanager/StateManager.java index b34af975bd..1767939114 100644 --- a/src/com/android/launcher3/statemanager/StateManager.java +++ b/src/com/android/launcher3/statemanager/StateManager.java @@ -84,7 +84,7 @@ public class StateManager> { + ", mCurrentStableState:" + mCurrentStableState + ", mState:" + mState + ", mRestState:" + mRestState - + ", isInTransition:" + (mConfig.currentAnimation != null) + ")"; + + ", isInTransition:" + isInTransition() + ")"; } public void dump(String prefix, PrintWriter writer) { @@ -93,7 +93,7 @@ public class StateManager> { writer.println(prefix + "\tmCurrentStableState:" + mCurrentStableState); writer.println(prefix + "\tmState:" + mState); writer.println(prefix + "\tmRestState:" + mRestState); - writer.println(prefix + "\tisInTransition:" + (mConfig.currentAnimation != null)); + writer.println(prefix + "\tisInTransition:" + isInTransition()); } public StateHandler[] getStateHandlers() { @@ -129,6 +129,13 @@ public class StateManager> { && (mConfig.targetState == null || mConfig.targetState == state); } + /** + * @return {@code true} If there is an active transition. + */ + public boolean isInTransition() { + return mConfig.currentAnimation != null; + } + /** * @see #goToState(STATE_TYPE, boolean, AnimatorListener) */ diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java index 17d925c1f9..8ebfd62b69 100644 --- a/src/com/android/launcher3/testing/TestInformationHandler.java +++ b/src/com/android/launcher3/testing/TestInformationHandler.java @@ -157,6 +157,12 @@ public class TestInformationHandler implements ResourceBasedOverride { return response; } + case TestProtocol.REQUEST_ENABLE_ROTATION: + MAIN_EXECUTOR.submit(() -> + Launcher.ACTIVITY_TRACKER.getCreatedActivity().getRotationHelper() + .forceAllowRotationForTesting(Boolean.parseBoolean(arg))); + return null; + default: return null; } diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index 91c7221313..9a74fb1577 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -108,6 +108,7 @@ public final class TestProtocol { "get-focused-task-height-for-tablet"; public static final String REQUEST_GET_GRID_TASK_SIZE_RECT_FOR_TABLET = "get-grid-task-size-rect-for-tablet"; + public static final String REQUEST_ENABLE_ROTATION = "enable_rotation"; public static Long sForcePauseTimeout; public static final String REQUEST_SET_FORCE_PAUSE_TIMEOUT = "set-force-pause-timeout"; diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml index dd75ade2d0..9f2a6292e8 100644 --- a/tests/AndroidManifest-common.xml +++ b/tests/AndroidManifest-common.xml @@ -110,7 +110,7 @@ state) { + protected void waitForStateTransitionToEnd(String message, Supplier state) { waitForLauncherCondition(message, - launcher -> launcher.getStateManager().isInStableState(state.get())); + launcher -> launcher.getStateManager().isInStableState(state.get()) + && !launcher.getStateManager().isInTransition()); } protected void waitForResumed(String message) { diff --git a/tests/src/com/android/launcher3/ui/WorkProfileTest.java b/tests/src/com/android/launcher3/ui/WorkProfileTest.java index 2087bfe8c6..aca5951e64 100644 --- a/tests/src/com/android/launcher3/ui/WorkProfileTest.java +++ b/tests/src/com/android/launcher3/ui/WorkProfileTest.java @@ -91,9 +91,11 @@ public class WorkProfileTest extends AbstractLauncherUiTest { public void workTabExists() { mDevice.pressHome(); waitForLauncherCondition("Launcher didn't start", Objects::nonNull); - waitForStableState("Launcher internal state didn't switch to Normal", () -> NORMAL); + waitForStateTransitionToEnd("Launcher internal state didn't switch to Normal", + () -> NORMAL); executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS)); - waitForStableState("Launcher internal state didn't switch to All Apps", () -> ALL_APPS); + waitForStateTransitionToEnd("Launcher internal state didn't switch to All Apps", + () -> ALL_APPS); waitForLauncherCondition("Personal tab is missing", launcher -> launcher.getAppsView().isPersonalTabVisible(), LauncherInstrumentation.WAIT_TIME_MS); diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index e2d023825c..5a807caa13 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -350,6 +350,10 @@ public final class LauncherInstrumentation { getTestInfo(TestProtocol.REQUEST_SET_FORCE_PAUSE_TIMEOUT, Long.toString(timeout)); } + public void setEnableRotation(boolean on) { + getTestInfo(TestProtocol.REQUEST_ENABLE_ROTATION, Boolean.toString(on)); + } + public boolean hadNontestEvents() { return getTestInfo(TestProtocol.REQUEST_GET_HAD_NONTEST_EVENTS) .getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD);