Merge "Fix NPE inside getFocusdChild" into ub-launcher3-master
diff --git a/quickstep/robolectric_tests/src/com/android/quickstep/util/RecentsOrientedStateTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/util/RecentsOrientedStateTest.java
new file mode 100644
index 0000000..656379f
--- /dev/null
+++ b/quickstep/robolectric_tests/src/com/android/quickstep/util/RecentsOrientedStateTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_90;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import android.content.Context;
+
+import com.android.quickstep.FallbackActivityInterface;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.annotation.LooperMode.Mode;
+
+/**
+ * Tests for {@link RecentsOrientedState}
+ */
+@RunWith(RobolectricTestRunner.class)
+@LooperMode(Mode.PAUSED)
+public class RecentsOrientedStateTest {
+
+ private RecentsOrientedState mR1, mR2;
+
+ @Before
+ public void setup() {
+ Context context = RuntimeEnvironment.application;
+ mR1 = new RecentsOrientedState(context, FallbackActivityInterface.INSTANCE, i -> { });
+ mR2 = new RecentsOrientedState(context, FallbackActivityInterface.INSTANCE, i -> { });
+ assertEquals(mR1.getStateId(), mR2.getStateId());
+ }
+
+ @Test
+ public void stateId_changesWithFlags() {
+ mR1.setGestureActive(true);
+ mR2.setGestureActive(false);
+ assertNotEquals(mR1.getStateId(), mR2.getStateId());
+
+ mR2.setGestureActive(true);
+ assertEquals(mR1.getStateId(), mR2.getStateId());
+ }
+
+ @Test
+ public void stateId_changesWithRecentsRotation() {
+ mR1.setRecentsRotation(ROTATION_90);
+ mR2.setRecentsRotation(ROTATION_180);
+ assertNotEquals(mR1.getStateId(), mR2.getStateId());
+
+ mR2.setRecentsRotation(ROTATION_90);
+ assertEquals(mR1.getStateId(), mR2.getStateId());
+ }
+
+ @Test
+ public void stateId_changesWithDisplayRotation() {
+ mR1.update(ROTATION_0, ROTATION_90);
+ mR2.update(ROTATION_0, ROTATION_180);
+ assertNotEquals(mR1.getStateId(), mR2.getStateId());
+
+ mR2.update(ROTATION_90, ROTATION_90);
+ assertNotEquals(mR1.getStateId(), mR2.getStateId());
+
+ mR2.update(ROTATION_90, ROTATION_0);
+ assertNotEquals(mR1.getStateId(), mR2.getStateId());
+
+ mR2.update(ROTATION_0, ROTATION_90);
+ assertEquals(mR1.getStateId(), mR2.getStateId());
+ }
+}
diff --git a/quickstep/robolectric_tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
index 6c88e55..688f323 100644
--- a/quickstep/robolectric_tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
+++ b/quickstep/robolectric_tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
@@ -148,7 +148,7 @@
if (mAppRotation < 0) {
mAppRotation = launcherRotation;
}
- tvs.setLayoutRotation(launcherRotation, mAppRotation);
+ tvs.getOrientationState().update(launcherRotation, mAppRotation);
if (mAppInsets == null) {
mAppInsets = new Rect(mLauncherInsets);
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 43c088b..041f679 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -378,7 +378,7 @@
if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
return;
}
- mTaskViewSimulator.setRecentsRotation(mActivity.getDisplay().getRotation());
+ mTaskViewSimulator.setOrientationState(mRecentsView.getPagedViewOrientedState());
// If we've already ended the gesture and are going home, don't prepare recents UI,
// as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL.
@@ -686,6 +686,7 @@
dp.updateInsets(targets.homeContentInsets);
dp.updateIsSeascape(mContext);
initTransitionEndpoints(dp);
+ mTaskViewSimulator.getOrientationState().setMultiWindowMode(dp.isMultiWindowMode);
}
// Notify when the animation starts
diff --git a/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index 55f5424..efd4530 100644
--- a/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -132,9 +132,8 @@
TaskViewSimulator tsv = new TaskViewSimulator(mActivity, mRecentsView.getSizeStrategy());
tsv.setDp(mActivity.getDeviceProfile());
+ tsv.setOrientationState(mRecentsView.getPagedViewOrientedState());
tsv.setPreview(runningTaskTarget);
- tsv.setLayoutRotation(mRecentsView.getPagedViewOrientedState().getTouchRotation(),
- mRecentsView.getPagedViewOrientedState().getDisplayRotation());
TransformParams params = new TransformParams()
.setTargetSet(targets)
diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
index 8f7ec3b..4bb1bb5 100644
--- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
+++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
@@ -79,7 +79,7 @@
mTaskViewSimulator = new TaskViewSimulator(context, gestureState.getActivityInterface());
mTransformParams = transformParams;
- mTaskViewSimulator.setLayoutRotation(
+ mTaskViewSimulator.getOrientationState().update(
mDeviceState.getRotationTouchHelper().getCurrentActiveRotation(),
mDeviceState.getRotationTouchHelper().getDisplayRotation());
mTaskViewSimulator.setDrawsBelowRecents(true);
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index ed761cf..2aed76a 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -179,16 +179,17 @@
Context context = v.getContext();
DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
- // RecentsView never updates the display rotation until swipe-up so the value may be stale.
- // Use the display value instead.
- int displayRotation = DisplayController.getDefaultDisplay(context).getInfo().rotation;
-
TaskViewSimulator topMostSimulator = null;
if (tsv == null && targets.apps.length > 0) {
tsv = new TaskViewSimulator(context, recentsView.getSizeStrategy());
tsv.setDp(dp);
- tsv.setLayoutRotation(displayRotation, displayRotation);
+
+ // RecentsView never updates the display rotation until swipe-up so the value may
+ // be stale. Use the display value instead.
+ int displayRotation = DisplayController.getDefaultDisplay(context).getInfo().rotation;
+ tsv.getOrientationState().update(displayRotation, displayRotation);
+
tsv.setPreview(targets.apps[targets.apps.length - 1]);
tsv.fullScreenProgress.value = 0;
tsv.recentsViewScale.value = 1;
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index bb84380..e273aeb 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -72,7 +72,6 @@
private static final String TAG = "RecentsOrientedState";
private static final boolean DEBUG = false;
- private static final String DELIMITER_DOT = "\\.";
private ContentObserver mSystemAutoRotateObserver =
newContentObserver(new Handler(), t -> updateAutoRotateSetting());
@@ -129,6 +128,9 @@
private int mFlags;
private int mPreviousRotation = ROTATION_0;
+ // Combined int which encodes the full state.
+ private int mStateId = 0;
+
/**
* @param rotationChangeListener Callback for receiving rotation events when rotation watcher
* is enabled
@@ -169,7 +171,7 @@
*/
public boolean setRecentsRotation(@SurfaceRotation int recentsRotation) {
mRecentsRotation = recentsRotation;
- return update(mTouchRotation, mDisplayRotation);
+ return updateHandler();
}
/**
@@ -183,8 +185,7 @@
* Sets if the swipe up gesture is currently running or not
*/
public boolean setGestureActive(boolean isGestureActive) {
- setFlag(FLAG_SWIPE_UP_NOT_RUNNING, !isGestureActive);
- return update(mTouchRotation, mDisplayRotation);
+ return setFlag(FLAG_SWIPE_UP_NOT_RUNNING, !isGestureActive);
}
/**
@@ -201,14 +202,13 @@
mDisplayRotation = displayRotation;
mTouchRotation = touchRotation;
mPreviousRotation = touchRotation;
+ return updateHandler();
+ }
- PagedOrientationHandler oldHandler = mOrientationHandler;
+ private boolean updateHandler() {
if (mRecentsActivityRotation == mTouchRotation
|| (canRecentsActivityRotate() && (mFlags & FLAG_SWIPE_UP_NOT_RUNNING) != 0)) {
mOrientationHandler = PagedOrientationHandler.PORTRAIT;
- if (DEBUG) {
- Log.d(TAG, "current RecentsOrientedState: " + this);
- }
} else if (mTouchRotation == ROTATION_90) {
mOrientationHandler = PagedOrientationHandler.LANDSCAPE;
} else if (mTouchRotation == ROTATION_270) {
@@ -219,19 +219,26 @@
if (DEBUG) {
Log.d(TAG, "current RecentsOrientedState: " + this);
}
- return oldHandler != mOrientationHandler;
+
+ int oldStateId = mStateId;
+ // Each SurfaceRotation value takes two bits
+ mStateId = (((((mFlags << 2)
+ | mDisplayRotation) << 2)
+ | mTouchRotation) << 3)
+ | (mRecentsRotation < 0 ? 7 : mRecentsRotation);
+ return mStateId != oldStateId;
}
@SurfaceRotation
private int inferRecentsActivityRotation(@SurfaceRotation int displayRotation) {
if (isRecentsActivityRotationAllowed()) {
- return mRecentsRotation < ROTATION_0 ? displayRotation : mRecentsRotation;
+ return mRecentsRotation < 0 ? displayRotation : mRecentsRotation;
} else {
return ROTATION_0;
}
}
- private void setFlag(int mask, boolean enabled) {
+ private boolean setFlag(int mask, boolean enabled) {
boolean wasRotationEnabled = !TestProtocol.sDisableSensorRotation
&& (mFlags & VALUE_ROTATION_WATCHER_ENABLED) == VALUE_ROTATION_WATCHER_ENABLED
&& !canRecentsActivityRotate();
@@ -253,6 +260,7 @@
}
});
}
+ return updateHandler();
}
@Override
@@ -327,6 +335,13 @@
return mRecentsActivityRotation;
}
+ /**
+ * Returns an id that can be used to tracking internal changes
+ */
+ public int getStateId() {
+ return mStateId;
+ }
+
public boolean isMultipleOrientationSupportedByDevice() {
return (mFlags & MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE)
== MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE;
@@ -509,14 +524,15 @@
public String toString() {
boolean systemRotationOn = (mFlags & FLAG_SYSTEM_ROTATION_ALLOWED) != 0;
return "["
- + "this=" + extractObjectNameAndAddress(super.toString())
- + " mOrientationHandler=" +
- extractObjectNameAndAddress(mOrientationHandler.toString())
+ + "this=" + nameAndAddress(this)
+ + " mOrientationHandler=" + nameAndAddress(mOrientationHandler)
+ " mDisplayRotation=" + mDisplayRotation
+ " mTouchRotation=" + mTouchRotation
+ " mRecentsActivityRotation=" + mRecentsActivityRotation
+ + " mRecentsRotation=" + mRecentsRotation
+ " isRecentsActivityRotationAllowed=" + isRecentsActivityRotationAllowed()
+ " mSystemRotation=" + systemRotationOn
+ + " mStateId=" + mStateId
+ " mFlags=" + mFlags
+ "]";
}
@@ -533,13 +549,7 @@
: idp.portraitProfile;
}
- /**
- * String conversion for only the helpful parts of {@link Object#toString()} method
- * @param stringToExtract "foo.bar.baz.MyObject@1234"
- * @return "MyObject@1234"
- */
- private static String extractObjectNameAndAddress(String stringToExtract) {
- int index = stringToExtract.lastIndexOf(DELIMITER_DOT);
- return index >= 0 ? stringToExtract.substring(index) : "";
+ private static String nameAndAddress(Object obj) {
+ return obj.getClass().getSimpleName() + "@" + obj.hashCode();
}
}
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 61ba411..2f4bb8e 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -23,7 +23,6 @@
import android.animation.TimeInterpolator;
import android.content.Context;
-import android.content.res.Configuration;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.PointF;
@@ -31,6 +30,8 @@
import android.graphics.RectF;
import android.util.IntProperty;
+import androidx.annotation.NonNull;
+
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PendingAnimation;
@@ -67,10 +68,12 @@
private final RectF mTempRectF = new RectF();
private final float[] mTempPoint = new float[2];
- private final RecentsOrientedState mOrientationState;
private final Context mContext;
private final BaseActivityInterface mSizeStrategy;
+ @NonNull
+ private RecentsOrientedState mOrientationState;
+
private final Rect mTaskRect = new Rect();
private boolean mDrawsBelowRecents;
private final PointF mPivot = new PointF();
@@ -100,6 +103,7 @@
// Cached calculations
private boolean mLayoutValid = false;
private boolean mScrollValid = false;
+ private int mOrientationStateId;
public TaskViewSimulator(Context context, BaseActivityInterface sizeStrategy) {
mContext = context;
@@ -107,8 +111,8 @@
mOrientationState = new RecentsOrientedState(context, sizeStrategy, i -> { });
mOrientationState.setGestureActive(true);
-
mCurrentFullscreenParams = new FullscreenDrawParams(context);
+ mOrientationStateId = mOrientationState.getStateId();
}
/**
@@ -116,23 +120,14 @@
*/
public void setDp(DeviceProfile dp) {
mDp = dp;
- mOrientationState.setMultiWindowMode(mDp.isMultiWindowMode);
mLayoutValid = false;
}
/**
- * @see com.android.quickstep.views.RecentsView#setLayoutRotation(int, int)
+ * Sets the orientation state used for this animation
*/
- public void setLayoutRotation(int touchRotation, int displayRotation) {
- mOrientationState.update(touchRotation, displayRotation);
- mLayoutValid = false;
- }
-
- /**
- * @see com.android.quickstep.views.RecentsView#onConfigurationChanged(Configuration)
- */
- public void setRecentsRotation(int recentsRotation) {
- mOrientationState.setRecentsRotation(recentsRotation);
+ public void setOrientationState(@NonNull RecentsOrientedState orientationState) {
+ mOrientationState = orientationState;
mLayoutValid = false;
}
@@ -251,8 +246,9 @@
if (mDp == null || mThumbnailPosition.isEmpty()) {
return;
}
- if (!mLayoutValid) {
+ if (!mLayoutValid || mOrientationStateId != mOrientationState.getStateId()) {
mLayoutValid = true;
+ mOrientationStateId = mOrientationState.getStateId();
getFullScreenScale();
mThumbnailData.rotation = mOrientationState.getDisplayRotation();
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 7efa5bd..f281296 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -89,6 +89,7 @@
import androidx.annotation.Nullable;
import com.android.launcher3.BaseActivity;
+import com.android.launcher3.BaseActivity.MultiWindowModeChangedListener;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.InvariantDeviceProfile;
@@ -239,7 +240,7 @@
}
};
- protected RecentsOrientedState mOrientationState;
+ protected final RecentsOrientedState mOrientationState;
protected final BaseActivityInterface mSizeStrategy;
protected RecentsAnimationController mRecentsAnimationController;
protected SurfaceTransactionApplier mSyncTransactionApplier;
@@ -408,17 +409,18 @@
private int mTaskViewStartIndex = 0;
private OverviewActionsView mActionsView;
- private BaseActivity.MultiWindowModeChangedListener mMultiWindowModeChangedListener =
- (inMultiWindowMode) -> {
- if (mOrientationState != null) {
+ private MultiWindowModeChangedListener mMultiWindowModeChangedListener =
+ new MultiWindowModeChangedListener() {
+ @Override
+ public void onMultiWindowModeChanged(boolean inMultiWindowMode) {
mOrientationState.setMultiWindowMode(inMultiWindowMode);
setLayoutRotation(mOrientationState.getTouchRotation(),
mOrientationState.getDisplayRotation());
updateChildTaskOrientations();
- }
- if (!inMultiWindowMode && mOverviewStateEnabled) {
- // TODO: Re-enable layout transitions for addition of the unpinned task
- reloadIfNeeded();
+ if (!inMultiWindowMode && mOverviewStateEnabled) {
+ // TODO: Re-enable layout transitions for addition of the unpinned task
+ reloadIfNeeded();
+ }
}
};
@@ -476,9 +478,7 @@
mLiveTileTaskViewSimulator = new TaskViewSimulator(getContext(), getSizeStrategy());
mLiveTileTaskViewSimulator.recentsViewScale.value = 1;
- mLiveTileTaskViewSimulator.setLayoutRotation(getPagedViewOrientedState().getTouchRotation(),
- getPagedViewOrientedState().getDisplayRotation());
- mLiveTileTaskViewSimulator.setRecentsRotation(rotation);
+ mLiveTileTaskViewSimulator.setOrientationState(mOrientationState);
mLiveTileTaskViewSimulator.setDrawsBelowRecents(true);
}
@@ -1763,7 +1763,7 @@
if (mOrientationState.setRecentsRotation(rotation)) {
updateOrientationHandler();
}
- mLiveTileTaskViewSimulator.setRecentsRotation(rotation);
+
// If overview is in modal state when rotate, reset it to overview state without running
// animation.
if (mActivity.isInState(OVERVIEW_MODAL_TASK)) {
@@ -1798,8 +1798,6 @@
requestLayout();
// Reapply the current page to update page scrolls.
setCurrentPage(mCurrentPage);
- mLiveTileTaskViewSimulator.setLayoutRotation(getPagedViewOrientedState().getTouchRotation(),
- getPagedViewOrientedState().getDisplayRotation());
}
public RecentsOrientedState getPagedViewOrientedState() {
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 38ebe14..aa123f6 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2497,6 +2497,7 @@
@Override
public void bindAllApplications(AppInfo[] apps, int flags) {
mAppsView.getAppsStore().setApps(apps, flags);
+ PopupContainerWithArrow.dismissInvalidPopup(this);
}
/**
@@ -2528,6 +2529,7 @@
public void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) {
if (!updated.isEmpty()) {
mWorkspace.updateShortcuts(updated);
+ PopupContainerWithArrow.dismissInvalidPopup(this);
}
}
@@ -2552,6 +2554,7 @@
public void bindWorkspaceComponentsRemoved(final ItemInfoMatcher matcher) {
mWorkspace.removeItemsByMatcher(matcher);
mDragController.onAppsRemoved(matcher);
+ PopupContainerWithArrow.dismissInvalidPopup(this);
}
@Override
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 6d92b8b..59930ff 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -600,6 +600,17 @@
}
/**
+ * Dismisses the popup if it is no longer valid
+ */
+ public static void dismissInvalidPopup(BaseDraggingActivity activity) {
+ PopupContainerWithArrow popup = getOpen(activity);
+ if (popup != null && (!popup.mOriginalIcon.isAttachedToWindow()
+ || !canShow(popup.mOriginalIcon, (ItemInfo) popup.mOriginalIcon.getTag()))) {
+ popup.animateClose();
+ }
+ }
+
+ /**
* Handler to control drag-and-drop for popup items
*/
public interface PopupItemDragHandler extends OnLongClickListener, OnTouchListener { }
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index 2b04365..2adf8ce 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -39,6 +39,7 @@
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.PromiseAppInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.IntArray;
@@ -296,6 +297,7 @@
@Override
public void bindAllApplications(AppInfo[] apps, int flags) {
mAppsView.getAppsStore().setApps(apps, flags);
+ PopupContainerWithArrow.dismissInvalidPopup(this);
}
public PopupDataProvider getPopupDataProvider() {
diff --git a/src/com/android/launcher3/views/SearchResultIcon.java b/src/com/android/launcher3/views/SearchResultIcon.java
index 0851b54..51c741b 100644
--- a/src/com/android/launcher3/views/SearchResultIcon.java
+++ b/src/com/android/launcher3/views/SearchResultIcon.java
@@ -30,8 +30,6 @@
import android.view.View;
import android.view.ViewGroup;
-import androidx.annotation.UiThread;
-
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
@@ -49,6 +47,8 @@
import com.android.systemui.plugins.shared.SearchTarget;
import com.android.systemui.plugins.shared.SearchTargetEvent;
+import java.util.function.Consumer;
+
/**
* A {@link BubbleTextView} representing a single cell result in AllApps
*/
@@ -61,7 +61,6 @@
public static final String TARGET_TYPE_HERO_APP = "hero_app";
public static final String TARGET_TYPE_SHORTCUT = "shortcut";
public static final String TARGET_TYPE_REMOTE_ACTION = "remote_action";
- public static final String TARGET_TYPE_SUGGEST = "suggest";
public static final String REMOTE_ACTION_SHOULD_START = "should_start_for_result";
public static final String REMOTE_ACTION_TOKEN = "action_token";
@@ -73,6 +72,7 @@
private final Launcher mLauncher;
private SearchTarget mSearchTarget;
+ private Consumer<ItemInfoWithIcon> mOnItemInfoChanged;
public SearchResultIcon(Context context) {
this(context, null, 0);
@@ -98,6 +98,15 @@
mLauncher.getDeviceProfile().allAppsCellHeightPx));
}
+ /**
+ * Applies search target with a ItemInfoWithIcon consumer to be called after itemInfo is
+ * constructed
+ */
+ public void applySearchTarget(SearchTarget searchTarget, Consumer<ItemInfoWithIcon> cb) {
+ mOnItemInfoChanged = cb;
+ applySearchTarget(searchTarget);
+ }
+
@Override
public void applySearchTarget(SearchTarget searchTarget) {
mSearchTarget = searchTarget;
@@ -111,7 +120,6 @@
prepareUsingShortcutInfo(searchTarget.getShortcutInfos().get(0));
break;
case TARGET_TYPE_REMOTE_ACTION:
- case TARGET_TYPE_SUGGEST:
prepareUsingRemoteAction(searchTarget.getRemoteAction(),
searchTarget.getExtras().getString(REMOTE_ACTION_TOKEN),
searchTarget.getExtras().getBoolean(REMOTE_ACTION_SHOULD_START),
@@ -124,53 +132,45 @@
AllAppsStore appsStore = mLauncher.getAppsView().getAppsStore();
AppInfo appInfo = appsStore.getApp(new ComponentKey(componentName, userHandle));
applyFromApplicationInfo(appInfo);
+ notifyItemInfoChanged(appInfo);
}
private void prepareUsingShortcutInfo(ShortcutInfo shortcutInfo) {
WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(shortcutInfo, getContext());
- applyFromWorkspaceItem(workspaceItemInfo);
+ notifyItemInfoChanged(workspaceItemInfo);
LauncherAppState launcherAppState = LauncherAppState.getInstance(getContext());
MODEL_EXECUTOR.execute(() -> {
launcherAppState.getIconCache().getShortcutIcon(workspaceItemInfo, shortcutInfo);
- reapplyItemInfoAsync(workspaceItemInfo);
+ MAIN_EXECUTOR.post(() -> applyFromWorkspaceItem(workspaceItemInfo));
});
}
private void prepareUsingRemoteAction(RemoteAction remoteAction, String token, boolean start,
boolean useIconToBadge) {
RemoteActionItemInfo itemInfo = new RemoteActionItemInfo(remoteAction, token, start);
+ notifyItemInfoChanged(itemInfo);
+ UI_HELPER_EXECUTOR.post(() -> {
+ // If the Drawable from the remote action is not AdaptiveBitmap, styling will not
+ // work.
+ try (LauncherIcons li = LauncherIcons.obtain(getContext())) {
+ Drawable d = itemInfo.getRemoteAction().getIcon().loadDrawable(getContext());
+ BitmapInfo bitmap = li.createBadgedIconBitmap(d, itemInfo.user,
+ Build.VERSION.SDK_INT);
- applyFromRemoteActionInfo(itemInfo);
- if (!loadIconFromResource()) {
- UI_HELPER_EXECUTOR.post(() -> {
- // If the Drawable from the remote action is not AdaptiveBitmap, styling will not
- // work.
- try (LauncherIcons li = LauncherIcons.obtain(getContext())) {
- Drawable d = itemInfo.getRemoteAction().getIcon().loadDrawable(getContext());
- BitmapInfo bitmap = li.createBadgedIconBitmap(d, itemInfo.user,
- Build.VERSION.SDK_INT);
-
- if (useIconToBadge) {
- BitmapInfo placeholder = li.createIconBitmap(
- itemInfo.getRemoteAction().getTitle().toString().substring(0, 1),
- bitmap.color);
- itemInfo.bitmap = li.badgeBitmap(placeholder.icon, bitmap);
- } else {
- itemInfo.bitmap = bitmap;
- }
- reapplyItemInfoAsync(itemInfo);
+ if (useIconToBadge) {
+ BitmapInfo placeholder = li.createIconBitmap(
+ itemInfo.getRemoteAction().getTitle().toString().substring(0, 1),
+ bitmap.color);
+ itemInfo.bitmap = li.badgeBitmap(placeholder.icon, bitmap);
+ } else {
+ itemInfo.bitmap = bitmap;
}
- });
- }
+ }
+ MAIN_EXECUTOR.post(() -> applyFromRemoteActionInfo(itemInfo));
+ });
}
- @UiThread
- void reapplyItemInfoAsync(ItemInfoWithIcon itemInfoWithIcon) {
- MAIN_EXECUTOR.post(() -> reapplyItemInfo(itemInfoWithIcon));
- }
-
-
@Override
public void handleSelection(int eventType) {
mLauncher.getItemOnClickListener().onClick(this);
@@ -208,7 +208,10 @@
return false;
}
- protected boolean loadIconFromResource() {
- return false;
+ private void notifyItemInfoChanged(ItemInfoWithIcon itemInfoWithIcon) {
+ if (mOnItemInfoChanged != null) {
+ mOnItemInfoChanged.accept(itemInfoWithIcon);
+ mOnItemInfoChanged = null;
+ }
}
}
diff --git a/src/com/android/launcher3/views/SearchResultIconRow.java b/src/com/android/launcher3/views/SearchResultIconRow.java
index ecf5054..e3c7661 100644
--- a/src/com/android/launcher3/views/SearchResultIconRow.java
+++ b/src/com/android/launcher3/views/SearchResultIconRow.java
@@ -46,6 +46,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.function.Consumer;
/**
* A full width representation of {@link SearchResultIcon} with a secondary label and inline
@@ -53,7 +54,7 @@
*/
public class SearchResultIconRow extends LinearLayout implements
AllAppsSearchBarController.SearchTargetHandler, View.OnClickListener,
- View.OnLongClickListener {
+ View.OnLongClickListener, Consumer<ItemInfoWithIcon> {
public static final int MAX_SHORTCUTS_COUNT = 2;
@@ -95,6 +96,7 @@
mShortcutViews[1] = findViewById(R.id.shortcut_1);
mResultIcon.getLayoutParams().height = iconSize;
mResultIcon.getLayoutParams().width = iconSize;
+ mResultIcon.setTextVisibility(false);
for (BubbleTextView bubbleTextView : mShortcutViews) {
ViewGroup.LayoutParams lp = bubbleTextView.getLayoutParams();
lp.width = iconSize;
@@ -113,9 +115,7 @@
@Override
public void applySearchTarget(SearchTarget searchTarget) {
mSearchTarget = searchTarget;
- mResultIcon.applySearchTarget(searchTarget);
- mResultIcon.setTextVisibility(false);
- mTitleView.setText(mResultIcon.getText());
+ mResultIcon.applySearchTarget(searchTarget, this);
String itemType = searchTarget.getItemType();
boolean showDesc = itemType.equals(SearchResultIcon.TARGET_TYPE_SHORTCUT);
mDescriptionView.setVisibility(showDesc ? VISIBLE : GONE);
@@ -138,6 +138,11 @@
}
}
+ @Override
+ public void accept(ItemInfoWithIcon itemInfoWithIcon) {
+ mTitleView.setText(itemInfoWithIcon.title);
+ }
+
private void showInlineShortcuts(List<ShortcutInfo> infos) {
if (infos == null) return;
ArrayList<Pair<ShortcutInfo, ItemInfoWithIcon>> shortcuts = new ArrayList<>();
diff --git a/src/com/android/launcher3/views/SearchResultSuggestion.java b/src/com/android/launcher3/views/SearchResultSuggestion.java
index ab94bf0..c67b1cf 100644
--- a/src/com/android/launcher3/views/SearchResultSuggestion.java
+++ b/src/com/android/launcher3/views/SearchResultSuggestion.java
@@ -28,6 +28,7 @@
*/
public class SearchResultSuggestion extends SearchResultIcon {
+ public static final String TARGET_TYPE_SUGGEST = "suggest";
private final Drawable mCustomIcon;
public SearchResultSuggestion(Context context) {
@@ -55,8 +56,7 @@
}
@Override
- protected boolean loadIconFromResource() {
- setIcon(mCustomIcon);
- return true;
+ protected void setIcon(Drawable icon) {
+ super.setIcon(mCustomIcon);
}
}