Merge "Guard swipe to notification gesture with system settings preference"
diff --git a/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java b/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java
index ad21106..e649ce1 100644
--- a/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java
+++ b/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java
@@ -18,9 +18,12 @@
import static android.graphics.Bitmap.Config.ARGB_8888;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
import android.system.Os;
@@ -28,6 +31,9 @@
import androidx.annotation.Keep;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherSettings;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
@@ -165,6 +171,19 @@
return response;
}
+ case TestProtocol.REQUEST_CLEAR_DATA: {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ LauncherSettings.Settings.call(mContext.getContentResolver(),
+ LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
+ MAIN_EXECUTOR.submit(() ->
+ LauncherAppState.getInstance(mContext).getModel().forceReload());
+ return response;
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
default:
return super.call(method);
}
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index 98ce9af..5611969 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -71,6 +71,15 @@
// Represents the apps container within search results.
message SearchResultContainer {
+
+ // Length of search term.
+ optional int32 query_length = 1;
+
+ // Container from where search was invoked.
+ oneof ParentContainer {
+ WorkspaceContainer workspace = 2;
+ AllAppsContainer all_apps_container = 3;
+ }
}
// Container for package specific shortcuts to deep links and notifications.
diff --git a/quickstep/AndroidManifest-launcher.xml b/quickstep/AndroidManifest-launcher.xml
index 60afddb..1a634ce 100644
--- a/quickstep/AndroidManifest-launcher.xml
+++ b/quickstep/AndroidManifest-launcher.xml
@@ -53,7 +53,8 @@
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
- android:enabled="true">
+ android:enabled="true"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index 9a4f297..868c659 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -98,7 +98,8 @@
android:name="com.android.quickstep.interaction.GestureSandboxActivity"
android:autoRemoveFromRecents="true"
android:excludeFromRecents="true"
- android:screenOrientation="portrait">
+ android:screenOrientation="portrait"
+ android:exported="true">
<intent-filter>
<action android:name="com.android.quickstep.action.GESTURE_SANDBOX"/>
<category android:name="android.intent.category.DEFAULT"/>
@@ -110,7 +111,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">
<intent-filter>
<action android:name="com.android.launcher3.action.SHOW_HYBRID_HOTSEAT_EDU"/>
<category android:name="android.intent.category.DEFAULT" />
diff --git a/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml b/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml
index 36c9b00..1dab482 100644
--- a/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml
+++ b/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml
@@ -90,6 +90,7 @@
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:text="@string/hotseat_edu_dismiss"
+ android:layout_gravity="start|center_vertical"
android:textColor="@android:color/white"/>
</FrameLayout>
<FrameLayout
@@ -102,7 +103,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
- android:gravity="end"
+ android:layout_gravity="end|center_vertical"
android:text="@string/hotseat_edu_accept"
android:textColor="@android:color/white"/>
</FrameLayout>
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 5e54cd2..a0f6b04 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 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 @@
* {@link LauncherSettings.Favorites#ITEM_TYPE_DEEP_SHORTCUT}
*/
public OptionalInt getAllAppsRank(@Nullable ItemInfo itemInfo) {
- Optional<ComponentKey> 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<ComponentKeyMapper> 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/HotseatEduController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
index a1218ae..4f95254 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 @@
*/
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 @@
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 7334d80..987cd0f 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
@@ -155,14 +155,6 @@
}
/**
- * 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.
*/
public void showEdu() {
@@ -172,7 +164,7 @@
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,
@@ -663,11 +655,15 @@
+ ",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<ComponentKeyMapper> 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;
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 02bae64..a63f3a8 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 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 413a813..37aa0da 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 @@
@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 @@
}
@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/TaskOverlayFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
index 01936e4..e9614d1 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 @@
boolean rotated) {
final boolean isAllowedByPolicy = thumbnail.isRealSnapshot;
- mActionsView.updateDisabledFlags(DISABLED_ROTATED, rotated);
+ getActionsView().updateDisabledFlags(DISABLED_ROTATED, rotated);
getActionsView().setCallbacks(new OverlayUICallbacks() {
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index ee49acc..a3705fd 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -490,8 +490,9 @@
// Clone the previous gesture state since onConsumerAboutToBeSwitched might trigger
// onConsumerInactive and wipe the previous gesture state
GestureState prevGestureState = new GestureState(mGestureState);
- mGestureState = createGestureState(mGestureState);
+ GestureState newGestureState = createGestureState(mGestureState);
mConsumer.onConsumerAboutToBeSwitched();
+ mGestureState = newGestureState;
mConsumer = newConsumer(prevGestureState, mGestureState, event);
ActiveGestureLog.INSTANCE.addLog("setInputConsumer: " + mConsumer.getName());
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 4e967cf..26df9c7 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 @@
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 @@
mStartDisplacement = Math.min(displacement, -mTouchSlop);
}
- notifyGestureStarted();
+ notifyGestureStarted(isLikelyToStartNewTask);
}
}
@@ -310,13 +317,6 @@
}
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 @@
}
}
- private void notifyGestureStarted() {
+ private void notifyGestureStarted(boolean isLikelyToStartNewTask) {
ActiveGestureLog.INSTANCE.addLog("startQuickstep");
if (mInteractionHandler == null) {
return;
@@ -353,7 +353,7 @@
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 @@
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,
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 512bbac..ef66b7a 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 @@
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());
diff --git a/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
index 53f37c1..22d205a 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 @@
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 @@
}
@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 @@
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 @@
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 @@
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 5dcdd7a..0710a0a 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -70,13 +70,13 @@
private Resources mResources;
private OrientationRectF mLastRectTouched;
/**
- * The rotation of the last touched nav bar. Derived from {@link #mLastRectTouched}, but has a
- * longer lifetime than the rect. Note this is different than {@link #mQuickStepStartingRotation}
- * as it always updates its value on every touch whereas mQuickstepStartingRotation only
- * updates when device rotation matches touch rotation. Maybe this will be only one necessary
- * after TODO(b/154580671) is in. TBD.
+ * The rotation of the last touched nav bar, whether that be through the last region the user
+ * touched down on or valid rotation user turned their device to.
+ * Note this is different than
+ * {@link #mQuickStepStartingRotation} as it always updates its value on every touch whereas
+ * mQuickstepStartingRotation only updates when device rotation matches touch rotation.
*/
- private int mLastRectRotation;
+ private int mActiveTouchRotation;
private SysUINavigationMode.Mode mMode;
private QuickStepContractInfo mContractInfo;
@@ -176,13 +176,27 @@
if (mEnableMultipleRegions) {
mQuickStepStartingRotation = info.rotation;
} else {
- mLastRectRotation = 0;
+ mActiveTouchRotation = 0;
mQuickStepStartingRotation = QUICKSTEP_ROTATION_UNINITIALIZED;
}
resetSwipeRegions(info);
}
/**
+ * Call when removing multiple regions to swipe from, but still in active quickswitch mode (task
+ * list is still frozen).
+ * Ex. This would be called when user has quickswitched to the same app rotation that
+ * they started quickswitching in, indicating that extra nav regions can be ignored. Calling
+ * this will update the value of {@link #mActiveTouchRotation}
+ *
+ * @param displayInfo The display whos rotation will be used as the current active rotation
+ */
+ void setSingleActiveRegion(DefaultDisplay.Info displayInfo) {
+ mActiveTouchRotation = displayInfo.rotation;
+ resetSwipeRegions(displayInfo);
+ }
+
+ /**
* Only saves the swipe region represented by {@param region}, clears the
* rest from {@link #mSwipeTouchRegions}
* To be called whenever we want to stop tracking more than one swipe region.
@@ -195,15 +209,21 @@
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) {
@@ -218,20 +238,7 @@
new OrientationRectF(0, 0, size.x, size.y, rotation);
if (mMode == SysUINavigationMode.Mode.NO_BUTTON) {
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();
@@ -254,6 +261,21 @@
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());
@@ -280,7 +302,7 @@
}
int getCurrentActiveRotation() {
- return mLastRectRotation;
+ return mActiveTouchRotation;
}
int getQuickStepStartingRotation() {
@@ -325,8 +347,9 @@
Log.d(TestProtocol.NO_SWIPE_TO_HOME, "setting mLastRectTouched");
}
mLastRectTouched = rect;
- mLastRectRotation = rect.mRotation;
- if (mEnableMultipleRegions && mCurrentDisplayRotation == mLastRectRotation) {
+ mActiveTouchRotation = rect.mRotation;
+ if (mEnableMultipleRegions
+ && mCurrentDisplayRotation == mActiveTouchRotation) {
// TODO(b/154580671) might make this block unnecessary
// Start a touch session for the default nav region for the display
mQuickStepStartingRotation = mLastRectTouched.mRotation;
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 448c93e..6b0c395 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -159,7 +159,7 @@
* sysui to adjust the navbar.
*/
private OrientationEventListener mOrientationListener;
- private int mPreviousRotation = ROTATION_0;
+ private int mSensorRotation = ROTATION_0;
/**
* This is the configuration of the foreground app or the app that will be in the foreground
* once a quickstep gesture finishes.
@@ -270,18 +270,18 @@
@Override
public void onOrientationChanged(int degrees) {
int newRotation = RecentsOrientedState.getRotationForUserDegreesRotated(degrees,
- mPreviousRotation);
- if (newRotation == mPreviousRotation) {
+ mSensorRotation);
+ if (newRotation == mSensorRotation) {
return;
}
- mPreviousRotation = newRotation;
+ mSensorRotation = newRotation;
mPrioritizeDeviceRotation = true;
if (newRotation == mCurrentAppRotation) {
// When user rotates device to the orientation of the foreground app after
// quickstepping
- toggleSecondaryNavBarsForRotation(false);
+ toggleSecondaryNavBarsForRotation();
}
}
};
@@ -373,14 +373,16 @@
mCurrentAppRotation = mDisplayRotation;
/* Update nav bars on the following:
- * a) if we're not expecting quickswitch, this is coming from an activity rotation
- * b) we launch an app in the orientation that user is already in
- * c) We're not in overview, since overview will always be portrait (w/o home rotation)
+ * a) if this is coming from an activity rotation OR
+ * aa) we launch an app in the orientation that user is already in
+ * b) We're not in overview, since overview will always be portrait (w/o home rotation)
+ * c) We're actively in quickswitch mode
*/
if ((mPrioritizeDeviceRotation
- || mCurrentAppRotation == mPreviousRotation) // switch to an app of orientation user is in
- && !mInOverview) {
- toggleSecondaryNavBarsForRotation(false);
+ || mCurrentAppRotation == mSensorRotation) // switch to an app of orientation user is in
+ && !mInOverview
+ && mTaskListFrozen) {
+ toggleSecondaryNavBarsForRotation();
}
}
@@ -501,7 +503,9 @@
* @return whether SystemUI is in a state where we can start a system gesture.
*/
public boolean canStartSystemGesture() {
- return (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
+ boolean canStartWithNavHidden = (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
+ || mTaskListFrozen;
+ return canStartWithNavHidden
&& (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
&& (mSystemUiStateFlags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) == 0
&& ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
@@ -707,29 +711,26 @@
}
private void enableMultipleRegions(boolean enable) {
- toggleSecondaryNavBarsForRotation(enable);
- if (enable && !TestProtocol.sDisableSensorRotation) {
+ mOrientationTouchTransformer.enableMultipleRegions(enable, mDefaultDisplay.getInfo());
+ notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getQuickStepStartingRotation());
+ if (enable && !mInOverview && !TestProtocol.sDisableSensorRotation) {
+ // Clear any previous state from sensor manager
+ mSensorRotation = mCurrentAppRotation;
mOrientationListener.enable();
} else {
mOrientationListener.disable();
}
}
- private void notifySysuiForRotation(int rotation) {
- UI_HELPER_EXECUTOR.execute(() ->
- SystemUiProxy.INSTANCE.get(mContext).onQuickSwitchToNewTask(rotation));
- }
-
public void onStartGesture() {
if (mTaskListFrozen) {
// Prioritize whatever nav bar user touches once in quickstep
// This case is specifically when user changes what nav bar they are using mid
// quickswitch session before tasks list is unfrozen
- notifySysuiForRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
+ notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
}
}
-
void onEndTargetCalculated(GestureState.GestureEndTarget endTarget,
BaseActivityInterface activityInterface) {
if (endTarget == GestureState.GestureEndTarget.RECENTS) {
@@ -746,7 +747,8 @@
// First gesture to start quickswitch
enableMultipleRegions(true);
} else {
- notifySysuiForRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
+ notifySysuiOfCurrentRotation(
+ mOrientationTouchTransformer.getCurrentActiveRotation());
}
// A new gesture is starting, reset the current device rotation
@@ -758,7 +760,7 @@
// touched nav bar but didn't go anywhere and not quickswitching, do nothing
return;
}
- notifySysuiForRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
+ notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
}
}
@@ -770,13 +772,10 @@
/**
* Disables/Enables multiple nav bars on {@link OrientationTouchTransformer} and then
* notifies system UI of the primary rotation the user is interacting with
- *
- * @param enable if {@code true}, this will report to sysUI the navbar of the region the gesture
- * started in (during ACTION_DOWN), otherwise will report {@param displayRotation}
*/
- private void toggleSecondaryNavBarsForRotation(boolean enable) {
- mOrientationTouchTransformer.enableMultipleRegions(enable, mDefaultDisplay.getInfo());
- notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getQuickStepStartingRotation());
+ private void toggleSecondaryNavBarsForRotation() {
+ mOrientationTouchTransformer.setSingleActiveRegion(mDefaultDisplay.getInfo());
+ notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
}
public int getCurrentActiveRotation() {
diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
index ace6743..2b7a8ec 100644
--- a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
+++ b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
@@ -166,11 +166,13 @@
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();
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 2034801..eac45e9 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -17,7 +17,7 @@
package com.android.quickstep.logging;
import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.FOLDER;
-import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.PREDICTED_HOTSEAT_CONTAINER;
+import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.SEARCH_RESULT_CONTAINER;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WORKSPACE_SNAPSHOT;
import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__ALLAPPS;
import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__BACKGROUND;
@@ -75,6 +75,7 @@
// from nano to lite, bake constant to prevent robo test failure.
private static final int DEFAULT_PAGE_INDEX = -2;
private static final int FOLDER_HIERARCHY_OFFSET = 100;
+ private static final int SEARCH_RESULT_HIERARCHY_OFFSET = 200;
public StatsLogCompatManager(Context context) {
sContext = context;
@@ -156,10 +157,10 @@
getComponentName(info) /* component_name */,
getGridX(info, false) /* grid_x */,
getGridY(info, false) /* grid_y */,
- getPageId(info, false) /* page_id */,
+ getPageId(info) /* page_id */,
getGridX(info, true) /* grid_x_parent */,
getGridY(info, true) /* grid_y_parent */,
- getPageId(info, true) /* page_id_parent */,
+ getParentPageId(info) /* page_id_parent */,
getHierarchy(info) /* hierarchy */,
info.getIsWork() /* is_work_profile */,
info.getAttribute().getNumber() /* origin */,
@@ -321,10 +322,10 @@
getComponentName(atomInfo) /* component_name */,
getGridX(atomInfo, false) /* grid_x */,
getGridY(atomInfo, false) /* grid_y */,
- getPageId(atomInfo, false) /* page_id */,
+ getPageId(atomInfo) /* page_id */,
getGridX(atomInfo, true) /* grid_x_parent */,
getGridY(atomInfo, true) /* grid_y_parent */,
- getPageId(atomInfo, true) /* page_id_parent */,
+ getParentPageId(atomInfo) /* page_id_parent */,
getHierarchy(atomInfo) /* hierarchy */,
atomInfo.getIsWork() /* is_work_profile */,
atomInfo.getRank() /* rank */,
@@ -336,9 +337,14 @@
}
private static int getCardinality(LauncherAtom.ItemInfo info) {
- return info.getContainerInfo().getContainerCase().equals(PREDICTED_HOTSEAT_CONTAINER)
- ? info.getContainerInfo().getPredictedHotseatContainer().getCardinality()
- : info.getFolderIcon().getCardinality();
+ switch (info.getContainerInfo().getContainerCase()){
+ case PREDICTED_HOTSEAT_CONTAINER:
+ return info.getContainerInfo().getPredictedHotseatContainer().getCardinality();
+ case SEARCH_RESULT_CONTAINER:
+ return info.getContainerInfo().getSearchResultContainer().getQueryLength();
+ default:
+ return info.getFolderIcon().getCardinality();
+ }
}
private static String getPackageName(LauncherAtom.ItemInfo info) {
@@ -395,15 +401,24 @@
}
}
- private static int getPageId(LauncherAtom.ItemInfo info, boolean parent) {
- if (info.getContainerInfo().getContainerCase() == FOLDER) {
- if (parent) {
- return info.getContainerInfo().getFolder().getWorkspace().getPageIndex();
- } else {
+ private static int getPageId(LauncherAtom.ItemInfo info) {
+ switch (info.getContainerInfo().getContainerCase()) {
+ case FOLDER:
return info.getContainerInfo().getFolder().getPageIndex();
- }
- } else {
- return info.getContainerInfo().getWorkspace().getPageIndex();
+ default:
+ return info.getContainerInfo().getWorkspace().getPageIndex();
+ }
+ }
+
+ private static int getParentPageId(LauncherAtom.ItemInfo info) {
+ switch (info.getContainerInfo().getContainerCase()) {
+ case FOLDER:
+ return info.getContainerInfo().getFolder().getWorkspace().getPageIndex();
+ case SEARCH_RESULT_CONTAINER:
+ return info.getContainerInfo().getSearchResultContainer().getWorkspace()
+ .getPageIndex();
+ default:
+ return info.getContainerInfo().getWorkspace().getPageIndex();
}
}
@@ -411,6 +426,9 @@
if (info.getContainerInfo().getContainerCase() == FOLDER) {
return info.getContainerInfo().getFolder().getParentContainerCase().getNumber()
+ FOLDER_HIERARCHY_OFFSET;
+ } else if (info.getContainerInfo().getContainerCase() == SEARCH_RESULT_CONTAINER) {
+ return info.getContainerInfo().getSearchResultContainer().getParentContainerCase()
+ .getNumber() + SEARCH_RESULT_HIERARCHY_OFFSET;
} else {
return info.getContainerInfo().getContainerCase().getNumber();
}
diff --git a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
index 0fdc684..9ed2bbe 100644
--- a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
+++ b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
@@ -101,7 +101,8 @@
});
}
- if (!hasReachedMaxCount(HOTSEAT_DISCOVERY_TIP_COUNT)) {
+ if (FeatureFlags.ENABLE_HYBRID_HOTSEAT.get() && !hasReachedMaxCount(
+ HOTSEAT_DISCOVERY_TIP_COUNT)) {
stateManager.addStateListener(new StateListener<LauncherState>() {
boolean mFromAllApps = false;
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index ed71ddc..89d768c 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -182,7 +182,7 @@
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 @@
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);
@@ -313,9 +311,18 @@
}
@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;
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 4f53d45..5c4a492 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -138,9 +138,6 @@
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 9bfd5ba..08d7e4c 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 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 @@
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<Future<Bitmap>> BITMAP_WRITER =
- new PipeDataWriter<Future<Bitmap>>() {
- @Override
- public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String s,
- Bundle bundle, Future<Bitmap> 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 @@
.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 @@
@Override
public String getType(Uri uri) {
- List<String> segments = uri.getPathSegments();
- if (segments.size() > 0 && KEY_PREVIEW.equals(segments.get(0))) {
- return MIME_TYPE_PNG;
- }
return "vnd.android.cursor.dir/launcher_grid";
}
@@ -173,33 +139,6 @@
}
@Override
- public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
- List<String> 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",
Binder.getCallingPid(), Binder.getCallingUid())
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index 15f4e3f..885fb66 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.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.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.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.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 @@
* 4) Measure and draw the view on a canvas
*/
@TargetApi(Build.VERSION_CODES.O)
-public class LauncherPreviewRenderer implements Callable<Bitmap> {
+public class LauncherPreviewRenderer {
private static final String TAG = "LauncherPreviewRenderer";
@@ -213,15 +205,17 @@
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 @@
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 @@
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 @@
// 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 350f221..fdc3a94 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.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 @@
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 @@
}
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);
+ }
}
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
index 25a2c69..ebdfa8c 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
@@ -248,10 +248,10 @@
/** Return what's in the src but not in the dest */
private static List<DbEntry> calcDiff(List<DbEntry> src, List<DbEntry> dest) {
Set<String> destIntentSet = new HashSet<>();
- Set<Set<String>> destFolderIntentSet = new HashSet<>();
+ Set<Map<String, Integer>> destFolderIntentSet = new HashSet<>();
for (DbEntry entry : dest) {
if (entry.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
- destFolderIntentSet.add(entry.mFolderItems.keySet());
+ destFolderIntentSet.add(getFolderIntents(entry));
} else {
destIntentSet.add(entry.mIntent);
}
@@ -259,7 +259,7 @@
List<DbEntry> diff = new ArrayList<>();
for (DbEntry entry : src) {
if (entry.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
- if (!destFolderIntentSet.contains(entry.mFolderItems.keySet())) {
+ if (!destFolderIntentSet.contains(getFolderIntents(entry))) {
diff.add(entry);
}
} else {
@@ -271,13 +271,23 @@
return diff;
}
+ private static Map<String, Integer> getFolderIntents(DbEntry entry) {
+ Map<String, Integer> folder = new HashMap<>();
+ for (String intent : entry.mFolderItems.keySet()) {
+ folder.put(intent, entry.mFolderItems.get(intent).size());
+ }
+ return folder;
+ }
+
private static void insertEntryInDb(SQLiteDatabase db, Context context, DbEntry entry,
String srcTableName, String destTableName) {
int id = copyEntryAndUpdate(db, context, entry, srcTableName, destTableName);
if (entry.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
- for (int itemId : entry.mFolderItems.values()) {
- copyEntryAndUpdate(db, context, itemId, id, srcTableName, destTableName);
+ for (Set<Integer> itemIds : entry.mFolderItems.values()) {
+ for (int itemId : itemIds) {
+ copyEntryAndUpdate(db, context, itemId, id, srcTableName, destTableName);
+ }
}
}
}
@@ -675,7 +685,10 @@
String intent = c.getString(1);
verifyIntent(intent);
total++;
- entry.mFolderItems.put(intent, id);
+ if (!entry.mFolderItems.containsKey(intent)) {
+ entry.mFolderItems.put(intent, new HashSet<>());
+ }
+ entry.mFolderItems.get(intent).add(id);
} catch (Exception e) {
removeEntryFromDb(mDb, mTableName, IntArray.wrap(c.getInt(0)));
}
@@ -714,7 +727,7 @@
private String mIntent;
private String mProvider;
- private Map<String, Integer> mFolderItems = new HashMap<>();
+ private Map<String, Set<Integer>> mFolderItems = new HashMap<>();
/** Comparator according to the reading order */
@Override
@@ -748,9 +761,5 @@
values.put(LauncherSettings.Favorites.SPANX, spanX);
values.put(LauncherSettings.Favorites.SPANY, spanY);
}
-
- public String getIntentStr() {
- return mIntent;
- }
}
}
diff --git a/src/com/android/launcher3/model/data/FolderInfo.java b/src/com/android/launcher3/model/data/FolderInfo.java
index 05ce06a..41ccbd7 100644
--- a/src/com/android/launcher3/model/data/FolderInfo.java
+++ b/src/com/android/launcher3/model/data/FolderInfo.java
@@ -226,7 +226,7 @@
}
// 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 @@
: 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);
+ }
}
/**
diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java
index 3082b6e..0d3ddad 100644
--- a/src/com/android/launcher3/model/data/ItemInfo.java
+++ b/src/com/android/launcher3/model/data/ItemInfo.java
@@ -344,7 +344,7 @@
return itemBuilder;
}
- ContainerInfo getContainerInfo() {
+ protected ContainerInfo getContainerInfo() {
switch (container) {
case CONTAINER_HOTSEAT:
return ContainerInfo.newBuilder()
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index 49da7b3..3ca08fd 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -91,6 +91,7 @@
public static final String REQUEST_START_EVENT_LOGGING = "start-event-logging";
public static final String REQUEST_GET_TEST_EVENTS = "get-test-events";
public static final String REQUEST_STOP_EVENT_LOGGING = "stop-event-logging";
+ public static final String REQUEST_CLEAR_DATA = "clear-data";
public static boolean sDebugTracing = false;
public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing";
diff --git a/src/com/android/launcher3/util/DefaultDisplay.java b/src/com/android/launcher3/util/DefaultDisplay.java
index 150fb5b..35788a5 100644
--- a/src/com/android/launcher3/util/DefaultDisplay.java
+++ b/src/com/android/launcher3/util/DefaultDisplay.java
@@ -49,20 +49,25 @@
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<DisplayInfoChangeListener> 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 @@
}
Info oldInfo = mInfo;
- Info info = new Info(mContext);
+ Info info = new Info(mDisplayContext);
int change = 0;
if (info.hasDifferentSize(oldInfo)) {
@@ -162,8 +167,7 @@
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) {
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 3d39d25..858e183 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -300,17 +300,9 @@
checkDetectedLeaks(mLauncher);
}
- protected void clearLauncherData() throws IOException, InterruptedException {
- if (TestHelpers.isInLauncherProcess()) {
- LauncherSettings.Settings.call(mTargetContext.getContentResolver(),
- LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
- resetLoaderState();
- } else {
- clearPackageData(mDevice.getLauncherPackageName());
- mLauncher.enableDebugTracing();
- mLauncherPid = mLauncher.getPid();
- mLauncher.waitForLauncherInitialized();
- }
+ protected void clearLauncherData() {
+ mLauncher.clearLauncherData();
+ mLauncher.waitForLauncherInitialized();
}
/**
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index b9c0f96..a0a65f5 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -1336,6 +1336,10 @@
return tasks;
}
+ public void clearLauncherData() {
+ getTestInfo(TestProtocol.REQUEST_CLEAR_DATA);
+ }
+
public Closable eventsCheck() {
Assert.assertTrue("Nested event checking", mEventChecker == null);
disableSensorRotation();