Merge "Fix bug where default folder name doesn't change when locale changes." into ub-launcher3-master
diff --git a/quickstep/res/layout/task_menu.xml b/quickstep/res/layout/task_menu.xml
index bf55ece..098b34f 100644
--- a/quickstep/res/layout/task_menu.xml
+++ b/quickstep/res/layout/task_menu.xml
@@ -24,11 +24,19 @@
android:orientation="vertical"
android:visibility="invisible">
+ <com.android.quickstep.views.IconView
+ android:id="@+id/task_icon"
+ android:layout_width="@dimen/task_thumbnail_icon_size"
+ android:layout_height="@dimen/task_thumbnail_icon_size"
+ android:layout_gravity="top|center_horizontal"
+ android:layout_marginBottom="@dimen/deep_shortcut_drawable_padding"
+ android:focusable="false"
+ android:importantForAccessibility="no" />
+
<TextView
- android:id="@+id/task_icon_and_name"
+ android:id="@+id/task_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:drawablePadding="@dimen/deep_shortcut_drawable_padding"
android:gravity="center_horizontal"
android:layout_marginBottom="16dp"
android:textSize="12sp"/>
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
index 0eead88..1d1b7da 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.uioverrides;
+import static com.android.launcher3.AbstractFloatingView.TYPE_ACCESSIBLE;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
@@ -109,7 +110,7 @@
return false;
}
}
- if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
+ if (AbstractFloatingView.getTopOpenViewWithType(mLauncher, TYPE_ACCESSIBLE) != null) {
return false;
}
return true;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
index cfd4119..9a920c8 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.uioverrides;
+import static com.android.launcher3.AbstractFloatingView.TYPE_ACCESSIBLE;
import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
@@ -79,7 +80,7 @@
// If we are already animating from a previous state, we can intercept.
return true;
}
- if (AbstractFloatingView.getTopOpenView(mActivity) != null) {
+ if (AbstractFloatingView.getTopOpenViewWithType(mActivity, TYPE_ACCESSIBLE) != null) {
return false;
}
return isRecentsInteractive();
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index ac9f863..2d0946b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -165,6 +165,14 @@
}
}
+ public static void onEnterAnimationComplete(Context context) {
+ // After the transition to home, enable the high-res thumbnail loader if it wasn't enabled
+ // as a part of quickstep/scrub, so that high-res thumbnails can load the next time we
+ // enter overview
+ RecentsModel.getInstance(context).getRecentsTaskLoader()
+ .getHighResThumbnailLoader().setVisible(true);
+ }
+
public static void onLauncherStateOrResumeChanged(Launcher launcher) {
LauncherState state = launcher.getStateManager().getState();
DeviceProfile profile = launcher.getDeviceProfile();
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index d37ac49..3c69973 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -299,6 +299,9 @@
private void playScaleDownAnim(AnimatorSet anim, Launcher launcher) {
RecentsView recentsView = launcher.getOverviewPanel();
TaskView v = recentsView.getTaskViewAt(recentsView.getCurrentPage());
+ if (v == null) {
+ return;
+ }
ClipAnimationHelper clipHelper = new ClipAnimationHelper();
clipHelper.fromTaskThumbnailView(v.getThumbnail(), (RecentsView) v.getParent(), null);
if (!clipHelper.getSourceRect().isEmpty() && !clipHelper.getTargetRect().isEmpty()) {
diff --git a/quickstep/src/com/android/quickstep/LongSwipeHelper.java b/quickstep/src/com/android/quickstep/LongSwipeHelper.java
index 2fe7a11..16214dd 100644
--- a/quickstep/src/com/android/quickstep/LongSwipeHelper.java
+++ b/quickstep/src/com/android/quickstep/LongSwipeHelper.java
@@ -169,12 +169,4 @@
callback.run();
}
-
- public float getTargetAlpha(RemoteAnimationTargetCompat app, Float expectedAlpha) {
- if (!(app.isNotInRecents
- || app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME)) {
- return 0;
- }
- return expectedAlpha;
- }
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
index b0313fc..eea3971 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
@@ -15,14 +15,23 @@
*/
package com.android.quickstep;
+import static android.view.MotionEvent.ACTION_CANCEL;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_UP;
+
+import android.view.MotionEvent;
+
+import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.util.LooperExecutor;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
+import java.util.function.Supplier;
/**
* Wrapper around RecentsAnimationController to help with some synchronization
@@ -43,6 +52,27 @@
private final ExecutorService mExecutorService =
new LooperExecutor(UiThreadHelper.getBackgroundLooper());
+ private final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
+ private InputConsumerController mInputConsumer =
+ InputConsumerController.getRecentsAnimationInputConsumer();
+ private final Supplier<TouchConsumer> mTouchProxySupplier;
+
+ private boolean mInputConsumerUnregistered;
+ private boolean mTouchProxyEnabled;
+
+ private TouchConsumer mTouchConsumer;
+ private boolean mTouchInProgress;
+ private boolean mInputConsumerUnregisterPending;
+
+ private boolean mFinishPending;
+
+ public RecentsAnimationWrapper(Supplier<TouchConsumer> touchProxySupplier) {
+ // Register the input consumer on the UI thread, to ensure that it runs after any pending
+ // unregister calls
+ mTouchProxySupplier = touchProxySupplier;
+ mMainThreadExecutor.execute(mInputConsumer::registerInputConsumer);
+ }
+
public synchronized void setController(
RecentsAnimationControllerCompat controller, RemoteAnimationTargetSet targetSet) {
TraceHelper.partitionSection("RecentsController", "Set controller " + controller);
@@ -77,21 +107,37 @@
* on the background thread.
*/
public void finish(boolean toHome, Runnable onFinishComplete) {
- mExecutorService.submit(() -> {
- RecentsAnimationControllerCompat controller = mController;
- mController = null;
- TraceHelper.endSection("RecentsController",
- "Finish " + controller + ", toHome=" + toHome);
- if (controller != null) {
- controller.setInputConsumerEnabled(false);
- controller.finish(toHome);
+ if (!toHome) {
+ mExecutorService.submit(() -> finishBg(false, onFinishComplete));
+ }
+
+ mMainThreadExecutor.execute(() -> {
+ if (mTouchInProgress) {
+ mFinishPending = true;
+ // Execute the callback
if (onFinishComplete != null) {
onFinishComplete.run();
}
+ } else {
+ mExecutorService.submit(() -> finishBg(true, onFinishComplete));
}
});
}
+ protected void finishBg(boolean toHome, Runnable onFinishComplete) {
+ RecentsAnimationControllerCompat controller = mController;
+ mController = null;
+ TraceHelper.endSection("RecentsController", "Finish " + controller + ", toHome=" + toHome);
+ if (controller != null) {
+ controller.setInputConsumerEnabled(false);
+ controller.finish(toHome);
+
+ if (onFinishComplete != null) {
+ onFinishComplete.run();
+ }
+ }
+ }
+
public void enableInputConsumer() {
mInputConsumerEnabled = true;
if (mInputConsumerEnabled) {
@@ -106,6 +152,54 @@
}
}
+ public void unregisterInputConsumer() {
+ mMainThreadExecutor.execute(this::unregisterInputConsumerUi);
+ }
+
+ private void unregisterInputConsumerUi() {
+ if (mTouchProxyEnabled && mTouchInProgress) {
+ mInputConsumerUnregisterPending = true;
+ } else {
+ mInputConsumerUnregistered = true;
+ mInputConsumer.unregisterInputConsumer();
+ }
+ }
+
+ public void enableTouchProxy() {
+ mMainThreadExecutor.execute(this::enableTouchProxyUi);
+ }
+
+ private void enableTouchProxyUi() {
+ if (!mInputConsumerUnregistered) {
+ mTouchProxyEnabled = true;
+ mInputConsumer.setTouchListener(this::onInputConsumerTouch);
+ }
+ }
+
+ private boolean onInputConsumerTouch(MotionEvent ev) {
+ int action = ev.getAction();
+ if (action == ACTION_DOWN) {
+ mTouchInProgress = true;
+ mTouchConsumer = mTouchProxySupplier.get();
+ } else if (action == ACTION_CANCEL || action == ACTION_UP) {
+ // Finish any pending actions
+ mTouchInProgress = false;
+ if (mInputConsumerUnregisterPending) {
+ mInputConsumerUnregisterPending = false;
+ mInputConsumer.unregisterInputConsumer();
+ }
+ if (mFinishPending) {
+ mFinishPending = false;
+ mExecutorService.submit(() -> finishBg(true, null));
+ }
+ }
+ if (mTouchConsumer != null) {
+ mTouchConsumer.accept(ev);
+ }
+
+ return true;
+ }
+
public void setAnimationTargetsBehindSystemBars(boolean behindSystemBars) {
if (mBehindSystemBars == behindSystemBars) {
return;
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 0c8e47f..0b97f01 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -232,7 +232,6 @@
public void onStart() {
mRecentsTaskLoader.startLoader(mContext);
- mRecentsTaskLoader.getHighResThumbnailLoader().setVisible(true);
}
public void onTrimMemory(int level) {
diff --git a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
index d9da002..24e199b 100644
--- a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
+++ b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
@@ -30,7 +30,6 @@
import android.util.Log;
import android.view.View;
-import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.ItemInfo;
@@ -270,9 +269,4 @@
return null;
}
}
-
- private static void dismissTaskMenuView(BaseDraggingActivity activity) {
- AbstractFloatingView.closeOpenViews(activity, true,
- AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE);
- }
}
diff --git a/quickstep/src/com/android/quickstep/TouchConsumer.java b/quickstep/src/com/android/quickstep/TouchConsumer.java
index 4cecffa..42e9aee 100644
--- a/quickstep/src/com/android/quickstep/TouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/TouchConsumer.java
@@ -29,6 +29,8 @@
@FunctionalInterface
public interface TouchConsumer extends Consumer<MotionEvent> {
+ TouchConsumer NO_OP = (ev) -> {};
+
@IntDef(flag = true, value = {
INTERACTION_NORMAL,
INTERACTION_QUICK_SCRUB
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index c555bc6..5a1f523 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -21,7 +21,9 @@
import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
-import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
+
+import static com.android.systemui.shared.system.ActivityManagerWrapper
+ .CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
import android.annotation.TargetApi;
@@ -33,7 +35,6 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
-import android.os.RemoteException;
import android.util.Log;
import android.util.SparseArray;
import android.view.Choreographer;
@@ -79,7 +80,7 @@
private final IBinder mMyBinder = new IOverviewProxy.Stub() {
@Override
- public void onPreMotionEvent(@HitTarget int downHitTarget) throws RemoteException {
+ public void onPreMotionEvent(@HitTarget int downHitTarget) {
TraceHelper.beginSection("SysUiBinder");
setupTouchConsumer(downHitTarget);
TraceHelper.partitionSection("SysUiBinder", "Down target " + downHitTarget);
@@ -155,8 +156,6 @@
}
};
- private final TouchConsumer mNoOpTouchConsumer = (ev) -> {};
-
private static boolean sConnected = false;
public static boolean isConnected() {
@@ -185,7 +184,7 @@
mMainThreadExecutor = new MainThreadExecutor();
mOverviewCommandHelper = new OverviewCommandHelper(this);
mMainThreadChoreographer = Choreographer.getInstance();
- mEventQueue = new MotionEventQueue(mMainThreadChoreographer, mNoOpTouchConsumer);
+ mEventQueue = new MotionEventQueue(mMainThreadChoreographer, TouchConsumer.NO_OP);
mOverviewInteractionState = OverviewInteractionState.getInstance(this);
mOverviewCallbacks = OverviewCallbacks.get(this);
mTaskOverlayFactory = TaskOverlayFactory.get(this);
@@ -229,10 +228,11 @@
RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
if (runningTaskInfo == null && !forceToLauncher) {
- return mNoOpTouchConsumer;
+ return TouchConsumer.NO_OP;
} else if (forceToLauncher ||
runningTaskInfo.topActivity.equals(mOverviewCommandHelper.overviewComponent)) {
- return getOverviewConsumer();
+ return OverviewTouchConsumer.newInstance(
+ mOverviewCommandHelper.getActivityControlHelper(), false);
} else {
if (tracker == null) {
tracker = VelocityTracker.obtain();
@@ -245,16 +245,16 @@
}
}
- private TouchConsumer getOverviewConsumer() {
- ActivityControlHelper activityHelper = mOverviewCommandHelper.getActivityControlHelper();
- BaseDraggingActivity activity = activityHelper.getCreatedActivity();
- if (activity == null) {
- return mNoOpTouchConsumer;
+ private void initBackgroundChoreographer() {
+ if (sRemoteUiThread == null) {
+ sRemoteUiThread = new HandlerThread("remote-ui");
+ sRemoteUiThread.start();
}
- return new OverviewTouchConsumer(activityHelper, activity);
+ new Handler(sRemoteUiThread.getLooper()).post(() ->
+ mBackgroundThreadChoreographer = ChoreographerCompat.getSfInstance());
}
- private static class OverviewTouchConsumer<T extends BaseDraggingActivity>
+ public static class OverviewTouchConsumer<T extends BaseDraggingActivity>
implements TouchConsumer {
private final ActivityControlHelper<T> mActivityHelper;
@@ -265,6 +265,8 @@
private final int mTouchSlop;
private final QuickScrubController mQuickScrubController;
+ private final boolean mStartingInActivityBounds;
+
private boolean mTrackingStarted = false;
private boolean mInvalidated = false;
@@ -272,11 +274,13 @@
private boolean mStartPending = false;
private boolean mEndPending = false;
- OverviewTouchConsumer(ActivityControlHelper<T> activityHelper, T activity) {
+ OverviewTouchConsumer(ActivityControlHelper<T> activityHelper, T activity,
+ boolean startingInActivityBounds) {
mActivityHelper = activityHelper;
mActivity = activity;
mTarget = activity.getDragLayer();
mTouchSlop = ViewConfiguration.get(mTarget.getContext()).getScaledTouchSlop();
+ mStartingInActivityBounds = startingInActivityBounds;
mQuickScrubController = mActivity.<RecentsView>getOverviewPanel()
.getQuickScrubController();
@@ -289,6 +293,10 @@
}
int action = ev.getActionMasked();
if (action == ACTION_DOWN) {
+ if (mStartingInActivityBounds) {
+ startTouchTracking(ev, false /* updateLocationOffset */);
+ return;
+ }
mTrackingStarted = false;
mDownPos.set(ev.getX(), ev.getY());
} else if (!mTrackingStarted) {
@@ -301,13 +309,13 @@
break;
case ACTION_CANCEL:
case ACTION_UP:
- startTouchTracking(ev);
+ startTouchTracking(ev, true /* updateLocationOffset */);
break;
case ACTION_MOVE: {
float displacement = ev.getY() - mDownPos.y;
if (Math.abs(displacement) >= mTouchSlop) {
// Start tracking only when mTouchSlop is crossed.
- startTouchTracking(ev);
+ startTouchTracking(ev, true /* updateLocationOffset */);
}
}
}
@@ -322,8 +330,10 @@
}
}
- private void startTouchTracking(MotionEvent ev) {
- mTarget.getLocationOnScreen(mLocationOnScreen);
+ private void startTouchTracking(MotionEvent ev, boolean updateLocationOffset) {
+ if (updateLocationOffset) {
+ mTarget.getLocationOnScreen(mLocationOnScreen);
+ }
// Send down touch event
MotionEvent down = MotionEvent.obtain(ev);
@@ -336,7 +346,7 @@
private void sendEvent(MotionEvent ev) {
int flags = ev.getEdgeFlags();
- ev.setEdgeFlags(flags | EDGE_NAV_BAR);
+ ev.setEdgeFlags(flags | TouchInteractionService.EDGE_NAV_BAR);
ev.offsetLocation(-mLocationOnScreen[0], -mLocationOnScreen[1]);
if (!mTrackingStarted) {
mTarget.onInterceptTouchEvent(ev);
@@ -411,14 +421,13 @@
mQuickScrubController.onQuickScrubProgress(progress);
}
- }
-
- private void initBackgroundChoreographer() {
- if (sRemoteUiThread == null) {
- sRemoteUiThread = new HandlerThread("remote-ui");
- sRemoteUiThread.start();
+ public static TouchConsumer newInstance(
+ ActivityControlHelper activityHelper, boolean startingInActivityBounds) {
+ BaseDraggingActivity activity = activityHelper.getCreatedActivity();
+ if (activity == null) {
+ return TouchConsumer.NO_OP;
+ }
+ return new OverviewTouchConsumer(activityHelper, activity, startingInActivityBounds);
}
- new Handler(sRemoteUiThread.getLooper()).post(() ->
- mBackgroundThreadChoreographer = ChoreographerCompat.getSfInstance());
}
}
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 0ce522a..8e34490 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -73,6 +73,7 @@
import com.android.quickstep.ActivityControlHelper.AnimationFactory;
import com.android.quickstep.ActivityControlHelper.LayoutListener;
import com.android.quickstep.TouchConsumer.InteractionType;
+import com.android.quickstep.TouchInteractionService.OverviewTouchConsumer;
import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.quickstep.util.TransformedRect;
@@ -80,7 +81,6 @@
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.LatencyTrackerCompat;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -220,10 +220,8 @@
private @InteractionType int mInteractionType = INTERACTION_NORMAL;
- private InputConsumerController mInputConsumer =
- InputConsumerController.getRecentsAnimationInputConsumer();
-
- private final RecentsAnimationWrapper mRecentsAnimationWrapper = new RecentsAnimationWrapper();
+ private final RecentsAnimationWrapper mRecentsAnimationWrapper =
+ new RecentsAnimationWrapper(this::createNewTouchProxyHandler);
private final long mTouchTimeMs;
private long mLauncherFrameDrawnTime;
@@ -247,9 +245,6 @@
.createActivityInitListener(this::onActivityInit);
initStateCallbacks();
- // Register the input consumer on the UI thread, to ensure that it runs after any pending
- // unregister calls
- executeOnUiThread(mInputConsumer::registerInputConsumer);
}
private void initStateCallbacks() {
@@ -482,6 +477,12 @@
if (LatencyTrackerCompat.isEnabled(mContext)) {
LatencyTrackerCompat.logToggleRecents((int) (mLauncherFrameDrawnTime - mTouchTimeMs));
}
+
+ // This method is only called when STATE_GESTURE_STARTED_QUICKSTEP/
+ // STATE_GESTURE_STARTED_QUICKSCRUB is set, so we can enable the high-res thumbnail loader
+ // here once we are sure that we will end up in an overview state
+ RecentsModel.getInstance(mContext).getRecentsTaskLoader()
+ .getHighResThumbnailLoader().setVisible(true);
}
public void updateInteractionType(@InteractionType int interactionType) {
@@ -695,6 +696,18 @@
}
}
+ @UiThread
+ private TouchConsumer createNewTouchProxyHandler() {
+ mCurrentShift.finishAnimation();
+ if (mLauncherTransitionController != null) {
+ mLauncherTransitionController.getAnimationPlayer().end();
+ }
+ // Hide the task view, if not already hidden
+ setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha);
+
+ return OverviewTouchConsumer.newInstance(mActivityControlHelper, true);
+ }
+
private void handleNormalGestureEnd(float endVelocity, boolean isFling) {
float velocityPxPerMs = endVelocity / 1000;
long duration = MAX_SWIPE_DURATION;
@@ -737,6 +750,10 @@
}
}
}
+ if (goingToHome) {
+ mRecentsAnimationWrapper.enableTouchProxy();
+ }
+
animateToProgress(startShift, endShift, duration, interpolator, goingToHome);
}
@@ -831,7 +848,7 @@
}
mActivityInitListener.unregister();
- mInputConsumer.unregisterInputConsumer();
+ mRecentsAnimationWrapper.unregisterInputConsumer();
mTaskSnapshot = null;
}
@@ -1059,7 +1076,7 @@
mLongSwipeController = mActivityControlHelper.getLongSwipeController(
mActivity, mRunningTaskId);
onLongSwipeDisplacementUpdated();
- setTargetAlphaProvider(mLongSwipeController::getTargetAlpha);
+ setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha);
}
private void onLongSwipeGestureFinishUi(float velocity, boolean isFling) {
@@ -1089,4 +1106,12 @@
private void preloadAssistData() {
RecentsModel.getInstance(mContext).preloadAssistData(mRunningTaskId, mAssistData);
}
+
+ public static float getHiddenTargetAlpha(RemoteAnimationTargetCompat app, Float expectedAlpha) {
+ if (!(app.isNotInRecents
+ || app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME)) {
+ return 0;
+ }
+ return expectedAlpha;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/IconView.java b/quickstep/src/com/android/quickstep/views/IconView.java
index c359966..8659949 100644
--- a/quickstep/src/com/android/quickstep/views/IconView.java
+++ b/quickstep/src/com/android/quickstep/views/IconView.java
@@ -18,8 +18,11 @@
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.View;
+import com.android.launcher3.FastBitmapDrawable;
+import java.util.ArrayList;
/**
* A view which draws a drawable stretched to fit its size. Unlike ImageView, it avoids relayout
@@ -27,8 +30,14 @@
*/
public class IconView extends View {
+ public interface OnScaleUpdateListener {
+ public void onScaleUpdate(float scale);
+ }
+
private Drawable mDrawable;
+ private ArrayList<OnScaleUpdateListener> mScaleListeners;
+
public IconView(Context context) {
super(context);
}
@@ -53,6 +62,10 @@
invalidate();
}
+ public Drawable getDrawable() {
+ return mDrawable;
+ }
+
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
@@ -78,6 +91,16 @@
}
@Override
+ public void invalidateDrawable(@NonNull Drawable drawable) {
+ super.invalidateDrawable(drawable);
+ if (drawable instanceof FastBitmapDrawable && mScaleListeners != null) {
+ for (OnScaleUpdateListener listener : mScaleListeners) {
+ listener.onScaleUpdate(((FastBitmapDrawable) drawable).getScale());
+ }
+ }
+ }
+
+ @Override
protected void onDraw(Canvas canvas) {
if (mDrawable != null) {
mDrawable.draw(canvas);
@@ -88,4 +111,20 @@
public boolean hasOverlappingRendering() {
return false;
}
+
+ public void addUpdateScaleListener(OnScaleUpdateListener listener) {
+ if (mScaleListeners == null) {
+ mScaleListeners = new ArrayList<>();
+ }
+ mScaleListeners.add(listener);
+ if (mDrawable instanceof FastBitmapDrawable) {
+ listener.onScaleUpdate(((FastBitmapDrawable) mDrawable).getScale());
+ }
+ }
+
+ public void removeUpdateScaleListener(OnScaleUpdateListener listener) {
+ if (mScaleListeners != null) {
+ mScaleListeners.remove(listener);
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index 098349a..e609a40 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -22,7 +22,6 @@
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
-import android.content.res.Configuration;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
@@ -34,15 +33,16 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.FastBitmapDrawable;
import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
import com.android.launcher3.views.BaseDragLayer;
import com.android.quickstep.TaskSystemShortcut;
import com.android.quickstep.TaskUtils;
+import com.android.quickstep.views.IconView.OnScaleUpdateListener;
/**
* Contains options for a recent task when long-pressing its icon.
@@ -59,14 +59,41 @@
new TaskSystemShortcut.Install(),
};
+ private final OnScaleUpdateListener mTaskViewIconScaleListener = new OnScaleUpdateListener() {
+ @Override
+ public void onScaleUpdate(float scale) {
+ final Drawable drawable = mTaskIcon.getDrawable();
+ if (drawable instanceof FastBitmapDrawable) {
+ if (scale != ((FastBitmapDrawable) drawable).getScale()) {
+ mMenuIconDrawable.setScale(scale);
+ }
+ }
+ }
+ };
+
+ private final OnScaleUpdateListener mMenuIconScaleListener = new OnScaleUpdateListener() {
+ @Override
+ public void onScaleUpdate(float scale) {
+ final Drawable taskViewDrawable = mTaskView.getIconView().getDrawable();
+ if (taskViewDrawable instanceof FastBitmapDrawable) {
+ final float currentScale = ((FastBitmapDrawable) taskViewDrawable).getScale();
+ if (currentScale != scale) {
+ ((FastBitmapDrawable) taskViewDrawable).setScale(scale);
+ }
+ }
+ }
+ };
+
private static final int REVEAL_OPEN_DURATION = 150;
private static final int REVEAL_CLOSE_DURATION = 100;
private BaseDraggingActivity mActivity;
- private TextView mTaskIconAndName;
+ private TextView mTaskName;
+ private IconView mTaskIcon;
private AnimatorSet mOpenCloseAnimator;
private TaskView mTaskView;
private LinearLayout mOptionLayout;
+ private FastBitmapDrawable mMenuIconDrawable;
public TaskMenuView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -81,7 +108,8 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mTaskIconAndName = findViewById(R.id.task_icon_and_name);
+ mTaskName = findViewById(R.id.task_name);
+ mTaskIcon = findViewById(R.id.task_icon);
mOptionLayout = findViewById(R.id.menu_option_layout);
}
@@ -113,6 +141,15 @@
}
@Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ // Remove all scale listeners when menu is removed
+ mTaskView.getIconView().removeUpdateScaleListener(mTaskViewIconScaleListener);
+ mTaskIcon.removeUpdateScaleListener(mMenuIconScaleListener);
+ }
+
+ @Override
protected boolean isOfType(int type) {
return (type & TYPE_TASK_MENU) != 0;
}
@@ -138,17 +175,21 @@
private void addMenuOptions(TaskView taskView) {
Drawable icon = taskView.getTask().icon.getConstantState().newDrawable();
- int iconSize = getResources().getDimensionPixelSize(R.dimen.task_thumbnail_icon_size);
- icon.setBounds(0, 0, iconSize, iconSize);
- mTaskIconAndName.setCompoundDrawables(null, icon, null, null);
- mTaskIconAndName.setText(TaskUtils.getTitle(getContext(), taskView.getTask()));
- mTaskIconAndName.setOnClickListener(v -> close(true));
+ mTaskIcon.setDrawable(icon);
+ mTaskIcon.setOnClickListener(v -> close(true));
+ mTaskName.setText(TaskUtils.getTitle(getContext(), taskView.getTask()));
+ mTaskName.setOnClickListener(v -> close(true));
+
+ // Set the icons to match scale by listening to each other's changes
+ mMenuIconDrawable = icon instanceof FastBitmapDrawable ? (FastBitmapDrawable) icon : null;
+ taskView.getIconView().addUpdateScaleListener(mTaskViewIconScaleListener);
+ mTaskIcon.addUpdateScaleListener(mMenuIconScaleListener);
// Move the icon and text up half an icon size to lay over the TaskView
LinearLayout.LayoutParams params =
- (LinearLayout.LayoutParams) mTaskIconAndName.getLayoutParams();
+ (LinearLayout.LayoutParams) mTaskIcon.getLayoutParams();
params.topMargin = (int) -getResources().getDimension(R.dimen.task_thumbnail_top_margin);
- mTaskIconAndName.setLayoutParams(params);
+ mTaskIcon.setLayoutParams(params);
for (TaskSystemShortcut menuOption : MENU_OPTIONS) {
OnClickListener onClickListener = menuOption.getOnClickListener(mActivity, taskView);
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 88c81cf..1653038 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -18,6 +18,7 @@
import static android.widget.Toast.LENGTH_SHORT;
+import static com.android.launcher3.BaseActivity.fromContext;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
@@ -133,7 +134,7 @@
return;
}
launchTask(true /* animate */);
- BaseActivity.fromContext(context).getUserEventDispatcher().logTaskLaunchOrDismiss(
+ fromContext(context).getUserEventDispatcher().logTaskLaunchOrDismiss(
Touch.TAP, Direction.NONE, getRecentsView().indexOfChild(this),
TaskUtils.getLaunchComponentKeyForTask(getTask().key));
});
@@ -185,7 +186,7 @@
if (mTask != null) {
final ActivityOptions opts;
if (animate) {
- opts = BaseDraggingActivity.fromContext(getContext())
+ opts = ((BaseDraggingActivity) fromContext(getContext()))
.getActivityLaunchOptions(this);
} else {
opts = ActivityOptions.makeCustomAnimation(getContext(), 0, 0);
@@ -335,7 +336,7 @@
getContext().getText(R.string.accessibility_close_task)));
final Context context = getContext();
- final BaseDraggingActivity activity = BaseDraggingActivity.fromContext(context);
+ final BaseDraggingActivity activity = fromContext(context);
for (TaskSystemShortcut menuOption : TaskMenuView.MENU_OPTIONS) {
OnClickListener onClickListener = menuOption.getOnClickListener(activity, this);
if (onClickListener != null) {
@@ -363,7 +364,7 @@
for (TaskSystemShortcut menuOption : TaskMenuView.MENU_OPTIONS) {
if (action == menuOption.labelResId) {
OnClickListener onClickListener = menuOption.getOnClickListener(
- BaseDraggingActivity.fromContext(getContext()), this);
+ fromContext(getContext()), this);
if (onClickListener != null) {
onClickListener.onClick(this);
}
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index daf2032..3223837 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -34,6 +34,7 @@
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.util.TouchController;
+import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BaseDragLayer;
import java.lang.annotation.Retention;
@@ -84,7 +85,8 @@
// Usually we show the back button when a floating view is open. Instead, hide for these types.
public static final int TYPE_HIDE_BACK_BUTTON = TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE;
- public static final int TYPE_ACCESSIBLE = TYPE_ALL & ~TYPE_DISCOVERY_BOUNCE;
+ public static final int TYPE_ACCESSIBLE = TYPE_ALL
+ & ~TYPE_DISCOVERY_BOUNCE & ~TYPE_QUICKSTEP_PREVIEW;
protected boolean mIsOpen;
@@ -151,7 +153,7 @@
if (mIsOpen) {
sendAccessibilityEvent(TYPE_VIEW_FOCUSED);
}
- BaseDraggingActivity.fromContext(getContext()).getDragLayer()
+ ActivityContext.lookupContext(getContext()).getDragLayer()
.sendAccessibilityEvent(TYPE_WINDOW_CONTENT_CHANGED);
}
@@ -160,7 +162,7 @@
}
protected static <T extends AbstractFloatingView> T getOpenView(
- BaseDraggingActivity activity, @FloatingViewType int type) {
+ ActivityContext activity, @FloatingViewType int type) {
BaseDragLayer dragLayer = activity.getDragLayer();
// Iterate in reverse order. AbstractFloatingView is added later to the dragLayer,
// and will be one of the last views.
@@ -176,7 +178,7 @@
return null;
}
- public static void closeOpenContainer(BaseDraggingActivity activity,
+ public static void closeOpenContainer(ActivityContext activity,
@FloatingViewType int type) {
AbstractFloatingView view = getOpenView(activity, type);
if (view != null) {
@@ -184,7 +186,7 @@
}
}
- public static void closeOpenViews(BaseDraggingActivity activity, boolean animate,
+ public static void closeOpenViews(ActivityContext activity, boolean animate,
@FloatingViewType int type) {
BaseDragLayer dragLayer = activity.getDragLayer();
// Iterate in reverse order. AbstractFloatingView is added later to the dragLayer,
@@ -200,20 +202,20 @@
}
}
- public static void closeAllOpenViews(BaseDraggingActivity activity, boolean animate) {
+ public static void closeAllOpenViews(ActivityContext activity, boolean animate) {
closeOpenViews(activity, animate, TYPE_ALL);
activity.finishAutoCancelActionMode();
}
- public static void closeAllOpenViews(BaseDraggingActivity activity) {
+ public static void closeAllOpenViews(ActivityContext activity) {
closeAllOpenViews(activity, true);
}
- public static AbstractFloatingView getTopOpenView(BaseDraggingActivity activity) {
+ public static AbstractFloatingView getTopOpenView(ActivityContext activity) {
return getTopOpenViewWithType(activity, TYPE_ALL);
}
- public static AbstractFloatingView getTopOpenViewWithType(BaseDraggingActivity activity,
+ public static AbstractFloatingView getTopOpenViewWithType(ActivityContext activity,
@FloatingViewType int type) {
return getOpenView(activity, type);
}
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index fd69377..6c82e63 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -26,6 +26,7 @@
import android.content.Intent;
import android.content.res.Configuration;
import android.support.annotation.IntDef;
+import android.view.ContextThemeWrapper;
import android.view.View.AccessibilityDelegate;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
@@ -116,13 +117,6 @@
return Utilities.ATLEAST_NOUGAT && isInMultiWindowMode();
}
- public static BaseActivity fromContext(Context context) {
- if (context instanceof BaseActivity) {
- return (BaseActivity) context;
- }
- return ((BaseActivity) ((ContextWrapper) context).getBaseContext());
- }
-
public SystemUiController getSystemUiController() {
if (mSystemUiController == null) {
mSystemUiController = new SystemUiController(getWindow());
@@ -259,4 +253,14 @@
writer.println(" mActivityFlags: " + mActivityFlags);
writer.println(" mForceInvisible: " + mForceInvisible);
}
+
+ public static <T extends BaseActivity> T fromContext(Context context) {
+ if (context instanceof BaseActivity) {
+ return (T) context;
+ } else if (context instanceof ContextThemeWrapper) {
+ return fromContext(((ContextWrapper) context).getBaseContext());
+ } else {
+ throw new IllegalArgumentException("Cannot find BaseActivity in parent tree");
+ }
+ }
}
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index eec196e..d6635dc 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -18,8 +18,6 @@
import android.app.ActivityOptions;
import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.ContextWrapper;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Bundle;
@@ -28,23 +26,23 @@
import android.os.UserHandle;
import android.util.Log;
import android.view.ActionMode;
-import android.view.Surface;
import android.view.View;
import android.widget.Toast;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.badge.BadgeInfo;
import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.uioverrides.DisplayRotationListener;
import com.android.launcher3.uioverrides.WallpaperColorInfo;
-import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.views.BaseDragLayer;
+import com.android.launcher3.views.ActivityContext;
/**
* Extension of BaseActivity allowing support for drag-n-drop
*/
public abstract class BaseDraggingActivity extends BaseActivity
- implements WallpaperColorInfo.OnChangeListener {
+ implements WallpaperColorInfo.OnChangeListener, ActivityContext {
private static final String TAG = "BaseDraggingActivity";
@@ -110,6 +108,7 @@
mCurrentActionMode = null;
}
+ @Override
public boolean finishAutoCancelActionMode() {
if (mCurrentActionMode != null && AUTO_CANCEL_ACTION_MODE == mCurrentActionMode.getTag()) {
mCurrentActionMode.finish();
@@ -128,13 +127,6 @@
public abstract void invalidateParent(ItemInfo info);
- public static BaseDraggingActivity fromContext(Context context) {
- if (context instanceof BaseDraggingActivity) {
- return (BaseDraggingActivity) context;
- }
- return ((BaseDraggingActivity) ((ContextWrapper) context).getBaseContext());
- }
-
public Rect getViewBounds(View v) {
int[] pos = new int[2];
v.getLocationOnScreen(pos);
diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java
index 9217ca9..7efb6ec 100644
--- a/src/com/android/launcher3/FastBitmapDrawable.java
+++ b/src/com/android/launcher3/FastBitmapDrawable.java
@@ -109,7 +109,7 @@
@Override
public final void draw(Canvas canvas) {
- if (mScaleAnimation != null) {
+ if (mScale != 1f) {
int count = canvas.save();
Rect bounds = getBounds();
canvas.scale(mScale, mScale, bounds.exactCenterX(), bounds.exactCenterY());
@@ -150,10 +150,23 @@
return mAlpha;
}
+ public void setScale(float scale) {
+ if (mScaleAnimation != null) {
+ mScaleAnimation.cancel();
+ mScaleAnimation = null;
+ }
+ mScale = scale;
+ invalidateSelf();
+ }
+
public float getAnimatedScale() {
return mScaleAnimation == null ? 1 : mScale;
}
+ public float getScale() {
+ return mScale;
+ }
+
@Override
public int getIntrinsicWidth() {
return mBitmap.getWidth();
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 0917827..44d3d53 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -349,6 +349,12 @@
}
@Override
+ public void onEnterAnimationComplete() {
+ super.onEnterAnimationComplete();
+ UiFactory.onEnterAnimationComplete(this);
+ }
+
+ @Override
public void onConfigurationChanged(Configuration newConfig) {
int diff = newConfig.diff(mOldConfig);
@@ -2412,10 +2418,7 @@
}
public static Launcher getLauncher(Context context) {
- if (context instanceof Launcher) {
- return (Launcher) context;
- }
- return ((Launcher) ((ContextWrapper) context).getBaseContext());
+ return (Launcher) fromContext(context);
}
/**
diff --git a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
index 1e84b41..e204c63 100644
--- a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
+++ b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
@@ -106,6 +106,10 @@
}
protected boolean onDragStart(DragEvent event) {
+ return onDragStart(event, this);
+ }
+
+ protected boolean onDragStart(DragEvent event, DragOptions.PreDragCondition preDragCondition) {
ClipDescription desc = event.getClipDescription();
if (desc == null || !desc.hasMimeType(getMimeType())) {
Log.e(TAG, "Someone started a dragAndDrop before us.");
@@ -115,7 +119,7 @@
Point downPos = new Point((int) event.getX(), (int) event.getY());
DragOptions options = new DragOptions();
options.systemDndStartPoint = downPos;
- options.preDragCondition = this;
+ options.preDragCondition = preDragCondition;
// We use drag event position as the screenPos for the preview image. Since mPreviewRect
// already includes the view position relative to the drag event on the source window,
@@ -123,7 +127,7 @@
// across windows, using drag position here give a good estimate for relative position
// to source window.
createDragHelper().startDrag(new Rect(mPreviewRect),
- mPreviewBitmapWidth, mPreviewViewWidth, downPos, this, options);
+ mPreviewBitmapWidth, mPreviewViewWidth, downPos, this, options);
mDragStartTime = SystemClock.uptimeMillis();
return true;
}
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
index 83593aa..1c4327c 100644
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ b/src/com/android/launcher3/logging/LoggerUtils.java
@@ -144,7 +144,7 @@
}
public static Target newItemTarget(View v, InstantAppResolver instantAppResolver) {
- return (v.getTag() instanceof ItemInfo)
+ return (v != null) && (v.getTag() instanceof ItemInfo)
? newItemTarget((ItemInfo) v.getTag(), instantAppResolver)
: newTarget(Target.Type.ITEM);
}
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index be666a6..e157482 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -36,8 +36,10 @@
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.animation.AccelerateDecelerateInterpolator;
+import android.widget.FrameLayout;
import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.R;
@@ -47,6 +49,7 @@
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.graphics.TriangleShape;
import com.android.launcher3.util.Themes;
+import com.android.launcher3.views.BaseDragLayer;
import java.util.ArrayList;
import java.util.Collections;
@@ -134,7 +137,7 @@
protected void reorderAndShow(int viewsToFlip) {
setVisibility(View.INVISIBLE);
mIsOpen = true;
- mLauncher.getDragLayer().addView(this);
+ getPopupContainer().addView(this);
orientAboutObject();
boolean reverseOrder = mIsAboveIcon;
@@ -163,7 +166,7 @@
? R.dimen.popup_arrow_horizontal_center_start
: R.dimen.popup_arrow_horizontal_center_end);
final int halfArrowWidth = res.getDimensionPixelSize(R.dimen.popup_arrow_width) / 2;
- mLauncher.getDragLayer().addView(mArrow);
+ getPopupContainer().addView(mArrow);
DragLayer.LayoutParams arrowLp = (DragLayer.LayoutParams) mArrow.getLayoutParams();
if (mIsLeftAligned) {
mArrow.setX(getX() + arrowCenterOffset - halfArrowWidth);
@@ -179,7 +182,7 @@
ShapeDrawable arrowDrawable = new ShapeDrawable(TriangleShape.create(
arrowLp.width, arrowLp.height, !mIsAboveIcon));
Paint arrowPaint = arrowDrawable.getPaint();
- arrowPaint.setColor(Themes.getAttrColor(mLauncher, R.attr.popupColorPrimary));
+ arrowPaint.setColor(Themes.getAttrColor(getContext(), R.attr.popupColorPrimary));
// The corner path effect won't be reflected in the shadow, but shouldn't be noticeable.
int radius = getResources().getDimensionPixelSize(R.dimen.popup_arrow_corner_radius);
arrowPaint.setPathEffect(new CornerPathEffect(radius));
@@ -222,7 +225,7 @@
int height = getMeasuredHeight() + extraVerticalSpace;
getTargetObjectLocation(mTempRect);
- DragLayer dragLayer = mLauncher.getDragLayer();
+ InsettableFrameLayout dragLayer = getPopupContainer();
Rect insets = dragLayer.getInsets();
// Align left (right in RTL) if there is room.
@@ -301,12 +304,11 @@
return;
}
- DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
- DragLayer.LayoutParams arrowLp = (DragLayer.LayoutParams) mArrow.getLayoutParams();
+ FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
+ FrameLayout.LayoutParams arrowLp = (FrameLayout.LayoutParams) mArrow.getLayoutParams();
if (mIsAboveIcon) {
arrowLp.gravity = lp.gravity = Gravity.BOTTOM;
- lp.bottomMargin =
- mLauncher.getDragLayer().getHeight() - y - getMeasuredHeight() - insets.top;
+ lp.bottomMargin = getPopupContainer().getHeight() - y - getMeasuredHeight() - insets.top;
arrowLp.bottomMargin = lp.bottomMargin - arrowLp.height - mArrayOffset - insets.bottom;
} else {
arrowLp.gravity = lp.gravity = Gravity.TOP;
@@ -320,7 +322,7 @@
super.onLayout(changed, l, t, r, b);
// enforce contained is within screen
- DragLayer dragLayer = mLauncher.getDragLayer();
+ ViewGroup dragLayer = getPopupContainer();
if (getTranslationX() + l < 0 || getTranslationX() + r > dragLayer.getWidth()) {
// If we are still off screen, center horizontally too.
mGravity |= Gravity.CENTER_HORIZONTAL;
@@ -454,7 +456,11 @@
}
mIsOpen = false;
mDeferContainerRemoval = false;
- mLauncher.getDragLayer().removeView(this);
- mLauncher.getDragLayer().removeView(mArrow);
+ getPopupContainer().removeView(this);
+ getPopupContainer().removeView(mArrow);
+ }
+
+ protected BaseDragLayer getPopupContainer() {
+ return mLauncher.getDragLayer();
}
}
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 172cf41..635e043 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -55,7 +55,6 @@
import com.android.launcher3.accessibility.ShortcutMenuAccessibilityDelegate;
import com.android.launcher3.badge.BadgeInfo;
import com.android.launcher3.dragndrop.DragController;
-import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.logging.LoggerUtils;
@@ -65,8 +64,10 @@
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
+import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.views.BaseDragLayer;
import java.util.ArrayList;
import java.util.List;
@@ -146,10 +147,14 @@
command, mOriginalIcon, ContainerType.DEEPSHORTCUTS);
}
+ public OnClickListener getItemClickListener() {
+ return ItemClickHandler.INSTANCE;
+ }
+
@Override
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- DragLayer dl = mLauncher.getDragLayer();
+ BaseDragLayer dl = getPopupContainer();
if (!dl.isEventOverView(this, ev)) {
mLauncher.getUserEventDispatcher().logActionTapOutside(
LoggerUtils.newContainerTarget(ContainerType.DEEPSHORTCUTS));
@@ -215,7 +220,7 @@
}
@TargetApi(Build.VERSION_CODES.P)
- private void populateAndShow(final BubbleTextView originalIcon, final List<String> shortcutIds,
+ protected void populateAndShow(final BubbleTextView originalIcon, final List<String> shortcutIds,
final List<NotificationKeyData> notificationKeys, List<SystemShortcut> systemShortcuts) {
mNumNotifications = notificationKeys.size();
mOriginalIcon = originalIcon;
@@ -293,7 +298,7 @@
@Override
protected void getTargetObjectLocation(Rect outPos) {
- mLauncher.getDragLayer().getDescendantRectRelativeToSelf(mOriginalIcon, outPos);
+ getPopupContainer().getDescendantRectRelativeToSelf(mOriginalIcon, outPos);
outPos.top += mOriginalIcon.getPaddingTop();
outPos.left += mOriginalIcon.getPaddingLeft();
outPos.right -= mOriginalIcon.getPaddingRight();
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index 3c1cc90..693e532 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -75,6 +75,7 @@
public View.OnClickListener getOnClickListener(
BaseDraggingActivity activity, ItemInfo itemInfo) {
return (view) -> {
+ dismissTaskMenuView(activity);
Rect sourceBounds = activity.getViewBounds(view);
Bundle opts = activity.getActivityLaunchOptionsAsBundle(view);
new PackageManagerHelper(activity).startDetailsActivityForInfo(
@@ -117,4 +118,9 @@
};
}
}
+
+ protected static void dismissTaskMenuView(BaseDraggingActivity activity) {
+ AbstractFloatingView.closeOpenViews(activity, true,
+ AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE);
+ }
}
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutView.java b/src/com/android/launcher3/shortcuts/DeepShortcutView.java
index 9ad266b..7d0ea7b 100644
--- a/src/com/android/launcher3/shortcuts/DeepShortcutView.java
+++ b/src/com/android/launcher3/shortcuts/DeepShortcutView.java
@@ -121,7 +121,7 @@
mBubbleText.setText(usingLongLabel ? longLabel : mDetail.getShortLabel());
// TODO: Add the click handler to this view directly and not the child view.
- mBubbleText.setOnClickListener(ItemClickHandler.INSTANCE);
+ mBubbleText.setOnClickListener(container.getItemClickListener());
mBubbleText.setOnLongClickListener(container);
mBubbleText.setOnTouchListener(container);
}
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index f2f5592..97f836f 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -162,7 +162,7 @@
*
* @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.
*/
- private static void onClickAppShortcut(View v, ShortcutInfo shortcut, Launcher launcher) {
+ public static void onClickAppShortcut(View v, ShortcutInfo shortcut, Launcher launcher) {
if (shortcut.isDisabled()) {
final int disabledFlags = shortcut.runtimeStatusFlags & ShortcutInfo.FLAG_DISABLED_MASK;
if ((disabledFlags &
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
new file mode 100644
index 0000000..04100af
--- /dev/null
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.views;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.view.ContextThemeWrapper;
+
+/**
+ * An interface to be used along with a context. This allows a generic class to depend on Context
+ * subclass instead of an Activity.
+ */
+public interface ActivityContext {
+
+ default boolean finishAutoCancelActionMode() {
+ return false;
+ }
+
+ BaseDragLayer getDragLayer();
+
+ static ActivityContext lookupContext(Context context) {
+ if (context instanceof ActivityContext) {
+ return (ActivityContext) context;
+ } else if (context instanceof ContextThemeWrapper) {
+ return lookupContext(((ContextWrapper) context).getBaseContext());
+ } else {
+ throw new IllegalArgumentException("Cannot find ActivityContext in parent tree");
+ }
+ }
+}
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index 8457b2b..e8a879f 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -28,8 +28,6 @@
import android.widget.FrameLayout;
import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.BaseActivity;
-import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.MultiValueAlpha;
@@ -41,7 +39,8 @@
/**
* A viewgroup with utility methods for drag-n-drop and touch interception
*/
-public abstract class BaseDragLayer<T extends BaseDraggingActivity> extends InsettableFrameLayout {
+public abstract class BaseDragLayer<T extends Context & ActivityContext>
+ extends InsettableFrameLayout {
protected final int[] mTmpXY = new int[2];
protected final Rect mHitRect = new Rect();
@@ -55,7 +54,7 @@
public BaseDragLayer(Context context, AttributeSet attrs, int alphaChannelCount) {
super(context, attrs);
- mActivity = (T) BaseActivity.fromContext(context);
+ mActivity = (T) ActivityContext.lookupContext(context);
mMultiValueAlpha = new MultiValueAlpha(this, alphaChannelCount);
}
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index db4c492..5046639 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -94,7 +94,7 @@
if (ev.getAction() != MotionEvent.ACTION_DOWN) {
return false;
}
- if (mLauncher.getDragLayer().isEventOverView(this, ev)) {
+ if (getPopupContainer().isEventOverView(this, ev)) {
return false;
}
close(true);
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
index 5a7e50f..0d727fd 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
@@ -48,6 +48,8 @@
public static void onStart(Launcher launcher) { }
+ public static void onEnterAnimationComplete(Context context) {}
+
public static void onLauncherStateOrResumeChanged(Launcher launcher) { }
public static void onTrimMemory(Launcher launcher, int level) { }
diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml
index af8b15c..89ca7f3 100644
--- a/tests/AndroidManifest-common.xml
+++ b/tests/AndroidManifest-common.xml
@@ -31,7 +31,6 @@
android:resource="@xml/appwidget_no_config" />
</receiver>
-
<receiver
android:name="com.android.launcher3.testcomponent.AppWdigetHidden"
android:label="Hidden widget">