From 3c2a17b6f649c5e98178e9206d7c5a7843b855e3 Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Tue, 23 Jun 2020 12:53:37 -0700 Subject: [PATCH 001/160] Remove hotseat edu flag Launcher should not restrict user migration to a one time event if we want users to migrate their hotseat by enabling hotseat prediction from suggestion settings. Test: Manual Bug: 159731272 Change-Id: I0e42dd6b6cf6374928e5b399d121d17fe8024ae1 --- .../launcher3/hybridhotseat/HotseatEduController.java | 2 -- .../hybridhotseat/HotseatPredictionController.java | 10 +--------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java index a1218aeb86..4f95254a72 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java @@ -47,7 +47,6 @@ import java.util.stream.IntStream; */ public class HotseatEduController { - public static final String KEY_HOTSEAT_EDU_SEEN = "hotseat_edu_seen"; public static final String HOTSEAT_EDU_ACTION = "com.android.launcher3.action.SHOW_HYBRID_HOTSEAT_EDU"; public static final String SETTINGS_ACTION = @@ -229,7 +228,6 @@ public class HotseatEduController { void finishOnboarding() { mOnOnboardingComplete.run(); - mLauncher.getSharedPrefs().edit().putBoolean(KEY_HOTSEAT_EDU_SEEN, true).apply(); } void showDimissTip() { diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java index 7334d80dd6..1dbb9e2d6b 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java @@ -154,14 +154,6 @@ public class HotseatPredictionController implements DragController.DragListener, } } - /** - * Returns whether or not user has seen hybrid hotseat education - */ - public boolean isEduSeen() { - return mLauncher.getSharedPrefs().getBoolean(HotseatEduController.KEY_HOTSEAT_EDU_SEEN, - false); - } - /** * Shows appropriate hotseat education based on prediction enabled and migration states. */ @@ -172,7 +164,7 @@ public class HotseatPredictionController implements DragController.DragListener, Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_disabled, R.string.hotseat_prediction_settings, null, () -> mLauncher.startActivity(getSettingsIntent())); - } else if (isEduSeen() || getPredictedIcons().size() >= (mHotSeatItemsCount + 1) / 2) { + } else if (getPredictedIcons().size() >= (mHotSeatItemsCount + 1) / 2) { showDiscoveryTip(); } else { HotseatEduController eduController = new HotseatEduController(mLauncher, From aa902e859b49517bd5d6412b42e5de0dd9d0a916 Mon Sep 17 00:00:00 2001 From: Ashwini Oruganti Date: Thu, 4 Jun 2020 17:47:09 -0700 Subject: [PATCH 002/160] Add an exported flag in manifest With b/150232615, we will need an explicit value set for the exported flag when intent filters are present, as the default behavior is changing for future versions. This change adds the value reflecting the previous default to the manifest. These changes were made using an automated tool, the xml file may be reformatted slightly creating a larger diff. The only "real" change is the addition of "android:exported" to activities, services, and receivers that have one or more intent-filters. Bug: 150232615 Bug: 158198882 Test: TH Exempt-From-Owner-Approval: mechanical refactoring Change-Id: I083a7bcab968c881f7cdff7152a249691ffac316 --- AndroidManifest-common.xml | 11 ++- AndroidManifest.xml | 1 + quickstep/AndroidManifest-launcher.xml | 1 + quickstep/AndroidManifest.xml | 126 ++++++++++++------------- tests/AndroidManifest-common.xml | 22 ++++- tests/dummy_app/AndroidManifest.xml | 1 + 6 files changed, 92 insertions(+), 70 deletions(-) diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml index ff5bf0d1e5..84dd06aa39 100644 --- a/AndroidManifest-common.xml +++ b/AndroidManifest-common.xml @@ -86,6 +86,7 @@ @@ -94,14 +95,16 @@ + android:name="com.android.launcher3.SessionCommitReceiver" + android:exported="true"> - + @@ -117,6 +120,7 @@ android:name="com.android.launcher3.notification.NotificationListener" android:label="@string/notification_dots_service_title" android:enabled="@bool/notification_dots_enabled" + android:exported="true" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> @@ -130,6 +134,7 @@ android:theme="@style/AppItemActivityTheme" android:excludeFromRecents="true" android:autoRemoveFromRecents="true" + android:exported="true" android:label="@string/action_add_to_workspace" > @@ -165,6 +170,7 @@ android:name="com.android.launcher3.settings.SettingsActivity" android:label="@string/settings_button_text" android:theme="@style/HomeSettingsTheme" + android:exported="true" android:autoRemoveFromRecents="true"> @@ -187,6 +193,7 @@ android:name="com.android.launcher3.secondarydisplay.SecondaryDisplayLauncher" android:theme="@style/AppTheme" android:launchMode="singleTop" + android:exported="true" android:enabled="true"> diff --git a/AndroidManifest.xml b/AndroidManifest.xml index b031ffbee4..8e01f82018 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -53,6 +53,7 @@ android:resizeableActivity="true" android:resumeWhilePausing="true" android:taskAffinity="" + android:exported="true" android:enabled="true"> diff --git a/quickstep/AndroidManifest-launcher.xml b/quickstep/AndroidManifest-launcher.xml index 60afddb0a8..53910e344b 100644 --- a/quickstep/AndroidManifest-launcher.xml +++ b/quickstep/AndroidManifest-launcher.xml @@ -53,6 +53,7 @@ android:resizeableActivity="true" android:resumeWhilePausing="true" android:taskAffinity="" + android:exported="true" android:enabled="true"> diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml index e49f2ecdc0..a4b196643c 100644 --- a/quickstep/AndroidManifest.xml +++ b/quickstep/AndroidManifest.xml @@ -17,97 +17,91 @@ ** limitations under the License. */ --> - - + + - - - + + + - + - + - + + android:excludeFromRecents="true" + android:launchMode="singleTask" + android:clearTaskOnLaunch="true" + android:stateNotNeeded="true" + android:theme="@style/LauncherTheme" + android:screenOrientation="unspecified" + android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize" + android:resizeableActivity="true" + android:resumeWhilePausing="true" + android:taskAffinity=""/> - + - + - - + + - + - + - + - - + + @@ -39,6 +40,7 @@ @@ -49,6 +51,7 @@ @@ -58,12 +61,14 @@ + android:name="com.android.launcher3.testcomponent.WidgetConfigActivity" + android:exported="true"> - + @@ -72,6 +77,7 @@ @@ -102,6 +108,7 @@ android:stateNotNeeded="true" android:taskAffinity="" android:theme="@android:style/Theme.DeviceDefault.Light" + android:exported="true" android:windowSoftInputMode="adjustPan"> @@ -114,6 +121,7 @@ @@ -128,6 +136,7 @@ @@ -136,6 +145,7 @@ @@ -144,6 +154,7 @@ @@ -152,6 +163,7 @@ @@ -160,6 +172,7 @@ @@ -168,6 +181,7 @@ @@ -176,6 +190,7 @@ @@ -184,6 +199,7 @@ @@ -192,6 +208,7 @@ @@ -200,6 +217,7 @@ diff --git a/tests/dummy_app/AndroidManifest.xml b/tests/dummy_app/AndroidManifest.xml index f00138c78e..d5e2320b70 100644 --- a/tests/dummy_app/AndroidManifest.xml +++ b/tests/dummy_app/AndroidManifest.xml @@ -26,6 +26,7 @@ From 6fc3648e895782db0ca9b14f83f937635931c0e4 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 23 Jun 2020 13:33:03 -0700 Subject: [PATCH 003/160] Fix map initial capcity. Change-Id: I69f9dc2310435ba23d9a12cc8a5ef1037b43bb2b --- src/com/android/launcher3/util/OnboardingPrefs.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/util/OnboardingPrefs.java b/src/com/android/launcher3/util/OnboardingPrefs.java index d4e074c897..26313e5a21 100644 --- a/src/com/android/launcher3/util/OnboardingPrefs.java +++ b/src/com/android/launcher3/util/OnboardingPrefs.java @@ -64,7 +64,7 @@ public class OnboardingPrefs { private static final Map MAX_COUNTS; static { - Map maxCounts = new ArrayMap<>(3); + Map maxCounts = new ArrayMap<>(4); maxCounts.put(HOME_BOUNCE_COUNT, 3); maxCounts.put(SHELF_BOUNCE_COUNT, 3); maxCounts.put(ALL_APPS_COUNT, 5); From b6354114bade2c25b0bd8b943ac7ef60e7f9e8a4 Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Date: Tue, 23 Jun 2020 10:17:51 -0700 Subject: [PATCH 004/160] Add explicit android:exported="true" declarations We add this for GestureSandboxActivity and com.android.launcher3.uioverrides.QuickstepLauncher to reinstate the behavior of go/ag/11746107 which was incorrectly reverted in go/ag/11963698. We also add this for HotseatEduActivity which was newly added in go/ag/11963698. (Cherry pick from master cadb94983be5ab558202041a053eb4b67ccf3c01) Bug: 159709775 Fixes: 159709775 Test: wembley-userdebug boots and has functioning Launcher Change-Id: I17904f9ad88abc66364675426545eae423cb3175 Merged-In: I17904f9ad88abc66364675426545eae423cb3175 --- quickstep/AndroidManifest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml index a4b196643c..4e7c3fa75b 100644 --- a/quickstep/AndroidManifest.xml +++ b/quickstep/AndroidManifest.xml @@ -110,7 +110,8 @@ android:noHistory="true" android:launchMode="singleTask" android:clearTaskOnLaunch="true" - android:permission="${packageName}.permission.HOTSEAT_EDU"> + android:permission="${packageName}.permission.HOTSEAT_EDU" + android:exported="true"> From 7776d306090b0cc88c4a604ee7d6f7359f250112 Mon Sep 17 00:00:00 2001 From: Sreyas Date: Tue, 23 Jun 2020 15:34:50 -0700 Subject: [PATCH 005/160] Fixing TaskMenu positioning. Bug: 159728554 Change-Id: I4a666363f092b5416edecd0731a0f448916c8def --- .../src/com/android/quickstep/views/TaskMenuView.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java index 512bbac6bb..ef66b7a396 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java @@ -235,7 +235,8 @@ public class TaskMenuView extends AbstractFloatingView { Rect insets = mActivity.getDragLayer().getInsets(); BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams(); params.width = orientationHandler.getTaskMenuWidth(taskView.getThumbnail()); - params.gravity = Gravity.START; + // Gravity set to Left instead of Start as sTempRect.left measures Left distance not Start + params.gravity = Gravity.LEFT; setLayoutParams(params); setScaleX(taskView.getScaleX()); setScaleY(taskView.getScaleY()); From 88f1f2046cecb83cafb94e94cc356cf02c3b7890 Mon Sep 17 00:00:00 2001 From: Sreyas Date: Tue, 23 Jun 2020 16:31:34 -0700 Subject: [PATCH 006/160] Fixing NPE befre ActionsView first initialized. Bug: 159728260 Change-Id: I00e6f8fccf8057495f77873f2f0a1ab01e63ed23 --- .../src/com/android/quickstep/TaskOverlayFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java index 01936e4ac7..e9614d1351 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java @@ -148,7 +148,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride { boolean rotated) { final boolean isAllowedByPolicy = thumbnail.isRealSnapshot; - mActionsView.updateDisabledFlags(DISABLED_ROTATED, rotated); + getActionsView().updateDisabledFlags(DISABLED_ROTATED, rotated); getActionsView().setCallbacks(new OverlayUICallbacks() { @Override From 8995590e444d02746bb580ff4aef7ddf0b3ee3da Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Tue, 23 Jun 2020 16:52:04 +0800 Subject: [PATCH 007/160] Use isolated display context to get display info While display is in landscape, and the launcher is transformed to portrait, the display rotation from activity or application context will get the rotation in portrait. In order to transform the input event when the orientations are different, the actual device rotation is still needed. By creating the display context from application context, the resources of the new context won't be affected by the activity/application level display info adjustments. That provides the actual device states. Additionally, DefaultDisplay#INSTANCE should only be used for the operations related to physical orientation/size because it won't contain the override information from activity. Bug: 157456493 Test: Use a device which may switch refresh rate. Open Maps and put device in landscape. Use gesture navigation to swipe up. The direction of movement should be consistent with UI. Change-Id: I03108b1ab057e28727b6a6db3629d2c1c069e828 --- .../launcher3/util/DefaultDisplay.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/com/android/launcher3/util/DefaultDisplay.java b/src/com/android/launcher3/util/DefaultDisplay.java index 150fb5b043..35788a54c8 100644 --- a/src/com/android/launcher3/util/DefaultDisplay.java +++ b/src/com/android/launcher3/util/DefaultDisplay.java @@ -49,20 +49,25 @@ public class DefaultDisplay implements DisplayListener { public static final int CHANGE_ALL = CHANGE_SIZE | CHANGE_ROTATION | CHANGE_FRAME_DELAY; - private final Context mContext; + private final Context mDisplayContext; private final int mId; private final ArrayList mListeners = new ArrayList<>(); private final Handler mChangeHandler; private Info mInfo; private DefaultDisplay(Context context) { - mContext = context; - mInfo = new Info(context); + DisplayManager dm = context.getSystemService(DisplayManager.class); + // Use application context to create display context so that it can have its own Resources. + mDisplayContext = context.getApplicationContext().createDisplayContext( + dm.getDisplay(DEFAULT_DISPLAY)); + // Note that the Display object must be obtained from DisplayManager which is associated to + // the display context, so the Display is isolated from Activity and Application to provide + // the actual state of device that excludes the additional adjustment and override. + mInfo = new Info(mDisplayContext); mId = mInfo.id; mChangeHandler = new Handler(this::onChange); - context.getSystemService(DisplayManager.class) - .registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler()); + dm.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler()); } @Override @@ -78,7 +83,7 @@ public class DefaultDisplay implements DisplayListener { } Info oldInfo = mInfo; - Info info = new Info(mContext); + Info info = new Info(mDisplayContext); int change = 0; if (info.hasDifferentSize(oldInfo)) { @@ -162,8 +167,7 @@ public class DefaultDisplay implements DisplayListener { display.getRealSize(realSize); display.getCurrentSizeRange(smallestSize, largestSize); - Context defaultDisplayContext = context.createDisplayContext(display); - metrics = defaultDisplayContext.getResources().getDisplayMetrics(); + metrics = context.getResources().getDisplayMetrics(); } private boolean hasDifferentSize(Info info) { From 2bbce930cb2630f04e096d4c1261f427443f23fb Mon Sep 17 00:00:00 2001 From: Sreyas Date: Tue, 23 Jun 2020 16:31:34 -0700 Subject: [PATCH 008/160] Fixing NPE befre ActionsView first initialized. Bug: 159728260 Change-Id: I00e6f8fccf8057495f77873f2f0a1ab01e63ed23 (cherry picked from commit 88f1f2046cecb83cafb94e94cc356cf02c3b7890) --- .../src/com/android/quickstep/TaskOverlayFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java index 01936e4ac7..e9614d1351 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java @@ -148,7 +148,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride { boolean rotated) { final boolean isAllowedByPolicy = thumbnail.isRealSnapshot; - mActionsView.updateDisabledFlags(DISABLED_ROTATED, rotated); + getActionsView().updateDisabledFlags(DISABLED_ROTATED, rotated); getActionsView().setCallbacks(new OverlayUICallbacks() { @Override From c6a56ef7a295b5421ad9531cfc6addc1581e67e6 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Wed, 24 Jun 2020 11:59:10 -0700 Subject: [PATCH 009/160] Pass isLikelyToStartNewTask to onGestureStarted() This ensures we immediately setRecentsAttachedToAppWindow(). As mentioned in the bug, there was an edge case where we would animate the attached state if the first move event passed the touch slop, causing the adjacent task view to lag behind during the gesture. Fixes: 159742520 Change-Id: Ie47bb84fdd3dbd69e3b74ca504d487fb9aedb551 --- .../android/quickstep/BaseSwipeUpHandler.java | 2 +- .../quickstep/BaseSwipeUpHandlerV2.java | 9 ++++++-- .../OtherActivityInputConsumer.java | 23 +++++++++---------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index 02bae64274..a63f3a802f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -327,7 +327,7 @@ public abstract class BaseSwipeUpHandler, Q extend public abstract void onMotionPauseChanged(boolean isPaused); @UiThread - public void onGestureStarted() { } + public void onGestureStarted(boolean isLikelyToStartNewTask) { } @UiThread public abstract void onGestureCancelled(); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java index 413a81379a..37aa0dadd2 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java @@ -492,9 +492,13 @@ public abstract class BaseSwipeUpHandlerV2, Q exte @Override public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { + setIsLikelyToStartNewTask(isLikelyToStartNewTask, true /* animate */); + } + + private void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask, boolean animate) { if (mIsLikelyToStartNewTask != isLikelyToStartNewTask) { mIsLikelyToStartNewTask = isLikelyToStartNewTask; - maybeUpdateRecentsAttachedState(); + maybeUpdateRecentsAttachedState(animate); } } @@ -628,8 +632,9 @@ public abstract class BaseSwipeUpHandlerV2, Q exte } @Override - public void onGestureStarted() { + public void onGestureStarted(boolean isLikelyToStartNewTask) { notifyGestureStartedAsync(); + setIsLikelyToStartNewTask(isLikelyToStartNewTask, false /* animate */); mStateCallback.setStateOnUiThread(STATE_GESTURE_STARTED); mGestureStarted = true; } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index 4e967cfd10..26df9c7b93 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -277,6 +277,13 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC if (!mPassedSlopOnThisGesture && passedSlop) { mPassedSlopOnThisGesture = true; } + // Until passing slop, we don't know what direction we're going, so assume + // we're quick switching to avoid translating recents away when continuing + // the gesture (in which case mPassedPilferInputSlop starts as true). + boolean haveNotPassedSlopOnContinuedGesture = + !mPassedSlopOnThisGesture && mPassedPilferInputSlop; + boolean isLikelyToStartNewTask = haveNotPassedSlopOnContinuedGesture + || horizontalDist > upDist; if (!mPassedPilferInputSlop) { if (passedSlop) { @@ -299,7 +306,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mStartDisplacement = Math.min(displacement, -mTouchSlop); } - notifyGestureStarted(); + notifyGestureStarted(isLikelyToStartNewTask); } } @@ -310,13 +317,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } if (mDeviceState.isFullyGesturalNavMode()) { - // Until passing slop, we don't know what direction we're going, so assume - // we're quick switching to avoid translating recents away when continuing - // the gesture. - boolean haveNotPassedSlopOnContinuedGesture = - !mPassedSlopOnThisGesture && mPassedPilferInputSlop; - boolean isLikelyToStartNewTask = haveNotPassedSlopOnContinuedGesture - || horizontalDist > upDist; mMotionPauseDetector.setDisallowPause(upDist < mMotionPauseMinDisplacement || isLikelyToStartNewTask); mMotionPauseDetector.addPosition(ev); @@ -340,7 +340,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } } - private void notifyGestureStarted() { + private void notifyGestureStarted(boolean isLikelyToStartNewTask) { ActiveGestureLog.INSTANCE.addLog("startQuickstep"); if (mInteractionHandler == null) { return; @@ -353,7 +353,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC CLOSE_SYSTEM_WINDOWS_REASON_RECENTS); // Notify the handler that the gesture has actually started - mInteractionHandler.onGestureStarted(); + mInteractionHandler.onGestureStarted(isLikelyToStartNewTask); } private void startTouchTrackingForWindowAnimation(long touchTimeMs) { @@ -370,8 +370,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mActiveCallbacks = mTaskAnimationManager.continueRecentsAnimation(mGestureState); mActiveCallbacks.addListener(mInteractionHandler); mTaskAnimationManager.notifyRecentsAnimationState(mInteractionHandler); - mInteractionHandler.setIsLikelyToStartNewTask(true); - notifyGestureStarted(); + notifyGestureStarted(true /*isLikelyToStartNewTask*/); } else { intent.putExtra(INTENT_EXTRA_LOG_TRACE_ID, mGestureState.getGestureId()); mActiveCallbacks = mTaskAnimationManager.startRecentsAnimation(mGestureState, intent, From 4b531b972df78f6273e4de343c06117eea550b71 Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Wed, 24 Jun 2020 20:47:51 +0000 Subject: [PATCH 010/160] Updates Assistant gesture regions when no longer tracking multiple. This should prevent states where Assistant triggers from the vertical-center of the screen in portrait (see bug). Also fleshes out OrientationTouchTransformerTests and adds some new ones that fail without this change: - enableMultipleRegions_assistantTriggersInMostRecent - enableMultipleRegions_assistantTriggersInCurrentOrientationAfterDisable Fixes: 158686674 Change-Id: I6d045a485f62e4010e9e3d00805a50fdd953a2fc --- .../OrientationTouchTransformerTest.java | 153 +++++++++++++----- .../OrientationTouchTransformer.java | 42 +++-- 2 files changed, 142 insertions(+), 53 deletions(-) diff --git a/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java index 53f37c15bb..22d205a7cd 100644 --- a/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java +++ b/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java @@ -59,6 +59,7 @@ public class OrientationTouchTransformerTest { mResources = mock(Resources.class); when(mResources.getBoolean(anyInt())).thenReturn(true); when(mResources.getDimension(anyInt())).thenReturn(10.0f); + when(mResources.getDimensionPixelSize(anyInt())).thenReturn(10); DisplayMetrics mockDisplayMetrics = new DisplayMetrics(); mockDisplayMetrics.density = DENSITY_DISPLAY_METRICS; when(mResources.getDisplayMetrics()).thenReturn(mockDisplayMetrics); @@ -67,53 +68,114 @@ public class OrientationTouchTransformerTest { } @Test - public void disabledMultipeRegions_shouldOverrideFirstRegion() { - mTouchTransformer.createOrAddTouchRegion(mInfo); - DefaultDisplay.Info info2 = createDisplayInfo(Surface.ROTATION_90); - mTouchTransformer.createOrAddTouchRegion(info2); + public void disabledMultipleRegions_shouldOverrideFirstRegion() { + float portraitRegionY = generateTouchRegionHeight(Surface.ROTATION_0) + 1; + float landscapeRegionY = generateTouchRegionHeight(Surface.ROTATION_90) + 1; - float y = generateTouchRegionHeight(Surface.ROTATION_0) + 1; - MotionEvent inOldRegion = generateMotionEvent(MotionEvent.ACTION_DOWN, 100, y); - mTouchTransformer.transform(inOldRegion); - assertFalse(mTouchTransformer.touchInValidSwipeRegions(inOldRegion.getX(), inOldRegion.getY())); + mTouchTransformer.createOrAddTouchRegion(mInfo); + tapAndAssertTrue(100, portraitRegionY, + event -> mTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY())); + tapAndAssertFalse(100, landscapeRegionY, + event -> mTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY())); + tapAndAssertTrue(0, portraitRegionY, + event -> mTouchTransformer.touchInAssistantRegion(event)); + tapAndAssertFalse(0, landscapeRegionY, + event -> mTouchTransformer.touchInAssistantRegion(event)); // Override region + mTouchTransformer.createOrAddTouchRegion(createDisplayInfo(Surface.ROTATION_90)); + tapAndAssertFalse(100, portraitRegionY, + event -> mTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY())); + tapAndAssertTrue(100, landscapeRegionY, + event -> mTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY())); + tapAndAssertFalse(0, portraitRegionY, + event -> mTouchTransformer.touchInAssistantRegion(event)); + tapAndAssertTrue(0, landscapeRegionY, + event -> mTouchTransformer.touchInAssistantRegion(event)); + + // Override region again mTouchTransformer.createOrAddTouchRegion(mInfo); - inOldRegion = generateMotionEvent(MotionEvent.ACTION_DOWN, 100, y); - mTouchTransformer.transform(inOldRegion); - assertTrue(mTouchTransformer.touchInValidSwipeRegions(inOldRegion.getX(), inOldRegion.getY())); + tapAndAssertTrue(100, portraitRegionY, + event -> mTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY())); + tapAndAssertFalse(100, landscapeRegionY, + event -> mTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY())); + tapAndAssertTrue(0, portraitRegionY, + event -> mTouchTransformer.touchInAssistantRegion(event)); + tapAndAssertFalse(0, landscapeRegionY, + event -> mTouchTransformer.touchInAssistantRegion(event)); } @Test - public void allowMultipeRegions_shouldOverrideFirstRegion() { - DefaultDisplay.Info info2 = createDisplayInfo(Surface.ROTATION_90); - mTouchTransformer.createOrAddTouchRegion(info2); + public void enableMultipleRegions_shouldOverrideFirstRegion() { + float portraitRegionY = generateTouchRegionHeight(Surface.ROTATION_0) + 1; + float landscapeRegionY = generateTouchRegionHeight(Surface.ROTATION_90) + 1; + + mTouchTransformer.createOrAddTouchRegion(createDisplayInfo(Surface.ROTATION_90)); + tapAndAssertFalse(100, portraitRegionY, + event -> mTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY())); + tapAndAssertTrue(100, landscapeRegionY, + event -> mTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY())); + tapAndAssertFalse(0, portraitRegionY, + event -> mTouchTransformer.touchInAssistantRegion(event)); + tapAndAssertTrue(0, landscapeRegionY, + event -> mTouchTransformer.touchInAssistantRegion(event)); // We have to add 0 rotation second so that gets set as the current rotation, otherwise // matrix transform will fail (tests only work in Portrait at the moment) mTouchTransformer.enableMultipleRegions(true, mInfo); mTouchTransformer.createOrAddTouchRegion(mInfo); - float y = generateTouchRegionHeight(Surface.ROTATION_0) + 1; - MotionEvent inNewRegion = generateMotionEvent(MotionEvent.ACTION_DOWN, 100, y); - mTouchTransformer.transform(inNewRegion); - assertTrue(mTouchTransformer.touchInValidSwipeRegions(inNewRegion.getX(), inNewRegion.getY())); + tapAndAssertTrue(100, portraitRegionY, + event -> mTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY())); + tapAndAssertFalse(100, landscapeRegionY, + event -> mTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY())); + tapAndAssertTrue(0, portraitRegionY, + event -> mTouchTransformer.touchInAssistantRegion(event)); + tapAndAssertFalse(0, landscapeRegionY, + event -> mTouchTransformer.touchInAssistantRegion(event)); + } + + @Test + public void enableMultipleRegions_assistantTriggersInMostRecent() { + float portraitRegionY = generateTouchRegionHeight(Surface.ROTATION_0) + 1; + float landscapeRegionY = generateTouchRegionHeight(Surface.ROTATION_90) + 1; + + mTouchTransformer.enableMultipleRegions(true, mInfo); + mTouchTransformer.createOrAddTouchRegion(createDisplayInfo(Surface.ROTATION_90)); + mTouchTransformer.createOrAddTouchRegion(mInfo); + tapAndAssertTrue(0, portraitRegionY, + event -> mTouchTransformer.touchInAssistantRegion(event)); + tapAndAssertFalse(0, landscapeRegionY, + event -> mTouchTransformer.touchInAssistantRegion(event)); + } + + @Test + public void enableMultipleRegions_assistantTriggersInCurrentOrientationAfterDisable() { + float portraitRegionY = generateTouchRegionHeight(Surface.ROTATION_0) + 1; + float landscapeRegionY = generateTouchRegionHeight(Surface.ROTATION_90) + 1; + + mTouchTransformer.enableMultipleRegions(true, mInfo); + mTouchTransformer.createOrAddTouchRegion(mInfo); + mTouchTransformer.createOrAddTouchRegion(createDisplayInfo(Surface.ROTATION_90)); + mTouchTransformer.enableMultipleRegions(false, mInfo); + tapAndAssertTrue(0, portraitRegionY, + event -> mTouchTransformer.touchInAssistantRegion(event)); + tapAndAssertFalse(0, landscapeRegionY, + event -> mTouchTransformer.touchInAssistantRegion(event)); } @Test public void applyTransform_taskNotFrozen_notInRegion() { mTouchTransformer.createOrAddTouchRegion(mInfo); - MotionEvent outOfRegion = generateMotionEvent(MotionEvent.ACTION_DOWN, 100, 100); - mTouchTransformer.transform(outOfRegion); - assertFalse(mTouchTransformer.touchInValidSwipeRegions(outOfRegion.getX(), outOfRegion.getY())); + tapAndAssertFalse(100, 100, + event -> mTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY())); } @Test public void applyTransform_taskFrozen_noRotate_outOfRegion() { mTouchTransformer.createOrAddTouchRegion(mInfo); mTouchTransformer.enableMultipleRegions(true, mInfo); - MotionEvent outOfRegion = generateMotionEvent(MotionEvent.ACTION_DOWN, 100, 100); - mTouchTransformer.transform(outOfRegion); - assertFalse(mTouchTransformer.touchInValidSwipeRegions(outOfRegion.getX(), outOfRegion.getY())); + tapAndAssertFalse(100, 100, + event -> mTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY())); } @Test @@ -121,27 +183,24 @@ public class OrientationTouchTransformerTest { mTouchTransformer.createOrAddTouchRegion(mInfo); mTouchTransformer.enableMultipleRegions(true, mInfo); float y = generateTouchRegionHeight(Surface.ROTATION_0) + 1; - MotionEvent inRegion = generateMotionEvent(MotionEvent.ACTION_DOWN, 100, y); - mTouchTransformer.transform(inRegion); - assertTrue(mTouchTransformer.touchInValidSwipeRegions(inRegion.getX(), inRegion.getY())); + tapAndAssertTrue(100, y, + event -> mTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY())); } @Test public void applyTransform_taskNotFrozen_noRotate_inDefaultRegion() { mTouchTransformer.createOrAddTouchRegion(mInfo); float y = generateTouchRegionHeight(Surface.ROTATION_0) + 1; - MotionEvent inRegion = generateMotionEvent(MotionEvent.ACTION_DOWN, 100, y); - mTouchTransformer.transform(inRegion); - assertTrue(mTouchTransformer.touchInValidSwipeRegions(inRegion.getX(), inRegion.getY())); + tapAndAssertTrue(100, y, + event -> mTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY())); } @Test public void applyTransform_taskNotFrozen_90Rotate_inRegion() { mTouchTransformer.createOrAddTouchRegion(createDisplayInfo(Surface.ROTATION_90)); float y = generateTouchRegionHeight(Surface.ROTATION_90) + 1; - MotionEvent inRegion = generateMotionEvent(MotionEvent.ACTION_DOWN, 100, y); - mTouchTransformer.transform(inRegion); - assertTrue(mTouchTransformer.touchInValidSwipeRegions(inRegion.getX(), inRegion.getY())); + tapAndAssertTrue(100, y, + event -> mTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY())); } @Test @@ -160,15 +219,15 @@ public class OrientationTouchTransformerTest { MotionEvent inRegion2 = generateMotionEvent(MotionEvent.ACTION_DOWN, 10, 10); mTouchTransformer.transform(inRegion1_down); mTouchTransformer.transform(inRegion2); - assertTrue(mTouchTransformer.touchInValidSwipeRegions(inRegion1_down.getX(), inRegion1_down.getY())); + assertTrue(mTouchTransformer.touchInValidSwipeRegions( + inRegion1_down.getX(), inRegion1_down.getY())); // We only process one gesture region until we see a MotionEvent.ACTION_UP assertFalse(mTouchTransformer.touchInValidSwipeRegions(inRegion2.getX(), inRegion2.getY())); mTouchTransformer.transform(inRegion1_up); // Set the new region with this MotionEvent.ACTION_DOWN - inRegion2 = generateMotionEvent(MotionEvent.ACTION_DOWN, 10, 370); - mTouchTransformer.transform(inRegion2); + inRegion2 = generateAndTransformMotionEvent(MotionEvent.ACTION_DOWN, 10, 370); assertTrue(mTouchTransformer.touchInValidSwipeRegions(inRegion2.getX(), inRegion2.getY())); } @@ -191,4 +250,26 @@ public class OrientationTouchTransformerTest { private MotionEvent generateMotionEvent(int motionAction, float x, float y) { return MotionEvent.obtain(0, 0, motionAction, x, y, 0); } + + private MotionEvent generateAndTransformMotionEvent(int motionAction, float x, float y) { + MotionEvent motionEvent = generateMotionEvent(motionAction, x, y); + mTouchTransformer.transform(motionEvent); + return motionEvent; + } + + private void tapAndAssertTrue(float x, float y, MotionEventAssertion assertion) { + MotionEvent motionEvent = generateAndTransformMotionEvent(MotionEvent.ACTION_DOWN, x, y); + assertTrue(assertion.getCondition(motionEvent)); + generateAndTransformMotionEvent(MotionEvent.ACTION_UP, x, y); + } + + private void tapAndAssertFalse(float x, float y, MotionEventAssertion assertion) { + MotionEvent motionEvent = generateAndTransformMotionEvent(MotionEvent.ACTION_DOWN, x, y); + assertFalse(assertion.getCondition(motionEvent)); + generateAndTransformMotionEvent(MotionEvent.ACTION_UP, x, y); + } + + private interface MotionEventAssertion { + boolean getCondition(MotionEvent motionEvent); + } } diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java index 3375c53124..b091807c78 100644 --- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java +++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java @@ -178,15 +178,21 @@ class OrientationTouchTransformer { mCurrentDisplayRotation = region.rotation; OrientationRectF regionToKeep = mSwipeTouchRegions.get(mCurrentDisplayRotation); + if (regionToKeep == null) { + regionToKeep = createRegionForDisplay(region); + } mSwipeTouchRegions.clear(); - mSwipeTouchRegions.put(mCurrentDisplayRotation, - regionToKeep != null ? regionToKeep : createRegionForDisplay(region)); + mSwipeTouchRegions.put(mCurrentDisplayRotation, regionToKeep); + updateAssistantRegions(regionToKeep); } private void resetSwipeRegions() { OrientationRectF regionToKeep = mSwipeTouchRegions.get(mCurrentDisplayRotation); mSwipeTouchRegions.clear(); - mSwipeTouchRegions.put(mCurrentDisplayRotation, regionToKeep); + if (regionToKeep != null) { + mSwipeTouchRegions.put(mCurrentDisplayRotation, regionToKeep); + updateAssistantRegions(regionToKeep); + } } private OrientationRectF createRegionForDisplay(DefaultDisplay.Info display) { @@ -201,20 +207,7 @@ class OrientationTouchTransformer { if (mMode == SysUINavigationMode.Mode.NO_BUTTON) { int touchHeight = getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE); orientationRectF.top = orientationRectF.bottom - touchHeight; - - final int assistantWidth = mResources - .getDimensionPixelSize(R.dimen.gestures_assistant_width); - final float assistantHeight = Math.max(touchHeight, - mContractInfo.getWindowCornerRadius()); - mAssistantLeftRegion.bottom = mAssistantRightRegion.bottom = orientationRectF.bottom; - mAssistantLeftRegion.top = mAssistantRightRegion.top = - orientationRectF.bottom - assistantHeight; - - mAssistantLeftRegion.left = 0; - mAssistantLeftRegion.right = assistantWidth; - - mAssistantRightRegion.right = orientationRectF.right; - mAssistantRightRegion.left = orientationRectF.right - assistantWidth; + updateAssistantRegions(orientationRectF); } else { mAssistantLeftRegion.setEmpty(); mAssistantRightRegion.setEmpty(); @@ -236,6 +229,21 @@ class OrientationTouchTransformer { return orientationRectF; } + private void updateAssistantRegions(OrientationRectF orientationRectF) { + int navbarHeight = getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE); + int assistantWidth = mResources.getDimensionPixelSize(R.dimen.gestures_assistant_width); + float assistantHeight = Math.max(navbarHeight, mContractInfo.getWindowCornerRadius()); + mAssistantLeftRegion.bottom = mAssistantRightRegion.bottom = orientationRectF.bottom; + mAssistantLeftRegion.top = mAssistantRightRegion.top = + orientationRectF.bottom - assistantHeight; + + mAssistantLeftRegion.left = 0; + mAssistantLeftRegion.right = assistantWidth; + + mAssistantRightRegion.right = orientationRectF.right; + mAssistantRightRegion.left = orientationRectF.right - assistantWidth; + } + boolean touchInAssistantRegion(MotionEvent ev) { return mAssistantLeftRegion.contains(ev.getX(), ev.getY()) || mAssistantRightRegion.contains(ev.getX(), ev.getY()); From fb099c7fe167752f9a921e99cf7eae2afc609538 Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 23 Jun 2020 18:49:41 -0700 Subject: [PATCH 011/160] Improving diagnostics when can't find a widget Instead of "exceeded number of attempts" now printing that can't scroll to widget. Change-Id: Ia6f582e038d68fc35f152d94e592f60ef0bc2cf4 --- .../launcher3/testing/TestInformationHandler.java | 6 ++++++ src/com/android/launcher3/testing/TestProtocol.java | 1 + tests/tapl/com/android/launcher3/tapl/Widgets.java | 13 +++++++++++++ 3 files changed, 20 insertions(+) diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java index 38b3712f6e..d4a132e5ba 100644 --- a/src/com/android/launcher3/testing/TestInformationHandler.java +++ b/src/com/android/launcher3/testing/TestInformationHandler.java @@ -33,6 +33,7 @@ import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherState; import com.android.launcher3.R; import com.android.launcher3.util.ResourceBasedOverride; +import com.android.launcher3.widget.WidgetsFullSheet; import java.util.concurrent.ExecutionException; import java.util.function.Function; @@ -92,6 +93,11 @@ public class TestInformationHandler implements ResourceBasedOverride { l -> l.getAppsView().getActiveRecyclerView().getCurrentScrollY()); } + case TestProtocol.REQUEST_WIDGETS_SCROLL_Y: { + return getLauncherUIProperty(Bundle::putInt, + l -> WidgetsFullSheet.getWidgetsView(l).getCurrentScrollY()); + } + case TestProtocol.REQUEST_WINDOW_INSETS: { return getUIProperty(Bundle::putParcelable, a -> { WindowInsets insets = a.getWindow() diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index 3ca08fd8ec..8165627448 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -81,6 +81,7 @@ public final class TestProtocol { public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list"; public static final String REQUEST_APP_LIST_FREEZE_FLAGS = "app-list-freeze-flags"; public static final String REQUEST_APPS_LIST_SCROLL_Y = "apps-list-scroll-y"; + public static final String REQUEST_WIDGETS_SCROLL_Y = "widgets-scroll-y"; public static final String REQUEST_WINDOW_INSETS = "window-insets"; public static final String REQUEST_PID = "pid"; public static final String REQUEST_TOTAL_PSS_KB = "total_pss"; diff --git a/tests/tapl/com/android/launcher3/tapl/Widgets.java b/tests/tapl/com/android/launcher3/tapl/Widgets.java index 39ac6454b0..49af616b85 100644 --- a/tests/tapl/com/android/launcher3/tapl/Widgets.java +++ b/tests/tapl/com/android/launcher3/tapl/Widgets.java @@ -28,6 +28,7 @@ import androidx.test.uiautomator.UiObject2; import androidx.test.uiautomator.Until; import com.android.launcher3.tapl.LauncherInstrumentation.GestureScope; +import com.android.launcher3.testing.TestProtocol; import java.util.Collection; @@ -90,6 +91,12 @@ public final class Widgets extends LauncherInstrumentation.VisibleContainer { return LauncherInstrumentation.ContainerType.WIDGETS; } + private int getWidgetsScroll() { + return mLauncher.getTestInfo( + TestProtocol.REQUEST_WIDGETS_SCROLL_Y) + .getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD); + } + public Widget getWidget(String labelText) { try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck(); LauncherInstrumentation.Closable c = mLauncher.addContextLayer( @@ -136,7 +143,13 @@ public final class Widgets extends LauncherInstrumentation.VisibleContainer { } mLauncher.assertTrue("Too many attempts", ++i <= 40); + final int scroll = getWidgetsScroll(); mLauncher.scrollToLastVisibleRow(widgetsContainer, cells, 0); + final int newScroll = getWidgetsScroll(); + mLauncher.assertTrue( + "Scrolled in a wrong direction in Widgets: from " + scroll + " to " + + newScroll, newScroll >= scroll); + mLauncher.assertTrue("Unable to scroll to the widget", newScroll != scroll); } } } From dfa3de7d3f477381371ad1abbea9a40098dbd1de Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Wed, 24 Jun 2020 17:37:16 -0700 Subject: [PATCH 012/160] Get rid of a weird shadow background when rendering smartspace in preview I think it has something to do ripple background, clipChildren, focusable, clickable, etc. My previous projects ran into related issues before, which is why I tried to set focusable here to false. Let me know if you have a better idea of what exactly is going on FYI, I also did go back to my previous CL and confirmed that it's necessary. Fixes: 152278370 Test: Factory reset the phone (with latest build and launcher built from this CL). Make sure no background is shown Change-Id: I401ffcccd1e07a3c0beb5ed460a707d25bddf41e --- res/layout/launcher_preview_layout.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/res/layout/launcher_preview_layout.xml b/res/layout/launcher_preview_layout.xml index 3fd02e3fda..4a20c705b6 100644 --- a/res/layout/launcher_preview_layout.xml +++ b/res/layout/launcher_preview_layout.xml @@ -17,7 +17,8 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:launcher="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:focusable="false"> Date: Wed, 24 Jun 2020 20:52:26 -0700 Subject: [PATCH 013/160] Fix tracking window being slightly off when swiping from an app Test: swipe up from an app in landscape, seascape, and portrait, and verify the window tracks with the finger 1:1 until pullback Bug: 149934536 Change-Id: Ia469877e7152c8135e0b9153f69c191ba86cbd14 --- quickstep/src/com/android/quickstep/util/LayoutUtils.java | 2 +- .../launcher3/touch/LandscapePagedViewHandler.java | 8 ++++++++ .../android/launcher3/touch/PagedOrientationHandler.java | 1 + .../android/launcher3/touch/PortraitPagedViewHandler.java | 6 ++++++ .../android/launcher3/touch/SeascapePagedViewHandler.java | 7 +++++++ 5 files changed, 23 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java index ae19d73719..f7bd1e29d8 100644 --- a/quickstep/src/com/android/quickstep/util/LayoutUtils.java +++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java @@ -49,7 +49,7 @@ public class LayoutUtils { Rect taskSize = new Rect(); LauncherActivityInterface.INSTANCE.calculateTaskSize(context, dp, taskSize, orientationHandler); - return (dp.heightPx - taskSize.height()) / 2; + return orientationHandler.getDistanceToBottomOfRect(dp, taskSize); } int shelfHeight = dp.hotseatBarSizePx + dp.getInsets().bottom; int spaceBetweenShelfAndRecents = (int) context.getResources().getDimension( diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java index 48c773413f..c2bfb167a2 100644 --- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java +++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java @@ -17,6 +17,7 @@ package com.android.launcher3.touch; import static android.widget.ListPopupWindow.WRAP_CONTENT; + import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X; import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y; import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL; @@ -33,6 +34,7 @@ import android.view.View; import android.view.accessibility.AccessibilityEvent; import android.widget.LinearLayout; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.PagedView; import com.android.launcher3.Utilities; import com.android.launcher3.util.OverScroller; @@ -260,4 +262,10 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler { } return new ChildBounds(childHeight, childWidth, childBottom, childLeft); } + + @SuppressWarnings("SuspiciousNameCombination") + @Override + public int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect) { + return rect.left; + } } diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java index 65b1a7a77e..b650526fe1 100644 --- a/src/com/android/launcher3/touch/PagedOrientationHandler.java +++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java @@ -96,6 +96,7 @@ public interface PagedOrientationHandler { int getTaskMenuWidth(View view); int getTaskMenuLayoutOrientation(LinearLayout taskMenuLayout); void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp); + int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect); /** * Maps the velocity from the coordinate plane of the foreground app to that diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java index 79e5c87785..e87c887d33 100644 --- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java +++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java @@ -32,6 +32,7 @@ import android.view.View; import android.view.accessibility.AccessibilityEvent; import android.widget.LinearLayout; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.PagedView; import com.android.launcher3.Utilities; import com.android.launcher3.util.OverScroller; @@ -257,4 +258,9 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { } return new ChildBounds(childWidth, childHeight, childRight, childTop); } + + @Override + public int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect) { + return dp.heightPx - rect.bottom; + } } diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java index d5ae2dcb16..e91f16d71a 100644 --- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java +++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java @@ -18,9 +18,11 @@ package com.android.launcher3.touch; import android.content.res.Resources; import android.graphics.PointF; +import android.graphics.Rect; import android.view.Surface; import android.view.View; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.Utilities; public class SeascapePagedViewHandler extends LandscapePagedViewHandler { @@ -77,4 +79,9 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler { view.setTranslationX(0); view.setTranslationY(translation); } + + @Override + public int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect) { + return dp.widthPx - rect.right; + } } From 514df92bcfc592c305fd0079287f6d09653b0340 Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Thu, 25 Jun 2020 11:17:16 -0700 Subject: [PATCH 014/160] Add NPE check for prediction controller Bug: 159835714 Test: Manual Change-Id: I9cc03f6491f4e14462be6c01edf3ed4ca1d82136 --- .../com/android/quickstep/util/QuickstepOnboardingPrefs.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java index 0fdc6841b5..9ed2bbef38 100644 --- a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java +++ b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java @@ -101,7 +101,8 @@ public class QuickstepOnboardingPrefs extends OnboardingPrefs() { boolean mFromAllApps = false; From 633a4bdf5724517509f6d40635cd16f14452e4e8 Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Wed, 24 Jun 2020 12:48:11 -0700 Subject: [PATCH 015/160] Do preview grid migration in a worker thread Also remove USE_SURFACE_VIEW_FOR_PREVIEW flag Fixes: 159755324 Test: manual Change-Id: I6517c34911e217a69063226b01e4583194902f9c --- .../launcher3/config/FeatureFlags.java | 3 - .../graphics/GridOptionsProvider.java | 61 ---------------- .../graphics/LauncherPreviewRenderer.java | 55 ++------------- .../graphics/PreviewSurfaceRenderer.java | 70 ++++++++++++------- 4 files changed, 50 insertions(+), 139 deletions(-) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 4f53d45c73..5c4a4922fd 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -138,9 +138,6 @@ public final class FeatureFlags { public static final BooleanFlag ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER = getDebugFlag( "ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER", true, "Show launcher preview in grid picker"); - public static final BooleanFlag USE_SURFACE_VIEW_FOR_GRID_PREVIEW = getDebugFlag( - "USE_SURFACE_VIEW_FOR_GRID_PREVIEW", true, "Use surface view for grid preview"); - public static final BooleanFlag ENABLE_OVERVIEW_ACTIONS = getDebugFlag( "ENABLE_OVERVIEW_ACTIONS", true, "Show app actions instead of the shelf in Overview." + " As part of this decoupling, also distinguish swipe up from nav bar vs above it."); diff --git a/src/com/android/launcher3/graphics/GridOptionsProvider.java b/src/com/android/launcher3/graphics/GridOptionsProvider.java index 9bfd5bab87..08d7e4c65e 100644 --- a/src/com/android/launcher3/graphics/GridOptionsProvider.java +++ b/src/com/android/launcher3/graphics/GridOptionsProvider.java @@ -1,21 +1,14 @@ package com.android.launcher3.graphics; -import static com.android.launcher3.config.FeatureFlags.USE_SURFACE_VIEW_FOR_GRID_PREVIEW; -import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; - import android.content.ContentProvider; import android.content.ContentValues; import android.content.pm.PackageManager; import android.content.res.XmlResourceParser; import android.database.Cursor; import android.database.MatrixCursor; -import android.graphics.Bitmap; import android.net.Uri; import android.os.Binder; import android.os.Bundle; -import android.os.ParcelFileDescriptor; -import android.os.ParcelFileDescriptor.AutoCloseOutputStream; -import android.text.TextUtils; import android.util.Log; import android.util.Xml; @@ -26,12 +19,10 @@ import com.android.launcher3.R; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.concurrent.Future; /** * Exposes various launcher grid options and allows the caller to change them. @@ -62,24 +53,7 @@ public class GridOptionsProvider extends ContentProvider { private static final String KEY_LIST_OPTIONS = "/list_options"; private static final String KEY_DEFAULT_GRID = "/default_grid"; - private static final String KEY_PREVIEW = "preview"; - private static final String MIME_TYPE_PNG = "image/png"; - private static final String METHOD_GET_PREVIEW = "get_preview"; - private static final String METADATA_KEY_PREVIEW_VERSION = "preview_version"; - - public static final PipeDataWriter> BITMAP_WRITER = - new PipeDataWriter>() { - @Override - public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String s, - Bundle bundle, Future bitmap) { - try (AutoCloseOutputStream os = new AutoCloseOutputStream(output)) { - bitmap.get().compress(Bitmap.CompressFormat.PNG, 100, os); - } catch (Exception e) { - Log.w(TAG, "fail to write to pipe", e); - } - } - }; @Override public boolean onCreate() { @@ -104,10 +78,6 @@ public class GridOptionsProvider extends ContentProvider { .add(KEY_IS_DEFAULT, idp.numColumns == gridOption.numColumns && idp.numRows == gridOption.numRows); } - Bundle metadata = new Bundle(); - metadata.putString(METADATA_KEY_PREVIEW_VERSION, - USE_SURFACE_VIEW_FOR_GRID_PREVIEW.get() ? "V2" : "V1"); - cursor.setExtras(metadata); return cursor; } @@ -132,10 +102,6 @@ public class GridOptionsProvider extends ContentProvider { @Override public String getType(Uri uri) { - List segments = uri.getPathSegments(); - if (segments.size() > 0 && KEY_PREVIEW.equals(segments.get(0))) { - return MIME_TYPE_PNG; - } return "vnd.android.cursor.dir/launcher_grid"; } @@ -172,33 +138,6 @@ public class GridOptionsProvider extends ContentProvider { return 1; } - @Override - public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { - List segments = uri.getPathSegments(); - if (segments.size() < 2 || !KEY_PREVIEW.equals(segments.get(0))) { - throw new FileNotFoundException("Invalid preview url"); - } - String profileName = segments.get(1); - if (TextUtils.isEmpty(profileName)) { - throw new FileNotFoundException("Invalid preview url"); - } - - InvariantDeviceProfile idp; - try { - idp = new InvariantDeviceProfile(getContext(), profileName); - } catch (Exception e) { - throw new FileNotFoundException(e.getMessage()); - } - - try { - return openPipeHelper(uri, MIME_TYPE_PNG, null, - UI_HELPER_EXECUTOR.submit(new LauncherPreviewRenderer(getContext(), idp)), - BITMAP_WRITER); - } catch (Exception e) { - throw new FileNotFoundException(e.getMessage()); - } - } - @Override public Bundle call(String method, String arg, Bundle extras) { if (getContext().checkPermission("android.permission.BIND_WALLPAPER", diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index 15f4e3fcec..885fb6698b 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -20,7 +20,6 @@ import static android.view.View.MeasureSpec.makeMeasureSpec; import static android.view.View.VISIBLE; import static com.android.launcher3.config.FeatureFlags.ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER; -import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_ALGO; import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems; import static com.android.launcher3.model.ModelUtils.getMissingHotseatRanks; import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially; @@ -34,8 +33,6 @@ import android.content.ContextWrapper; import android.content.Intent; import android.content.pm.ShortcutInfo; import android.content.res.TypedArray; -import android.graphics.Bitmap; -import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.AdaptiveIconDrawable; @@ -63,20 +60,16 @@ import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.R; -import com.android.launcher3.Utilities; import com.android.launcher3.WorkspaceLayoutManager; import com.android.launcher3.allapps.SearchUiManager; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.BitmapInfo; -import com.android.launcher3.icons.BitmapRenderer; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.model.AllAppsList; import com.android.launcher3.model.BgDataModel; import com.android.launcher3.model.BgDataModel.Callbacks; -import com.android.launcher3.model.GridSizeMigrationTask; -import com.android.launcher3.model.GridSizeMigrationTaskV2; import com.android.launcher3.model.LoaderResults; import com.android.launcher3.model.LoaderTask; import com.android.launcher3.model.WidgetItem; @@ -105,7 +98,6 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.FutureTask; @@ -121,7 +113,7 @@ import java.util.concurrent.TimeoutException; * 4) Measure and draw the view on a canvas */ @TargetApi(Build.VERSION_CODES.O) -public class LauncherPreviewRenderer implements Callable { +public class LauncherPreviewRenderer { private static final String TAG = "LauncherPreviewRenderer"; @@ -213,15 +205,17 @@ public class LauncherPreviewRenderer implements Callable { private final Context mContext; private final InvariantDeviceProfile mIdp; private final DeviceProfile mDp; + private final boolean mMigrated; private final Rect mInsets; private final WorkspaceItemInfo mWorkspaceItemInfo; - public LauncherPreviewRenderer(Context context, InvariantDeviceProfile idp) { + public LauncherPreviewRenderer(Context context, InvariantDeviceProfile idp, boolean migrated) { mUiHandler = new Handler(Looper.getMainLooper()); mContext = context; mIdp = idp; mDp = idp.portraitProfile.copy(context); + mMigrated = migrated; // TODO: get correct insets once display cutout API is available. mInsets = new Rect(); @@ -243,28 +237,6 @@ public class LauncherPreviewRenderer implements Callable { context.getString(R.string.label_application); } - @Override - public Bitmap call() { - return BitmapRenderer.createHardwareBitmap(mDp.widthPx, mDp.heightPx, c -> { - - if (Looper.myLooper() == Looper.getMainLooper()) { - new MainThreadRenderer(mContext).renderScreenShot(c); - } else { - CountDownLatch latch = new CountDownLatch(1); - Utilities.postAsyncCallback(mUiHandler, () -> { - new MainThreadRenderer(mContext).renderScreenShot(c); - latch.countDown(); - }); - - try { - latch.await(); - } catch (Exception e) { - Log.e(TAG, "Error drawing on main thread", e); - } - } - }); - } - /** Populate preview and render it. */ public View getRenderedView() { MainThreadRenderer renderer = new MainThreadRenderer(mContext); @@ -407,20 +379,9 @@ public class LauncherPreviewRenderer implements Callable { private void populate() { if (ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER.get()) { - boolean needsToMigrate = - MULTI_DB_GRID_MIRATION_ALGO.get() - ? GridSizeMigrationTaskV2.needsToMigrate(mContext, mIdp) - : GridSizeMigrationTask.needsToMigrate(mContext, mIdp); - boolean success = false; - if (needsToMigrate) { - success = MULTI_DB_GRID_MIRATION_ALGO.get() - ? GridSizeMigrationTaskV2.migrateGridIfNeeded(mContext, mIdp) - : GridSizeMigrationTask.migrateGridIfNeeded(mContext, mIdp); - } - WorkspaceFetcher fetcher; PreviewContext previewContext = null; - if (needsToMigrate && success) { + if (mMigrated) { previewContext = new PreviewContext(mContext, mIdp); LauncherAppState appForPreview = new LauncherAppState( previewContext, null /* iconCacheFileName */); @@ -535,12 +496,6 @@ public class LauncherPreviewRenderer implements Callable { // Additional measure for views which use auto text size API measureView(mRootView, mDp.widthPx, mDp.heightPx); } - - private void renderScreenShot(Canvas canvas) { - populate(); - mRootView.draw(canvas); - dispatchVisibilityAggregated(mRootView, false); - } } private static void measureView(View view, int width, int height) { diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java index 350f221c97..fdc3a947a3 100644 --- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java +++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java @@ -16,7 +16,9 @@ package com.android.launcher3.graphics; +import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_ALGO; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import android.content.Context; import android.hardware.display.DisplayManager; @@ -32,6 +34,8 @@ import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import com.android.launcher3.InvariantDeviceProfile; +import com.android.launcher3.model.GridSizeMigrationTask; +import com.android.launcher3.model.GridSizeMigrationTaskV2; import java.util.concurrent.TimeUnit; @@ -93,32 +97,35 @@ public class PreviewSurfaceRenderer implements IBinder.DeathRecipient { return null; } - MAIN_EXECUTOR.execute(() -> { - // If mSurfaceControlViewHost is null due to any reason (e.g. binder died, - // happening when user leaves the preview screen before preview rendering finishes), - // we should return here. - SurfaceControlViewHost host = mSurfaceControlViewHost; - if (host == null) { - return; - } + MODEL_EXECUTOR.post(() -> { + final boolean success = doGridMigrationIfNecessary(); - View view = new LauncherPreviewRenderer(mContext, mIdp).getRenderedView(); - // This aspect scales the view to fit in the surface and centers it - final float scale = Math.min(mWidth / (float) view.getMeasuredWidth(), - mHeight / (float) view.getMeasuredHeight()); - view.setScaleX(scale); - view.setScaleY(scale); - view.setPivotX(0); - view.setPivotY(0); - view.setTranslationX((mWidth - scale * view.getWidth()) / 2); - view.setTranslationY((mHeight - scale * view.getHeight()) / 2); - view.setAlpha(0); - view.animate().alpha(1) - .setInterpolator(new AccelerateDecelerateInterpolator()) - .setDuration(FADE_IN_ANIMATION_DURATION) - .start(); - host.setView(view, view.getMeasuredWidth(), - view.getMeasuredHeight()); + MAIN_EXECUTOR.post(() -> { + // If mSurfaceControlViewHost is null due to any reason (e.g. binder died, + // happening when user leaves the preview screen before preview rendering finishes), + // we should return here. + SurfaceControlViewHost host = mSurfaceControlViewHost; + if (host == null) { + return; + } + + View view = new LauncherPreviewRenderer(mContext, mIdp, success).getRenderedView(); + // This aspect scales the view to fit in the surface and centers it + final float scale = Math.min(mWidth / (float) view.getMeasuredWidth(), + mHeight / (float) view.getMeasuredHeight()); + view.setScaleX(scale); + view.setScaleY(scale); + view.setPivotX(0); + view.setPivotY(0); + view.setTranslationX((mWidth - scale * view.getWidth()) / 2); + view.setTranslationY((mHeight - scale * view.getHeight()) / 2); + view.setAlpha(0); + view.animate().alpha(1) + .setInterpolator(new AccelerateDecelerateInterpolator()) + .setDuration(FADE_IN_ANIMATION_DURATION) + .start(); + host.setView(view, view.getMeasuredWidth(), view.getMeasuredHeight()); + }); }); Bundle result = new Bundle(); @@ -145,4 +152,17 @@ public class PreviewSurfaceRenderer implements IBinder.DeathRecipient { } mHostToken.unlinkToDeath(this, 0); } + + private boolean doGridMigrationIfNecessary() { + boolean needsToMigrate = + MULTI_DB_GRID_MIRATION_ALGO.get() + ? GridSizeMigrationTaskV2.needsToMigrate(mContext, mIdp) + : GridSizeMigrationTask.needsToMigrate(mContext, mIdp); + if (!needsToMigrate) { + return false; + } + return MULTI_DB_GRID_MIRATION_ALGO.get() + ? GridSizeMigrationTaskV2.migrateGridIfNeeded(mContext, mIdp) + : GridSizeMigrationTask.migrateGridIfNeeded(mContext, mIdp); + } } From 56fe9150fa1ff0a4164e1bad02d5384ac912477f Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 25 Jun 2020 13:32:20 -0700 Subject: [PATCH 016/160] Improving diagnostics when Launcher dies during a gesture Instead of crashing upon getting uninitialized event sequence, we show a meaningful message. Bug: 159921830 Change-Id: Ie42039b39a453c60bd5df3e54058d582137bba06 --- .../launcher3/testing/DebugTestInformationHandler.java | 6 ++++++ tests/tapl/com/android/launcher3/tapl/LogEventChecker.java | 3 +++ 2 files changed, 9 insertions(+) diff --git a/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java b/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java index e649ce1de4..aa3710b6d9 100644 --- a/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java +++ b/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java @@ -164,6 +164,12 @@ public class DebugTestInformationHandler extends TestInformationHandler { } case TestProtocol.REQUEST_GET_TEST_EVENTS: { + if (sEvents == null) { + // sEvents can be null if Launcher died and restarted after + // REQUEST_START_EVENT_LOGGING. + return response; + } + synchronized (sEvents) { response.putStringArrayList( TestProtocol.TEST_INFO_RESPONSE_FIELD, new ArrayList<>(sEvents)); diff --git a/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java b/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java index 4440b82976..2edfc53f75 100644 --- a/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java +++ b/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java @@ -57,6 +57,8 @@ public class LogEventChecker { while (true) { rawEvents = mLauncher.getTestInfo(TestProtocol.REQUEST_GET_TEST_EVENTS) .getStringArrayList(TestProtocol.TEST_INFO_RESPONSE_FIELD); + if (rawEvents == null) return null; + final int expectedCount = mExpectedEvents.entrySet() .stream().mapToInt(e -> e.getValue().size()).sum(); if (rawEvents.size() >= expectedCount @@ -83,6 +85,7 @@ public class LogEventChecker { String verify(long waitForExpectedCountMs, boolean successfulGesture) { final ListMap actualEvents = finishSync(waitForExpectedCountMs); + if (actualEvents == null) return "null event sequences because launcher likely died"; final StringBuilder sb = new StringBuilder(); boolean hasMismatches = false; From f957ff9123964bb421b231f40fc6d90cb514006d Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Wed, 24 Jun 2020 12:48:11 -0700 Subject: [PATCH 017/160] Do preview grid migration in a worker thread Also remove USE_SURFACE_VIEW_FOR_PREVIEW flag Fixes: 159755324 Test: manual Change-Id: I6517c34911e217a69063226b01e4583194902f9c (cherry picked from commit 633a4bdf5724517509f6d40635cd16f14452e4e8) --- .../launcher3/config/FeatureFlags.java | 3 - .../graphics/GridOptionsProvider.java | 61 ---------------- .../graphics/LauncherPreviewRenderer.java | 55 ++------------- .../graphics/PreviewSurfaceRenderer.java | 70 ++++++++++++------- 4 files changed, 50 insertions(+), 139 deletions(-) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 4f53d45c73..5c4a4922fd 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -138,9 +138,6 @@ public final class FeatureFlags { public static final BooleanFlag ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER = getDebugFlag( "ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER", true, "Show launcher preview in grid picker"); - public static final BooleanFlag USE_SURFACE_VIEW_FOR_GRID_PREVIEW = getDebugFlag( - "USE_SURFACE_VIEW_FOR_GRID_PREVIEW", true, "Use surface view for grid preview"); - public static final BooleanFlag ENABLE_OVERVIEW_ACTIONS = getDebugFlag( "ENABLE_OVERVIEW_ACTIONS", true, "Show app actions instead of the shelf in Overview." + " As part of this decoupling, also distinguish swipe up from nav bar vs above it."); diff --git a/src/com/android/launcher3/graphics/GridOptionsProvider.java b/src/com/android/launcher3/graphics/GridOptionsProvider.java index 9bfd5bab87..08d7e4c65e 100644 --- a/src/com/android/launcher3/graphics/GridOptionsProvider.java +++ b/src/com/android/launcher3/graphics/GridOptionsProvider.java @@ -1,21 +1,14 @@ package com.android.launcher3.graphics; -import static com.android.launcher3.config.FeatureFlags.USE_SURFACE_VIEW_FOR_GRID_PREVIEW; -import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; - import android.content.ContentProvider; import android.content.ContentValues; import android.content.pm.PackageManager; import android.content.res.XmlResourceParser; import android.database.Cursor; import android.database.MatrixCursor; -import android.graphics.Bitmap; import android.net.Uri; import android.os.Binder; import android.os.Bundle; -import android.os.ParcelFileDescriptor; -import android.os.ParcelFileDescriptor.AutoCloseOutputStream; -import android.text.TextUtils; import android.util.Log; import android.util.Xml; @@ -26,12 +19,10 @@ import com.android.launcher3.R; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.concurrent.Future; /** * Exposes various launcher grid options and allows the caller to change them. @@ -62,24 +53,7 @@ public class GridOptionsProvider extends ContentProvider { private static final String KEY_LIST_OPTIONS = "/list_options"; private static final String KEY_DEFAULT_GRID = "/default_grid"; - private static final String KEY_PREVIEW = "preview"; - private static final String MIME_TYPE_PNG = "image/png"; - private static final String METHOD_GET_PREVIEW = "get_preview"; - private static final String METADATA_KEY_PREVIEW_VERSION = "preview_version"; - - public static final PipeDataWriter> BITMAP_WRITER = - new PipeDataWriter>() { - @Override - public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String s, - Bundle bundle, Future bitmap) { - try (AutoCloseOutputStream os = new AutoCloseOutputStream(output)) { - bitmap.get().compress(Bitmap.CompressFormat.PNG, 100, os); - } catch (Exception e) { - Log.w(TAG, "fail to write to pipe", e); - } - } - }; @Override public boolean onCreate() { @@ -104,10 +78,6 @@ public class GridOptionsProvider extends ContentProvider { .add(KEY_IS_DEFAULT, idp.numColumns == gridOption.numColumns && idp.numRows == gridOption.numRows); } - Bundle metadata = new Bundle(); - metadata.putString(METADATA_KEY_PREVIEW_VERSION, - USE_SURFACE_VIEW_FOR_GRID_PREVIEW.get() ? "V2" : "V1"); - cursor.setExtras(metadata); return cursor; } @@ -132,10 +102,6 @@ public class GridOptionsProvider extends ContentProvider { @Override public String getType(Uri uri) { - List segments = uri.getPathSegments(); - if (segments.size() > 0 && KEY_PREVIEW.equals(segments.get(0))) { - return MIME_TYPE_PNG; - } return "vnd.android.cursor.dir/launcher_grid"; } @@ -172,33 +138,6 @@ public class GridOptionsProvider extends ContentProvider { return 1; } - @Override - public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { - List segments = uri.getPathSegments(); - if (segments.size() < 2 || !KEY_PREVIEW.equals(segments.get(0))) { - throw new FileNotFoundException("Invalid preview url"); - } - String profileName = segments.get(1); - if (TextUtils.isEmpty(profileName)) { - throw new FileNotFoundException("Invalid preview url"); - } - - InvariantDeviceProfile idp; - try { - idp = new InvariantDeviceProfile(getContext(), profileName); - } catch (Exception e) { - throw new FileNotFoundException(e.getMessage()); - } - - try { - return openPipeHelper(uri, MIME_TYPE_PNG, null, - UI_HELPER_EXECUTOR.submit(new LauncherPreviewRenderer(getContext(), idp)), - BITMAP_WRITER); - } catch (Exception e) { - throw new FileNotFoundException(e.getMessage()); - } - } - @Override public Bundle call(String method, String arg, Bundle extras) { if (getContext().checkPermission("android.permission.BIND_WALLPAPER", diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index 15f4e3fcec..885fb6698b 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -20,7 +20,6 @@ import static android.view.View.MeasureSpec.makeMeasureSpec; import static android.view.View.VISIBLE; import static com.android.launcher3.config.FeatureFlags.ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER; -import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_ALGO; import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems; import static com.android.launcher3.model.ModelUtils.getMissingHotseatRanks; import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially; @@ -34,8 +33,6 @@ import android.content.ContextWrapper; import android.content.Intent; import android.content.pm.ShortcutInfo; import android.content.res.TypedArray; -import android.graphics.Bitmap; -import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.AdaptiveIconDrawable; @@ -63,20 +60,16 @@ import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.R; -import com.android.launcher3.Utilities; import com.android.launcher3.WorkspaceLayoutManager; import com.android.launcher3.allapps.SearchUiManager; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.BitmapInfo; -import com.android.launcher3.icons.BitmapRenderer; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.model.AllAppsList; import com.android.launcher3.model.BgDataModel; import com.android.launcher3.model.BgDataModel.Callbacks; -import com.android.launcher3.model.GridSizeMigrationTask; -import com.android.launcher3.model.GridSizeMigrationTaskV2; import com.android.launcher3.model.LoaderResults; import com.android.launcher3.model.LoaderTask; import com.android.launcher3.model.WidgetItem; @@ -105,7 +98,6 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.FutureTask; @@ -121,7 +113,7 @@ import java.util.concurrent.TimeoutException; * 4) Measure and draw the view on a canvas */ @TargetApi(Build.VERSION_CODES.O) -public class LauncherPreviewRenderer implements Callable { +public class LauncherPreviewRenderer { private static final String TAG = "LauncherPreviewRenderer"; @@ -213,15 +205,17 @@ public class LauncherPreviewRenderer implements Callable { private final Context mContext; private final InvariantDeviceProfile mIdp; private final DeviceProfile mDp; + private final boolean mMigrated; private final Rect mInsets; private final WorkspaceItemInfo mWorkspaceItemInfo; - public LauncherPreviewRenderer(Context context, InvariantDeviceProfile idp) { + public LauncherPreviewRenderer(Context context, InvariantDeviceProfile idp, boolean migrated) { mUiHandler = new Handler(Looper.getMainLooper()); mContext = context; mIdp = idp; mDp = idp.portraitProfile.copy(context); + mMigrated = migrated; // TODO: get correct insets once display cutout API is available. mInsets = new Rect(); @@ -243,28 +237,6 @@ public class LauncherPreviewRenderer implements Callable { context.getString(R.string.label_application); } - @Override - public Bitmap call() { - return BitmapRenderer.createHardwareBitmap(mDp.widthPx, mDp.heightPx, c -> { - - if (Looper.myLooper() == Looper.getMainLooper()) { - new MainThreadRenderer(mContext).renderScreenShot(c); - } else { - CountDownLatch latch = new CountDownLatch(1); - Utilities.postAsyncCallback(mUiHandler, () -> { - new MainThreadRenderer(mContext).renderScreenShot(c); - latch.countDown(); - }); - - try { - latch.await(); - } catch (Exception e) { - Log.e(TAG, "Error drawing on main thread", e); - } - } - }); - } - /** Populate preview and render it. */ public View getRenderedView() { MainThreadRenderer renderer = new MainThreadRenderer(mContext); @@ -407,20 +379,9 @@ public class LauncherPreviewRenderer implements Callable { private void populate() { if (ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER.get()) { - boolean needsToMigrate = - MULTI_DB_GRID_MIRATION_ALGO.get() - ? GridSizeMigrationTaskV2.needsToMigrate(mContext, mIdp) - : GridSizeMigrationTask.needsToMigrate(mContext, mIdp); - boolean success = false; - if (needsToMigrate) { - success = MULTI_DB_GRID_MIRATION_ALGO.get() - ? GridSizeMigrationTaskV2.migrateGridIfNeeded(mContext, mIdp) - : GridSizeMigrationTask.migrateGridIfNeeded(mContext, mIdp); - } - WorkspaceFetcher fetcher; PreviewContext previewContext = null; - if (needsToMigrate && success) { + if (mMigrated) { previewContext = new PreviewContext(mContext, mIdp); LauncherAppState appForPreview = new LauncherAppState( previewContext, null /* iconCacheFileName */); @@ -535,12 +496,6 @@ public class LauncherPreviewRenderer implements Callable { // Additional measure for views which use auto text size API measureView(mRootView, mDp.widthPx, mDp.heightPx); } - - private void renderScreenShot(Canvas canvas) { - populate(); - mRootView.draw(canvas); - dispatchVisibilityAggregated(mRootView, false); - } } private static void measureView(View view, int width, int height) { diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java index 350f221c97..fdc3a947a3 100644 --- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java +++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java @@ -16,7 +16,9 @@ package com.android.launcher3.graphics; +import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_ALGO; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import android.content.Context; import android.hardware.display.DisplayManager; @@ -32,6 +34,8 @@ import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import com.android.launcher3.InvariantDeviceProfile; +import com.android.launcher3.model.GridSizeMigrationTask; +import com.android.launcher3.model.GridSizeMigrationTaskV2; import java.util.concurrent.TimeUnit; @@ -93,32 +97,35 @@ public class PreviewSurfaceRenderer implements IBinder.DeathRecipient { return null; } - MAIN_EXECUTOR.execute(() -> { - // If mSurfaceControlViewHost is null due to any reason (e.g. binder died, - // happening when user leaves the preview screen before preview rendering finishes), - // we should return here. - SurfaceControlViewHost host = mSurfaceControlViewHost; - if (host == null) { - return; - } + MODEL_EXECUTOR.post(() -> { + final boolean success = doGridMigrationIfNecessary(); - View view = new LauncherPreviewRenderer(mContext, mIdp).getRenderedView(); - // This aspect scales the view to fit in the surface and centers it - final float scale = Math.min(mWidth / (float) view.getMeasuredWidth(), - mHeight / (float) view.getMeasuredHeight()); - view.setScaleX(scale); - view.setScaleY(scale); - view.setPivotX(0); - view.setPivotY(0); - view.setTranslationX((mWidth - scale * view.getWidth()) / 2); - view.setTranslationY((mHeight - scale * view.getHeight()) / 2); - view.setAlpha(0); - view.animate().alpha(1) - .setInterpolator(new AccelerateDecelerateInterpolator()) - .setDuration(FADE_IN_ANIMATION_DURATION) - .start(); - host.setView(view, view.getMeasuredWidth(), - view.getMeasuredHeight()); + MAIN_EXECUTOR.post(() -> { + // If mSurfaceControlViewHost is null due to any reason (e.g. binder died, + // happening when user leaves the preview screen before preview rendering finishes), + // we should return here. + SurfaceControlViewHost host = mSurfaceControlViewHost; + if (host == null) { + return; + } + + View view = new LauncherPreviewRenderer(mContext, mIdp, success).getRenderedView(); + // This aspect scales the view to fit in the surface and centers it + final float scale = Math.min(mWidth / (float) view.getMeasuredWidth(), + mHeight / (float) view.getMeasuredHeight()); + view.setScaleX(scale); + view.setScaleY(scale); + view.setPivotX(0); + view.setPivotY(0); + view.setTranslationX((mWidth - scale * view.getWidth()) / 2); + view.setTranslationY((mHeight - scale * view.getHeight()) / 2); + view.setAlpha(0); + view.animate().alpha(1) + .setInterpolator(new AccelerateDecelerateInterpolator()) + .setDuration(FADE_IN_ANIMATION_DURATION) + .start(); + host.setView(view, view.getMeasuredWidth(), view.getMeasuredHeight()); + }); }); Bundle result = new Bundle(); @@ -145,4 +152,17 @@ public class PreviewSurfaceRenderer implements IBinder.DeathRecipient { } mHostToken.unlinkToDeath(this, 0); } + + private boolean doGridMigrationIfNecessary() { + boolean needsToMigrate = + MULTI_DB_GRID_MIRATION_ALGO.get() + ? GridSizeMigrationTaskV2.needsToMigrate(mContext, mIdp) + : GridSizeMigrationTask.needsToMigrate(mContext, mIdp); + if (!needsToMigrate) { + return false; + } + return MULTI_DB_GRID_MIRATION_ALGO.get() + ? GridSizeMigrationTaskV2.migrateGridIfNeeded(mContext, mIdp) + : GridSizeMigrationTask.migrateGridIfNeeded(mContext, mIdp); + } } From 6ab4da8aa0ab6edfa536a3e9931d815cd97b646d Mon Sep 17 00:00:00 2001 From: thiruram Date: Thu, 25 Jun 2020 10:13:14 -0700 Subject: [PATCH 018/160] Fixes missing folder label after launcher restarts. Rootcause: FolderInfo was persisted into DB only when folder options are updated. Hence when folder was created (Folder option remains suggested) its title was not persisted into DB. Fix: Persists folderInfo into DB always whenever title is updated Bug: 159904890 Change-Id: If0d20b0d7fa6966dd7bb40a2c07bcb22bd0893e0 --- src/com/android/launcher3/model/data/FolderInfo.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/model/data/FolderInfo.java b/src/com/android/launcher3/model/data/FolderInfo.java index 05ce06a3f7..41ccbd7054 100644 --- a/src/com/android/launcher3/model/data/FolderInfo.java +++ b/src/com/android/launcher3/model/data/FolderInfo.java @@ -226,7 +226,7 @@ public class FolderInfo extends ItemInfo { } // Updating title to same value does not change any states. - if (title != null && title == this.title) { + if (title != null && title.equals(this.title)) { return; } @@ -236,7 +236,15 @@ public class FolderInfo extends ItemInfo { : title.length() == 0 ? LabelState.EMPTY : getAcceptedSuggestionIndex().isPresent() ? LabelState.SUGGESTED : LabelState.MANUAL; - setOption(FLAG_MANUAL_FOLDER_NAME, newLabelState.equals(LabelState.MANUAL), modelWriter); + + if (newLabelState.equals(LabelState.MANUAL)) { + options |= FLAG_MANUAL_FOLDER_NAME; + } else { + options &= ~FLAG_MANUAL_FOLDER_NAME; + } + if (modelWriter != null) { + modelWriter.updateItemInDatabase(this); + } } /** From 6e7c37a2053c4334499c65b8a17dc0e85df5a54a Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Thu, 25 Jun 2020 19:22:37 -0700 Subject: [PATCH 019/160] During accessible drag, hover events were not properly getting dispatched to the DragAndDropAccessibilityDelegate => regressed in ag/10634216 which attemped to use onHoverListener => the problem is that onHoverListener is only triggered when the event is passed to the CellLayout, however, as with all dispatching, these events are handled depth first, and so in cases where a child handled the event, it would never bubble back up to the parent. => instead we have to continue to override dispatchHover event to always give presecedence to the delegate when it exists b/155956518 Change-Id: Ic3ecf1b422c1821456328035a66a2fc1277e6746 --- src/com/android/launcher3/CellLayout.java | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index ed71ddc3b7..89d768c302 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -182,7 +182,7 @@ public class CellLayout extends ViewGroup { private static final Paint sPaint = new Paint(); // Related to accessible drag and drop - private boolean mUseTouchHelper = false; + DragAndDropAccessibilityDelegate mTouchHelper; public CellLayout(Context context) { this(context, null); @@ -290,17 +290,15 @@ public class CellLayout extends ViewGroup { addView(mShortcutsAndWidgets); } - /** * Sets or clears a delegate used for accessible drag and drop */ public void setDragAndDropAccessibilityDelegate(DragAndDropAccessibilityDelegate delegate) { setOnClickListener(delegate); - setOnHoverListener(delegate); ViewCompat.setAccessibilityDelegate(this, delegate); - mUseTouchHelper = delegate != null; - int accessibilityFlag = mUseTouchHelper + mTouchHelper = delegate; + int accessibilityFlag = mTouchHelper != null ? IMPORTANT_FOR_ACCESSIBILITY_YES : IMPORTANT_FOR_ACCESSIBILITY_NO; setImportantForAccessibility(accessibilityFlag); getShortcutsAndWidgets().setImportantForAccessibility(accessibilityFlag); @@ -312,10 +310,19 @@ public class CellLayout extends ViewGroup { } } + @Override + public boolean dispatchHoverEvent(MotionEvent event) { + // Always attempt to dispatch hover events to accessibility first. + if (mTouchHelper != null && mTouchHelper.dispatchHoverEvent(event)) { + return true; + } + return super.dispatchHoverEvent(event); + } + @Override public boolean onInterceptTouchEvent(MotionEvent ev) { - if (mUseTouchHelper || - (mInterceptTouchListener != null && mInterceptTouchListener.onTouch(this, ev))) { + if (mTouchHelper != null + || (mInterceptTouchListener != null && mInterceptTouchListener.onTouch(this, ev))) { return true; } return false; From 54003963d83208c3f3579d27f5eebe2097cb9c3f Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Fri, 26 Jun 2020 10:11:24 -0700 Subject: [PATCH 020/160] Fix velocity in StaggeredWorkspaceAnimation. * Velocity should match the direction of the spring values. (Swipe direction is upwards, but icons move downwards on screen). * Remove additional conversion to pxPerS since getDimension already does that. Bug: 160003774 Change-Id: I12912edb2354c4a30c538da6ca3789c46d82b94d --- .../com/android/quickstep/util/StaggeredWorkspaceAnim.java | 6 ++++-- .../launcher3/QuickstepAppTransitionManagerImpl.java | 7 +------ res/values/config.xml | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java index 3cafd423ca..41203319b1 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java @@ -205,13 +205,15 @@ public class StaggeredWorkspaceAnim { ResourceProvider rp = DynamicResource.provider(v.getContext()); float stiffness = rp.getFloat(R.dimen.staggered_stiffness); float damping = rp.getFloat(R.dimen.staggered_damping_ratio); + float endTransY = 0; + float springVelocity = Math.abs(mVelocity) * Math.signum(endTransY - mSpringTransY); ValueAnimator springTransY = new SpringAnimationBuilder(v.getContext()) .setStiffness(stiffness) .setDampingRatio(damping) .setMinimumVisibleChange(1f) .setStartValue(mSpringTransY) - .setEndValue(0) - .setStartVelocity(mVelocity) + .setEndValue(endTransY) + .setStartVelocity(springVelocity) .build(v, VIEW_TRANSLATE_Y); springTransY.setStartDelay(startDelay); springTransY.addListener(new AnimatorListenerAdapter() { diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java index fe7b946ef4..bd97f650dd 100644 --- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java @@ -16,8 +16,6 @@ package com.android.launcher3; -import static android.util.TypedValue.COMPLEX_UNIT_DIP; - import static com.android.launcher3.BaseActivity.INVISIBLE_ALL; import static com.android.launcher3.BaseActivity.INVISIBLE_BY_APP_TRANSITIONS; import static com.android.launcher3.BaseActivity.INVISIBLE_BY_PENDING_FLAGS; @@ -62,7 +60,6 @@ import android.os.CancellationSignal; import android.os.Handler; import android.os.Looper; import android.util.Pair; -import android.util.TypedValue; import android.view.View; import androidx.annotation.NonNull; @@ -875,10 +872,8 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans } }); } else { - float velocityDpPerS = DynamicResource.provider(mLauncher) + float velocityPxPerS = DynamicResource.provider(mLauncher) .getDimension(R.dimen.unlock_staggered_velocity_dp_per_s); - float velocityPxPerS = TypedValue.applyDimension(COMPLEX_UNIT_DIP, - velocityDpPerS, mLauncher.getResources().getDisplayMetrics()); anim.play(new StaggeredWorkspaceAnim(mLauncher, velocityPxPerS, false) .getAnimators()); } diff --git a/res/values/config.xml b/res/values/config.xml index ca253259e4..75fcc907db 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -142,7 +142,7 @@ 0.7 150 - 3dp + 4dp 0.7 200 From a190dc1f40e6305f35a422f017cbb41ab40a31be Mon Sep 17 00:00:00 2001 From: vadimt Date: Mon, 4 May 2020 11:32:21 -0700 Subject: [PATCH 021/160] Zero tolerance towards referred destroyed activities After a framework fix, we are not allowing rooted destroyed activities at all. Bug: 139137636 Change-Id: I0dda200db438e1a1b5587636ee08f65300dfa6d1 --- .../android/launcher3/ui/ActivityLeakTracker.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/tests/src/com/android/launcher3/ui/ActivityLeakTracker.java b/tests/src/com/android/launcher3/ui/ActivityLeakTracker.java index 202dcb181f..dd216c7816 100644 --- a/tests/src/com/android/launcher3/ui/ActivityLeakTracker.java +++ b/tests/src/com/android/launcher3/ui/ActivityLeakTracker.java @@ -73,20 +73,12 @@ public class ActivityLeakTracker implements Application.ActivityLifecycleCallbac } public boolean noLeakedActivities() { - int liveActivities = 0; - int destroyedActivities = 0; - for (Activity activity : mActivities.keySet()) { if (activity.isDestroyed()) { - ++destroyedActivities; - } else { - ++liveActivities; + return false; } } - if (liveActivities > 2) return false; - - // It's OK to have 1 leaked activity if no active activities exist. - return liveActivities == 0 ? destroyedActivities <= 1 : destroyedActivities == 0; + return mActivities.size() <= 2; } } From fabfb3ae90524fef748ed35e6edf578a20789689 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Fri, 26 Jun 2020 17:02:47 -0700 Subject: [PATCH 022/160] Using original taskInfo to create the taskKey instead of fake data Change-Id: Ie4e35b35484e0f6cb939febe6357b37381d81682 --- .../AppToOverviewAnimationProvider.java | 12 +++++---- .../quickstep/BaseSwipeUpHandlerV2.java | 2 +- .../quickstep/OverviewCommandHelper.java | 2 +- .../fallback/FallbackRecentsView.java | 9 ++++--- .../android/quickstep/views/RecentsView.java | 25 +++++++++---------- .../quickstep/RecentsActivityTest.java | 8 ++++-- .../com/android/quickstep/RecentsModel.java | 13 +++------- 7 files changed, 35 insertions(+), 36 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java index de83caf162..9310685e30 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java @@ -24,6 +24,7 @@ import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MOD import android.animation.Animator; import android.animation.AnimatorSet; +import android.app.ActivityManager.RunningTaskInfo; import android.util.Log; import android.view.animation.Interpolator; @@ -52,17 +53,17 @@ final class AppToOverviewAnimationProvider> extend private final BaseActivityInterface mActivityInterface; // The id of the currently running task that is transitioning to overview. - private final int mTargetTaskId; + private final RunningTaskInfo mTargetTask; private final RecentsAnimationDeviceState mDeviceState; private T mActivity; private RecentsView mRecentsView; AppToOverviewAnimationProvider( - BaseActivityInterface activityInterface, int targetTaskId, + BaseActivityInterface activityInterface, RunningTaskInfo targetTask, RecentsAnimationDeviceState deviceState) { mActivityInterface = activityInterface; - mTargetTaskId = targetTaskId; + mTargetTask = targetTask; mDeviceState = deviceState; } @@ -73,7 +74,7 @@ final class AppToOverviewAnimationProvider> extend * @param wasVisible true if it was visible before */ boolean onActivityReady(T activity, Boolean wasVisible) { - activity.getOverviewPanel().showCurrentTask(mTargetTaskId); + activity.getOverviewPanel().showCurrentTask(mTargetTask); AbstractFloatingView.closeAllOpenViews(activity, wasVisible); BaseActivityInterface.AnimationFactory factory = mActivityInterface.prepareRecentsUI( mDeviceState, @@ -122,7 +123,8 @@ final class AppToOverviewAnimationProvider> extend wallpaperTargets, MODE_CLOSING); // Use the top closing app to determine the insets for the animation - RemoteAnimationTargetCompat runningTaskTarget = targets.findTask(mTargetTaskId); + RemoteAnimationTargetCompat runningTaskTarget = mTargetTask == null ? null + : targets.findTask(mTargetTask.taskId); if (runningTaskTarget == null) { Log.e(TAG, "No closing app"); return pa.buildAnim(); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java index 37aa0dadd2..024599222f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java @@ -421,7 +421,7 @@ public abstract class BaseSwipeUpHandlerV2, Q exte } protected void notifyGestureAnimationStartToRecents() { - mRecentsView.onGestureAnimationStart(mGestureState.getRunningTaskId()); + mRecentsView.onGestureAnimationStart(mGestureState.getRunningTask()); } private void launcherFrameDrawn() { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java index 434a929b5c..4879db7897 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java @@ -165,7 +165,7 @@ public class OverviewCommandHelper { mActivityInterface = mOverviewComponentObserver.getActivityInterface(); mCreateTime = SystemClock.elapsedRealtime(); mAnimationProvider = new AppToOverviewAnimationProvider<>(mActivityInterface, - RecentsModel.getRunningTaskId(), mDeviceState); + ActivityManagerWrapper.getInstance().getRunningTask(), mDeviceState); // Preload the plan mRecentsModel.getTasks(null); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java index d20bbe9780..ffe9d6aed9 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -76,7 +76,7 @@ public class FallbackRecentsView extends RecentsView */ public void onGestureAnimationStartOnHome(RunningTaskInfo homeTaskInfo) { mHomeTaskInfo = homeTaskInfo; - onGestureAnimationStart(homeTaskInfo == null ? -1 : homeTaskInfo.taskId); + onGestureAnimationStart(homeTaskInfo); } /** @@ -107,14 +107,15 @@ public class FallbackRecentsView extends RecentsView } @Override - protected boolean shouldAddDummyTaskView(int runningTaskId) { - if (mHomeTaskInfo != null && mHomeTaskInfo.taskId == runningTaskId + protected boolean shouldAddDummyTaskView(RunningTaskInfo runningTaskInfo) { + if (mHomeTaskInfo != null && runningTaskInfo != null && + mHomeTaskInfo.taskId == runningTaskInfo.taskId && getTaskViewCount() == 0) { // Do not add a dummy task if we are running over home with empty recents, so that we // show the empty recents message instead of showing a dummy task and later removing it. return false; } - return super.shouldAddDummyTaskView(runningTaskId); + return super.shouldAddDummyTaskView(runningTaskInfo); } @Override diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 68b89758ef..1a9bb85e69 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -56,6 +56,7 @@ import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.app.ActivityManager; +import android.app.ActivityManager.RunningTaskInfo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -135,6 +136,7 @@ import com.android.quickstep.util.TransformParams; import com.android.systemui.plugins.ResourceProvider; import com.android.systemui.shared.recents.IPinnedStackAnimationListener; import com.android.systemui.shared.recents.model.Task; +import com.android.systemui.shared.recents.model.Task.TaskKey; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.LauncherEventUtil; @@ -147,7 +149,7 @@ import java.util.function.Consumer; /** * A list of recent tasks. */ -@TargetApi(Build.VERSION_CODES.P) +@TargetApi(Build.VERSION_CODES.R) public abstract class RecentsView extends PagedView implements Insettable, TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback, InvariantDeviceProfile.OnIDPChangeListener, TaskVisualsChangeListener, @@ -1039,10 +1041,10 @@ public abstract class RecentsView extends PagedView /** * Called when a gesture from an app is starting. */ - public void onGestureAnimationStart(int runningTaskId) { + public void onGestureAnimationStart(RunningTaskInfo runningTaskInfo) { // This needs to be called before the other states are set since it can create the task view mOrientationState.setGestureActive(true); - showCurrentTask(runningTaskId); + showCurrentTask(runningTaskInfo); setEnableFreeScroll(false); setEnableDrawingLiveTile(false); setRunningTaskHidden(true); @@ -1120,8 +1122,8 @@ public abstract class RecentsView extends PagedView /** * Returns true if we should add a dummy taskView for the running task id */ - protected boolean shouldAddDummyTaskView(int runningTaskId) { - return getTaskView(runningTaskId) == null; + protected boolean shouldAddDummyTaskView(RunningTaskInfo runningTaskInfo) { + return runningTaskInfo != null && getTaskView(runningTaskInfo.taskId) == null; } /** @@ -1130,8 +1132,8 @@ public abstract class RecentsView extends PagedView * All subsequent calls to reload will keep the task as the first item until {@link #reset()} * is called. Also scrolls the view to this task. */ - public void showCurrentTask(int runningTaskId) { - if (shouldAddDummyTaskView(runningTaskId)) { + public void showCurrentTask(RunningTaskInfo runningTaskInfo) { + if (shouldAddDummyTaskView(runningTaskInfo)) { boolean wasEmpty = getChildCount() == 0; // Add an empty view for now until the task plan is loaded and applied final TaskView taskView = mTaskViewPool.getView(); @@ -1141,10 +1143,7 @@ public abstract class RecentsView extends PagedView } // The temporary running task is only used for the duration between the start of the // gesture and the task list is loaded and applied - mTmpRunningTask = new Task(new Task.TaskKey(runningTaskId, 0, new Intent(), - new ComponentName(getContext(), getClass()), 0, 0), null, null, "", "", 0, 0, - false, true, false, false, new ActivityManager.TaskDescription(), 0, - new ComponentName("", ""), false); + mTmpRunningTask = Task.from(new TaskKey(runningTaskInfo), runningTaskInfo, false); taskView.bind(mTmpRunningTask, mOrientationState); // Measure and layout immediately so that the scroll values is updated instantly @@ -1155,7 +1154,7 @@ public abstract class RecentsView extends PagedView } boolean runningTaskTileHidden = mRunningTaskTileHidden; - setCurrentTask(runningTaskId); + setCurrentTask(runningTaskInfo == null ? -1 : runningTaskInfo.taskId); setCurrentPage(getRunningTaskIndex()); setRunningTaskViewShowScreenshot(false); setRunningTaskHidden(runningTaskTileHidden); @@ -1673,7 +1672,7 @@ public abstract class RecentsView extends PagedView : View.LAYOUT_DIRECTION_RTL); mClearAllButton.setRotation(mOrientationHandler.getDegreesRotated()); mActivity.getDragLayer().recreateControllers(); - boolean isInLandscape = mOrientationState.getTouchRotation() != 0 + boolean isInLandscape = mOrientationState.getTouchRotation() != ROTATION_0 || mOrientationState.getRecentsActivityRotation() != ROTATION_0; mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION, !mOrientationState.canRecentsActivityRotate() && isInLandscape); diff --git a/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java index 93b64e666c..c148a4b6fe 100644 --- a/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java +++ b/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java @@ -17,6 +17,7 @@ package com.android.quickstep; import static com.android.launcher3.util.LauncherUIHelper.doLayout; +import android.app.ActivityManager.RunningTaskInfo; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; @@ -50,7 +51,7 @@ public class RecentsActivityTest { } @Test - public void testRecets_showCurrentTask() { + public void testRecents_showCurrentTask() { ActivityController controller = Robolectric.buildActivity(RecentsActivity.class); @@ -58,7 +59,10 @@ public class RecentsActivityTest { doLayout(activity); FallbackRecentsView frv = activity.getOverviewPanel(); - frv.showCurrentTask(22); + + RunningTaskInfo dummyTask = new RunningTaskInfo(); + dummyTask.taskId = 22; + frv.showCurrentTask(dummyTask); doLayout(activity); ThumbnailData thumbnailData = new ThumbnailData(); diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java index 517501ad9c..6f54ba2935 100644 --- a/quickstep/src/com/android/quickstep/RecentsModel.java +++ b/quickstep/src/com/android/quickstep/RecentsModel.java @@ -92,15 +92,6 @@ public class RecentsModel extends TaskStackChangeListener { return mTaskList.getTasks(false /* loadKeysOnly */, callback); } - /** - * @return The task id of the running task, or -1 if there is no current running task. - */ - public static int getRunningTaskId() { - ActivityManager.RunningTaskInfo runningTask = - ActivityManagerWrapper.getInstance().getRunningTask(); - return runningTask != null ? runningTask.id : -1; - } - /** * @return Whether the provided {@param changeId} is the latest recent tasks list id. */ @@ -140,7 +131,9 @@ public class RecentsModel extends TaskStackChangeListener { } // Keep the cache up to date with the latest thumbnails - int runningTaskId = RecentsModel.getRunningTaskId(); + ActivityManager.RunningTaskInfo runningTask = + ActivityManagerWrapper.getInstance().getRunningTask(); + int runningTaskId = runningTask != null ? runningTask.id : -1; mTaskList.getTaskKeys(mThumbnailCache.getCacheSize(), tasks -> { for (Task task : tasks) { if (task.key.id == runningTaskId) { From a3629bd52c751b1129815baea031b7d6b8092453 Mon Sep 17 00:00:00 2001 From: Zak Cohen Date: Sun, 28 Jun 2020 20:34:48 -0700 Subject: [PATCH 023/160] Thumbnail Cache - check canceled status on the right thread. The cache was checking the canceled status on the background thread, but the cancel call was being made on the main thread. This was leading to canceled requests still delivering this thumbnail in some cases. Bug: 159840851 Test: local build and non-repo of bug Change-Id: I9a3556f6570eee1db39ebec202c115d58010d7f8 --- .../src/com/android/quickstep/TaskThumbnailCache.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java index ace674383e..2b7a8ec250 100644 --- a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java +++ b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java @@ -166,11 +166,13 @@ public class TaskThumbnailCache { public void run() { ThumbnailData thumbnail = ActivityManagerWrapper.getInstance().getTaskThumbnail( key.id, lowResolution); - if (isCanceled()) { - // We don't call back to the provided callback in this case - return; - } + MAIN_EXECUTOR.execute(() -> { + if (isCanceled()) { + // We don't call back to the provided callback in this case + return; + } + mCache.put(key, thumbnail); callback.accept(thumbnail); onEnd(); From 37bda2bcc9d0a5967e1c2409a3753c6a82489eca Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Mon, 29 Jun 2020 00:22:09 -0700 Subject: [PATCH 024/160] Disable auto correct/suggest on folder edit text Bug: 160075575 TL;DR;; displayCompletions still work Change-Id: I0a7cd06d25ae3976371be0707a2783702b92e8cc --- src/com/android/launcher3/folder/Folder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index d01e189f7e..1c18402932 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -241,9 +241,9 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo mFolderName.setSelectAllOnFocus(true); mFolderName.setInputType(mFolderName.getInputType() & ~InputType.TYPE_TEXT_FLAG_AUTO_CORRECT - & ~InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS + | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_CAP_WORDS); - mFolderName.forceDisableSuggestions(!FeatureFlags.FOLDER_NAME_SUGGEST.get()); + mFolderName.forceDisableSuggestions(true); mFooter = findViewById(R.id.folder_footer); From 53925ff9c6558e330aed20a2e406d68474a41247 Mon Sep 17 00:00:00 2001 From: thiruram Date: Mon, 29 Jun 2020 10:47:14 -0700 Subject: [PATCH 025/160] Fixes NPE with system shortcuts. Bug: 160109140 Change-Id: I35c00fc1792fcf11fc61e1876f9184bd5fb309ce --- .../PredictionUiStateManager.java | 25 +++++++++++-------- .../HotseatPredictionController.java | 8 ++++-- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java index 5e54cd292f..a0f6b044ba 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java @@ -52,7 +52,6 @@ import com.android.launcher3.util.MainThreadInitializedObject; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Optional; import java.util.OptionalInt; import java.util.stream.IntStream; @@ -315,16 +314,22 @@ public class PredictionUiStateManager implements StateListener, * {@link LauncherSettings.Favorites#ITEM_TYPE_DEEP_SHORTCUT} */ public OptionalInt getAllAppsRank(@Nullable ItemInfo itemInfo) { - Optional componentKey = Optional.ofNullable(itemInfo) - .filter(item -> item.itemType == ITEM_TYPE_APPLICATION - || item.itemType == ITEM_TYPE_SHORTCUT - || item.itemType == ITEM_TYPE_DEEP_SHORTCUT) - .map(ItemInfo::getTargetComponent) - .map(componentName -> new ComponentKey(componentName, itemInfo.user)); + if (itemInfo == null || itemInfo.getTargetComponent() == null || itemInfo.user == null) { + return OptionalInt.empty(); + } - return componentKey.map(key -> IntStream.range(0, getCurrentState().apps.size()) - .filter(index -> key.equals(getCurrentState().apps.get(index).getComponentKey())) - .findFirst()).orElseGet(OptionalInt::empty); + if (itemInfo.itemType == ITEM_TYPE_APPLICATION + || itemInfo.itemType == ITEM_TYPE_SHORTCUT + || itemInfo.itemType == ITEM_TYPE_DEEP_SHORTCUT) { + ComponentKey key = new ComponentKey(itemInfo.getTargetComponent(), + itemInfo.user); + final List apps = getCurrentState().apps; + return IntStream.range(0, apps.size()) + .filter(index -> key.equals(apps.get(index).getComponentKey())) + .findFirst(); + } + + return OptionalInt.empty(); } /** diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java index 1dbb9e2d6b..987cd0fcf6 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java @@ -655,11 +655,15 @@ public class HotseatPredictionController implements DragController.DragListener, + ",launchLocation:" + itemInfo.container); } - final ComponentKey k = new ComponentKey(itemInfo.getTargetComponent(), itemInfo.user); + if (itemInfo.getTargetComponent() == null || itemInfo.user == null) { + return; + } + + final ComponentKey key = new ComponentKey(itemInfo.getTargetComponent(), itemInfo.user); final List predictedApps = new ArrayList<>(mComponentKeyMappers); OptionalInt rank = IntStream.range(0, predictedApps.size()) - .filter((i) -> k.equals(predictedApps.get(i).getComponentKey())) + .filter(index -> key.equals(predictedApps.get(index).getComponentKey())) .findFirst(); if (!rank.isPresent()) { return; From 84b848ad5d993ff47ad3c0fdd0b70aa12f0de213 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Mon, 29 Jun 2020 17:39:42 -0700 Subject: [PATCH 026/160] Fix all apps edu in landscape. * Fix bug where All Apps not visible during hint animation. * Fix bug where All Apps is empty after hint animation. Bug: 160122854 Change-Id: Id4106a6200df2845b3c041d5aae14fb83c94b4d4 --- .../com/android/quickstep/views/AllAppsEduView.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/AllAppsEduView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/AllAppsEduView.java index 0979c071bb..3d44eb613d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/AllAppsEduView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/AllAppsEduView.java @@ -16,6 +16,7 @@ package com.android.quickstep.views; import static com.android.launcher3.LauncherState.ALL_APPS; +import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.anim.Interpolators.ACCEL; import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; import static com.android.launcher3.anim.Interpolators.LINEAR; @@ -42,8 +43,10 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; +import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.util.Themes; @@ -139,7 +142,12 @@ public class AllAppsEduView extends AbstractFloatingView { config.userControlled = false; AnimatorPlaybackController stateAnimationController = mLauncher.getStateManager().createAnimationToNewWorkspace(ALL_APPS, config); - float maxAllAppsProgress = 0.15f; + float maxAllAppsProgress = mLauncher.getDeviceProfile().isLandscape ? 0.35f : 0.15f; + + AllAppsTransitionController allAppsController = mLauncher.getAllAppsController(); + PendingAnimation allAppsAlpha = new PendingAnimation(config.duration); + allAppsController.setAlphas(ALL_APPS, config, allAppsAlpha); + mAnimation.play(allAppsAlpha.buildAnim()); ValueAnimator intro = ValueAnimator.ofFloat(0, 1f); intro.setInterpolator(LINEAR); @@ -191,7 +199,8 @@ public class AllAppsEduView extends AbstractFloatingView { @Override public void onAnimationEnd(Animator animation) { mAnimation = null; - stateAnimationController.dispatchOnCancel(); + // Handles cancelling the animation used to hint towards All Apps. + mLauncher.getStateManager().goToState(NORMAL, false); handleClose(false); } }); From 1af70f2729e1001d23783c183d98ce76cca7438c Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 30 Jun 2020 11:50:49 -0700 Subject: [PATCH 027/160] Add logging for non-sending "end scrolled" event for Widgets Bug: 160238801 Change-Id: I60a1cb689110c5b22b0a145b3cca7d47d867005e --- .../android/launcher3/BaseRecyclerView.java | 16 +++++++- .../compat/AccessibilityManagerCompat.java | 3 ++ .../launcher3/testing/TestProtocol.java | 1 + .../launcher3/views/BaseDragLayer.java | 3 ++ .../launcher3/widget/WidgetsFullSheet.java | 11 ++++++ .../launcher3/widget/WidgetsRecyclerView.java | 38 ++++++++++++++++++- 6 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java index 8eceec04ec..41eeb78bc7 100644 --- a/src/com/android/launcher3/BaseRecyclerView.java +++ b/src/com/android/launcher3/BaseRecyclerView.java @@ -183,6 +183,10 @@ public abstract class BaseRecyclerView extends RecyclerView { public void onScrollStateChanged(int state) { super.onScrollStateChanged(state); + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "onScrollStateChanged: " + state); + } + if (state == SCROLL_STATE_IDLE) { AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext()); } @@ -192,6 +196,10 @@ public abstract class BaseRecyclerView extends RecyclerView { public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); if (isLayoutSuppressed()) info.setScrollable(false); + if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { + Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, + "onInitializeAccessibilityNodeInfo, scrollable: " + info.isScrollable()); + } } @Override @@ -199,8 +207,12 @@ public abstract class BaseRecyclerView extends RecyclerView { final boolean changing = frozen != isLayoutSuppressed(); super.setLayoutFrozen(frozen); if (changing) { - ActivityContext.lookupContext(getContext()).getDragLayer() - .sendAccessibilityEvent(TYPE_WINDOW_CONTENT_CHANGED); + if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { + Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "setLayoutFrozen " + frozen + + " @ " + Log.getStackTraceString(new Throwable())); + ActivityContext.lookupContext(getContext()).getDragLayer() + .sendAccessibilityEvent(TYPE_WINDOW_CONTENT_CHANGED); + } } } } \ No newline at end of file diff --git a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java index 1d32d1dfa2..737c97b1bc 100644 --- a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java +++ b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java @@ -75,6 +75,9 @@ public class AccessibilityManagerCompat { } public static void sendScrollFinishedEventToTest(Context context) { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "sendScrollFinishedEventToTest"); + } final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context); if (accessibilityManager == null) return; diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index 8165627448..2644db8f3c 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -107,4 +107,5 @@ public final class TestProtocol { public static final String PAUSE_NOT_DETECTED = "b/139891609"; public static final String OVERIEW_NOT_ALLAPPS = "b/156095088"; public static final String NO_SWIPE_TO_HOME = "b/158017601"; + public static final String NO_SCROLL_END_WIDGETS = "b/160238801"; } diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index b010b4b94b..2c75c74827 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -292,6 +292,9 @@ public abstract class BaseDragLayer @Override public boolean dispatchTouchEvent(MotionEvent ev) { + if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { + Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "BaseDragLayer: " + ev); + } switch (ev.getAction()) { case ACTION_DOWN: { if ((mTouchDispatchState & TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS) != 0) { diff --git a/src/com/android/launcher3/widget/WidgetsFullSheet.java b/src/com/android/launcher3/widget/WidgetsFullSheet.java index 68a3ec51ee..ba55f5adee 100644 --- a/src/com/android/launcher3/widget/WidgetsFullSheet.java +++ b/src/com/android/launcher3/widget/WidgetsFullSheet.java @@ -24,6 +24,7 @@ import android.animation.PropertyValuesHolder; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; +import android.util.Log; import android.util.Pair; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -38,8 +39,10 @@ import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppWidgetHost.ProviderChangedListener; import com.android.launcher3.R; +import com.android.launcher3.Utilities; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.compat.AccessibilityManagerCompat; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.views.RecyclerViewFastScroller; import com.android.launcher3.views.TopRoundedCornerView; @@ -68,6 +71,14 @@ public class WidgetsFullSheet extends BaseWidgetSheet } + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { + Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "WidgetsFullSheet: " + ev); + } + return super.dispatchTouchEvent(ev); + } + public WidgetsFullSheet(Context context, AttributeSet attrs) { this(context, attrs, 0); } diff --git a/src/com/android/launcher3/widget/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/WidgetsRecyclerView.java index 82d4110e85..17baa271e2 100644 --- a/src/com/android/launcher3/widget/WidgetsRecyclerView.java +++ b/src/com/android/launcher3/widget/WidgetsRecyclerView.java @@ -158,13 +158,23 @@ public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouch mScrollbar.isHitInParent(e.getX(), e.getY(), mFastScrollerOffset); } if (mTouchDownOnScroller) { - return mScrollbar.handleTouchEvent(e, mFastScrollerOffset); + final boolean result = mScrollbar.handleTouchEvent(e, mFastScrollerOffset); + if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { + Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "onInterceptTouchEvent 1 " + result); + } + return result; + } + if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { + Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "onInterceptTouchEvent 2 false"); } return false; } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) { + if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { + Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "WidgetsRecyclerView.onTouchEvent"); + } if (mTouchDownOnScroller) { mScrollbar.handleTouchEvent(e, mFastScrollerOffset); } @@ -172,5 +182,31 @@ public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouch @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { + if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { + Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "onRequestDisallowInterceptTouchEvent " + + disallowIntercept); + } + } + + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + final boolean result = super.dispatchTouchEvent(ev); + if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { + Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "WidgetsRecyclerView: state: " + + getScrollState() + + " can scroll: " + getLayoutManager().canScrollVertically() + + " result: " + result + + " layout suppressed: " + isLayoutSuppressed() + + " event: " + ev); + } + return result; + } + + @Override + public void stopNestedScroll() { + if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { + Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "stopNestedScroll"); + } + super.stopNestedScroll(); } } \ No newline at end of file From 3bf889a02fbaf01c72f6e9a1df9962f66fe8cd98 Mon Sep 17 00:00:00 2001 From: Pinyao Ting Date: Tue, 30 Jun 2020 16:43:51 -0700 Subject: [PATCH 028/160] Fixes the issue Launcher state propagation is slower than onDeferredResume. There's currently a bug prevents Launcher release drag lock for two step widgets. Supposedly, onDeferredResume should release the drag lock; However, in 3-button navigation mode, the transition from Overview -> Normal is triggered in Launcher#onNewIntent, which happens after onDeferredResume. This issue is not reproducible with gesture navigation because its transition from Overview -> Normal is handled in NavBarToHomeTouchController Test: manual verified with following steps 1. Enable 3-button navigation 2. Long press in WorkSpace -> Widgets 3. Drag Settings Widget to WorkSpace 4. When the config activity is shown, press "recents" button to see Overview 5. press "home" button to go back to workspace 6. repeat 2 and 3, verify the widget can be dragged Bug: 149659788 Change-Id: I396ffa8a7db44bf3872a10de4208340a99a7efe8 --- .../src/com/android/launcher3/BaseQuickstepLauncher.java | 6 ++++++ src/com/android/launcher3/Launcher.java | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java index 47ce320331..6b941be471 100644 --- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java @@ -157,6 +157,12 @@ public abstract class BaseQuickstepLauncher extends Launcher @Override protected void onDeferredResumed() { super.onDeferredResumed(); + handlePendingActivityRequest(); + } + + @Override + protected void handlePendingActivityRequest() { + super.handlePendingActivityRequest(); if (mPendingActivityRequestCode != -1 && isInState(NORMAL)) { // Remove any active ProxyActivityStarter task and send RESULT_CANCELED to Launcher. onActivityResult(mPendingActivityRequestCode, RESULT_CANCELED, null); diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 0970dae479..d06ae7a9c5 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -923,6 +923,7 @@ public class Launcher extends StatefulActivity implements Launche DiscoveryBounce.showForHomeIfNeeded(this); } + protected void handlePendingActivityRequest() { } private void logStopAndResume(int command) { int pageIndex = mWorkspace.isOverlayShown() ? -1 : mWorkspace.getCurrentPage(); @@ -1423,7 +1424,8 @@ public class Launcher extends StatefulActivity implements Launche if (!isInState(NORMAL)) { // Only change state, if not already the same. This prevents cancelling any // animations running as part of resume - mStateManager.goToState(NORMAL); + mStateManager.goToState(NORMAL, mStateManager.shouldAnimateStateChange(), + this::handlePendingActivityRequest); } // Reset the apps view From 0d213ebb791fae8dec623229dd8a85e5aaadadc1 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 30 Jun 2020 12:03:48 -0700 Subject: [PATCH 029/160] Fixing recents orientation (when home rotation is allowed) during swipe-up Bug: 158781568 Bug: 160149607 Change-Id: I27be09febcdb6f19687469db34b002ce682aa0cb --- .../quickstep/util/TaskViewSimulator.java | 1 + .../android/quickstep/views/RecentsView.java | 13 ++++++++--- .../quickstep/util/RecentsOrientedState.java | 23 +++++++------------ 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java index 46013d3f2b..c9ed498af1 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java @@ -103,6 +103,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { mSizeStrategy = sizeStrategy; mOrientationState = new RecentsOrientedState(context, sizeStrategy, i -> { }); + mOrientationState.setGestureActive(true); mCurrentFullscreenParams = new FullscreenDrawParams(context); mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 1a9bb85e69..9c25b240ba 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -1005,7 +1005,9 @@ public abstract class RecentsView extends PagedView mDwbToastShown = false; mActivity.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, 0); LayoutUtils.setViewEnabled(mActionsView, true); - mOrientationState.setGestureActive(false); + if (mOrientationState.setGestureActive(false)) { + updateOrientationHandler(); + } } public @Nullable TaskView getRunningTaskView() { @@ -1043,7 +1045,10 @@ public abstract class RecentsView extends PagedView */ public void onGestureAnimationStart(RunningTaskInfo runningTaskInfo) { // This needs to be called before the other states are set since it can create the task view - mOrientationState.setGestureActive(true); + if (mOrientationState.setGestureActive(true)) { + updateOrientationHandler(); + } + showCurrentTask(runningTaskInfo); setEnableFreeScroll(false); setEnableDrawingLiveTile(false); @@ -1106,7 +1111,9 @@ public abstract class RecentsView extends PagedView * Called when a gesture from an app has finished. */ public void onGestureAnimationEnd() { - mOrientationState.setGestureActive(false); + if (mOrientationState.setGestureActive(false)) { + updateOrientationHandler(); + } setOnScrollChangeListener(null); setEnableFreeScroll(true); diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java index b359f0f4e1..d822b6c291 100644 --- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java +++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java @@ -188,8 +188,9 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre /** * Sets if the swipe up gesture is currently running or not */ - public void setGestureActive(boolean isGestureActive) { + public boolean setGestureActive(boolean isGestureActive) { setFlag(FLAG_SWIPE_UP_NOT_RUNNING, !isGestureActive); + return update(mTouchRotation, mDisplayRotation); } /** @@ -202,27 +203,19 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre */ public boolean update( @SurfaceRotation int touchRotation, @SurfaceRotation int displayRotation) { - int recentsActivityRotation = inferRecentsActivityRotation(displayRotation); - if (mDisplayRotation == displayRotation - && mTouchRotation == touchRotation - && mRecentsActivityRotation == recentsActivityRotation) { - return false; - } - - mRecentsActivityRotation = recentsActivityRotation; + mRecentsActivityRotation = inferRecentsActivityRotation(displayRotation); mDisplayRotation = displayRotation; mTouchRotation = touchRotation; mPreviousRotation = touchRotation; - if (mRecentsActivityRotation == mTouchRotation || canRecentsActivityRotate()) { + PagedOrientationHandler oldHandler = mOrientationHandler; + if (mRecentsActivityRotation == mTouchRotation + || (canRecentsActivityRotate() && (mFlags & FLAG_SWIPE_UP_NOT_RUNNING) != 0)) { mOrientationHandler = PagedOrientationHandler.PORTRAIT; if (DEBUG) { Log.d(TAG, "current RecentsOrientedState: " + this); } - return true; - } - - if (mTouchRotation == ROTATION_90) { + } else if (mTouchRotation == ROTATION_90) { mOrientationHandler = PagedOrientationHandler.LANDSCAPE; } else if (mTouchRotation == ROTATION_270) { mOrientationHandler = PagedOrientationHandler.SEASCAPE; @@ -232,7 +225,7 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre if (DEBUG) { Log.d(TAG, "current RecentsOrientedState: " + this); } - return true; + return oldHandler != mOrientationHandler; } @SurfaceRotation From 451b09ea755733f2aa06431336d6da5f58479168 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Mon, 6 Jul 2020 11:12:07 -0700 Subject: [PATCH 030/160] Persist prediction cache on every update Test: Manual Bug: 160058750 Change-Id: Icb0b7322b7f9754d3f1c3012e1c98a760f83c787 --- .../hybridhotseat/HotseatPredictionController.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java index 987cd0fcf6..b94e6337d0 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java @@ -113,8 +113,6 @@ public class HotseatPredictionController implements DragController.DragListener, private AllAppsStore mAllAppsStore; private AnimatorSet mIconRemoveAnimators; private boolean mUIUpdatePaused = false; - private boolean mRequiresCacheUpdate = true; - private boolean mIsCacheEmpty; private boolean mIsDestroyed = false; @@ -350,7 +348,6 @@ public class HotseatPredictionController implements DragController.DragListener, fillGapsWithPrediction(); return; } - mIsCacheEmpty = apps.isEmpty(); int count = Math.min(ranks.size(), apps.size()); List items = new ArrayList<>(count); for (int i = 0; i < count; i++) { @@ -393,14 +390,7 @@ public class HotseatPredictionController implements DragController.DragListener, } updateDependencies(); fillGapsWithPrediction(); - cachePredictionComponentKeysIfNecessary(componentKeys); - } - - private void cachePredictionComponentKeysIfNecessary(ArrayList componentKeys) { - if (!mRequiresCacheUpdate && componentKeys.isEmpty() == mIsCacheEmpty) return; mPredictionModel.cachePredictionComponentKeys(componentKeys); - mIsCacheEmpty = componentKeys.isEmpty(); - mRequiresCacheUpdate = false; } private void updateDependencies() { @@ -429,7 +419,6 @@ public class HotseatPredictionController implements DragController.DragListener, notifyItemAction(mPredictionModel.wrapAppTargetWithLocation(appTarget, AppTargetEvent.ACTION_PIN, workspaceItemInfo)); } - mRequiresCacheUpdate = true; } private List mapToWorkspaceItemInfo( @@ -583,7 +572,6 @@ public class HotseatPredictionController implements DragController.DragListener, } mDragObject = null; fillGapsWithPrediction(true, this::removeOutlineDrawings); - mRequiresCacheUpdate = true; } From b0fd1360840b6b5f0dbaa4644c881b523371497c Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Wed, 1 Jul 2020 13:55:46 -0700 Subject: [PATCH 031/160] Remove WRITE_SECURE_SETTINGS permission used for rotation flag Fixes: 150802536 Change-Id: Iaa2fd079a43696e24bf6702dd974446fa39eceeb --- AndroidManifest-common.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml index 84dd06aa39..19a16e341a 100644 --- a/AndroidManifest-common.xml +++ b/AndroidManifest-common.xml @@ -45,9 +45,6 @@ - - - + + + \ No newline at end of file diff --git a/quickstep/res/layout/gesture_tutorial_fragment.xml b/quickstep/res/layout/gesture_tutorial_fragment.xml index 459d65faf7..43bf0ea966 100644 --- a/quickstep/res/layout/gesture_tutorial_fragment.xml +++ b/quickstep/res/layout/gesture_tutorial_fragment.xml @@ -24,6 +24,14 @@ android:layout_height="match_parent" android:background="@drawable/gesture_tutorial_ripple"/> + + + android:padding="18dp" + android:src="@drawable/gesture_tutorial_close_button" + android:tint="?android:attr/textColorPrimary"/> + android:layout_marginEnd="@dimen/gesture_tutorial_title_margin_start_end"/> + android:layout_marginTop="10dp" + android:layout_marginEnd="@dimen/gesture_tutorial_subtitle_margin_start_end"/> + android:layout_marginBottom="10dp"/>