diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2018-01-03 23:20:28 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2018-01-03 23:20:28 +0000 |
commit | a92638ab7d4957dd2dbff50c818f65492430967f (patch) | |
tree | 1663b308585b50682131138bf22056a94aff918e /quickstep | |
parent | cd7431d9256979e11faefb87912f888eb8b99258 (diff) | |
parent | 2a0659b223db5f8f8c5e6eec2d92c6290270ea9a (diff) | |
download | android_packages_apps_Trebuchet-a92638ab7d4957dd2dbff50c818f65492430967f.tar.gz android_packages_apps_Trebuchet-a92638ab7d4957dd2dbff50c818f65492430967f.tar.bz2 android_packages_apps_Trebuchet-a92638ab7d4957dd2dbff50c818f65492430967f.zip |
Merge "Two state swipe interaction fixes" into ub-launcher3-master
Diffstat (limited to 'quickstep')
6 files changed, 217 insertions, 137 deletions
diff --git a/quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java index 435d57e7e..410a36f04 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java @@ -29,7 +29,6 @@ import android.animation.ValueAnimator.AnimatorUpdateListener; import android.support.animation.SpringAnimation; import android.util.Log; import android.view.MotionEvent; -import android.view.animation.Interpolator; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.Launcher; @@ -42,7 +41,6 @@ import com.android.launcher3.allapps.AllAppsContainerView; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorSetBuilder; -import com.android.launcher3.anim.Interpolators; import com.android.launcher3.anim.SpringAnimationHandler; import com.android.launcher3.touch.SwipeDetector; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; @@ -50,6 +48,10 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.util.FloatRange; import com.android.launcher3.util.TouchController; +import com.android.quickstep.RecentsModel; +import com.android.quickstep.RecentsView; +import com.android.quickstep.TouchInteractionService; +import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan; import java.util.ArrayList; @@ -86,6 +88,8 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter private static final int FLAG_OVERVIEW_DISABLED_OUT_OF_RANGE = 1 << 0; private static final int FLAG_OVERVIEW_DISABLED_FLING = 1 << 1; private static final int FLAG_OVERVIEW_DISABLED_CANCEL_STATE = 1 << 2; + private static final int FLAG_RECENTS_PLAN_LOADING = 1 << 3; + private static final int FLAG_OVERVIEW_DISABLED = 1 << 4; private final Launcher mLauncher; private final SwipeDetector mDetector; @@ -98,9 +102,10 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter private TaggedAnimatorSetBuilder mTaggedAnimatorSetBuilder; private AnimatorSet mQuickOverviewAnimation; private boolean mAnimatingToOverview; - private TwoStateAnimationController mTwoStateAnimationController; + private CroppedAnimationController mCroppedAnimationController; private AnimatorPlaybackController mCurrentAnimation; + private LauncherState mFromState; private LauncherState mToState; private float mStartProgress; @@ -240,11 +245,27 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter + MAX_PROGRESS_TO_OVERVIEW - MIN_PROGRESS_TO_OVERVIEW; // Build current animation + mFromState = mLauncher.getStateManager().getState(); mToState = mLauncher.isInState(ALL_APPS) ? NORMAL : ALL_APPS; mTaggedAnimatorSetBuilder = new TaggedAnimatorSetBuilder(); mCurrentAnimation = mLauncher.getStateManager().createAnimationToNewWorkspace( mToState, mTaggedAnimatorSetBuilder, maxAccuracy); + if (TouchInteractionService.isConnected()) { + // Load recents plan + RecentsModel recentsModel = RecentsModel.getInstance(mLauncher); + if (recentsModel.getLastLoadPlan() != null) { + onRecentsPlanLoaded(recentsModel.getLastLoadPlan()); + } else { + mDragPauseDetector.addDisabledFlags(FLAG_RECENTS_PLAN_LOADING); + } + // Reload again so that we get the latest list + // TODO: Use callback instead of polling everytime + recentsModel.loadTasks(-1, this::onRecentsPlanLoaded); + } else { + mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED); + } + mCurrentAnimation.getTarget().addListener(this); mStartProgress = 0; mProgressMultiplier = (mLauncher.isInState(ALL_APPS) ? 1 : -1) / range; @@ -262,6 +283,14 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter } } + private void onRecentsPlanLoaded(RecentsTaskLoadPlan plan) { + RecentsView recentsView = mLauncher.getOverviewPanel(); + recentsView.update(plan); + recentsView.initToPage(0); + + mDragPauseDetector.clearDisabledFlags(FLAG_RECENTS_PLAN_LOADING); + } + private float getShiftRange() { return mLauncher.getAllAppsController().getShiftRange(); } @@ -287,16 +316,11 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter @Override public void onDragEnd(float velocity, boolean fling) { - if (!fling && mDragPauseDetector.isEnabled() && mDragPauseDetector.isTriggered()) { - snapToOverview(velocity); - return; - } - mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED_FLING); final long animationDuration; final int logAction; - final LauncherState targetState; + LauncherState targetState; final float progress = mCurrentAnimation.getProgressFraction(); if (fling) { @@ -317,7 +341,7 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter targetState = mToState; animationDuration = SwipeDetector.calculateDuration(velocity, 1 - progress); } else { - targetState = mToState == ALL_APPS ? NORMAL : ALL_APPS; + targetState = mFromState; animationDuration = SwipeDetector.calculateDuration(velocity, progress); } } @@ -328,7 +352,13 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter h.animateToFinalPosition(0 /* pos */, 1 /* startValue */); } } - mCurrentAnimation.setEndAction(() -> onSwipeInteractionCompleted(targetState, logAction)); + mCurrentAnimation.setEndAction(() -> { + LauncherState finalState = targetState; + if (mDragPauseDetector.isTriggered() && targetState == NORMAL) { + finalState = OVERVIEW; + } + onSwipeInteractionCompleted(finalState, logAction); + }); float nextFrameProgress = Utilities.boundToRange( progress + velocity * SINGLE_FRAME_MS / getShiftRange(), 0f, 1f); @@ -341,7 +371,7 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter } private void onSwipeInteractionCompleted(LauncherState targetState, int logAction) { - if (targetState == mToState) { + if (targetState != mFromState) { // Transition complete. log the action mLauncher.getUserEventDispatcher().logActionOnContainer(logAction, mToState == ALL_APPS ? Direction.UP : Direction.DOWN, @@ -354,33 +384,6 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter mLauncher.getStateManager().goToState(targetState, false /* animated */); } - private void snapToOverview(float velocity) { - mAnimatingToOverview = true; - - final float progress = mCurrentAnimation.getProgressFraction(); - float endProgress = mToState == NORMAL ? 1f : 0f; - long animationDuration = SwipeDetector.calculateDuration( - velocity, Math.abs(endProgress - progress)); - float nextFrameProgress = Utilities.boundToRange( - progress + velocity * SINGLE_FRAME_MS / getShiftRange(), 0f, 1f); - - mCurrentAnimation.setEndAction(() -> { - // TODO: Add logging - clearState(); - mLauncher.getStateManager().goToState(OVERVIEW, true /* animated */); - }); - - if (mTwoStateAnimationController != null) { - mTwoStateAnimationController.goBackToStart(endProgress); - } - - ValueAnimator anim = mCurrentAnimation.getAnimationPlayer(); - anim.setFloatValues(nextFrameProgress, endProgress); - anim.setDuration(animationDuration); - anim.setInterpolator(scrollInterpolatorForVelocity(velocity)); - anim.start(); - } - private void onDragPauseDetected() { final ValueAnimator twoStepAnimator = ValueAnimator.ofFloat(0, 1); twoStepAnimator.setDuration(mCurrentAnimation.getDuration()); @@ -409,33 +412,29 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter mQuickOverviewAnimation.start(); } - private void onQuickOverviewAnimationComplete(ValueAnimator twoStepAnimator) { + private void onQuickOverviewAnimationComplete(ValueAnimator animator) { if (mAnimatingToOverview) { return; } - // The remaining state handlers are on the OVERVIEW state. Create two animations, one - // towards the NORMAL state and one towards ALL_APPS state and control them based on the - // swipe progress. + // For the remainder to the interaction, the user can either go to the ALL_APPS state or + // the OVERVIEW state. + // The remaining state handlers are on the OVERVIEW state. Create one animation towards the + // ALL_APPS state and only call it when the user moved above the current range. AnimationConfig config = new AnimationConfig(); config.duration = (long) (2 * getShiftRange()); config.userControlled = true; - LauncherState fromState = mToState == ALL_APPS ? NORMAL : ALL_APPS; - AnimatorSetBuilder builderToTargetState = new AnimatorSetBuilder(); - AnimatorSetBuilder builderToSourceState = new AnimatorSetBuilder(); - + AnimatorSetBuilder builderToAllAppsState = new AnimatorSetBuilder(); StateHandler[] handlers = mLauncher.getStateManager().getStateHandlers(); for (int i = OTHER_HANDLERS_START_INDEX; i < handlers.length; i++) { - handlers[i].setStateWithAnimation(mToState, builderToTargetState, config); - handlers[i].setStateWithAnimation(fromState, builderToSourceState, config); + handlers[i].setStateWithAnimation(ALL_APPS, builderToAllAppsState, config); } - mTwoStateAnimationController = new TwoStateAnimationController( - AnimatorPlaybackController.wrap(builderToSourceState.build(), config.duration), - AnimatorPlaybackController.wrap(builderToTargetState.build(), config.duration), - twoStepAnimator.getAnimatedFraction()); - twoStepAnimator.addUpdateListener(mTwoStateAnimationController); + mCroppedAnimationController = new CroppedAnimationController( + AnimatorPlaybackController.wrap(builderToAllAppsState.build(), config.duration), + new FloatRange(animator.getAnimatedFraction(), mToState == ALL_APPS ? 1 : 0)); + animator.addUpdateListener(mCroppedAnimationController); } private void clearState() { @@ -450,69 +449,49 @@ public class TwoStepSwipeController extends AnimatorListenerAdapter mQuickOverviewAnimation.cancel(); mQuickOverviewAnimation = null; } - mTwoStateAnimationController = null; + mCroppedAnimationController = null; mAnimatingToOverview = false; mDetector.finishedScrolling(); } /** - * {@link AnimatorUpdateListener} which interpolates two animations based the progress + * {@link AnimatorUpdateListener} which controls another animation for a fraction of range */ - private static class TwoStateAnimationController implements AnimatorUpdateListener { - - private final AnimatorPlaybackController mControllerTowardsStart; - private final AnimatorPlaybackController mControllerTowardsEnd; + private static class CroppedAnimationController implements AnimatorUpdateListener { - private Interpolator mInterpolator = Interpolators.LINEAR; - private float mStartFraction; - private float mLastFraction; + private final AnimatorPlaybackController mTarget; + private final FloatRange mRange; - TwoStateAnimationController(AnimatorPlaybackController controllerTowardsStart, - AnimatorPlaybackController controllerTowardsEnd, float startFraction) { - mControllerTowardsStart = controllerTowardsStart; - mControllerTowardsEnd = controllerTowardsEnd; - mLastFraction = mStartFraction = startFraction; + CroppedAnimationController(AnimatorPlaybackController target, FloatRange range) { + mTarget = target; + mRange = range; } + @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { - mLastFraction = mInterpolator.getInterpolation(valueAnimator.getAnimatedFraction()); - if (mLastFraction > mStartFraction) { - if (mStartFraction >= 1) { - mControllerTowardsEnd.setPlayFraction(0); + float fraction = valueAnimator.getAnimatedFraction(); + + if (mRange.start < mRange.end) { + if (fraction <= mRange.start) { + mTarget.setPlayFraction(0); + } else if (fraction >= mRange.end) { + mTarget.setPlayFraction(1); } else { - mControllerTowardsEnd.setPlayFraction( - (mLastFraction - mStartFraction) / (1 - mStartFraction)); + mTarget.setPlayFraction((fraction - mRange.start) / (mRange.end - mRange.start)); } - } else { - if (mStartFraction <= 0) { - mControllerTowardsStart.setPlayFraction(0); + } else if (mRange.start > mRange.end) { + if (fraction >= mRange.start) { + mTarget.setPlayFraction(0); + } else if (fraction <= mRange.end) { + mTarget.setPlayFraction(1); } else { - mControllerTowardsStart.setPlayFraction( - (mStartFraction - mLastFraction) / mStartFraction); + mTarget.setPlayFraction((fraction - mRange.start) / (mRange.end - mRange.start)); } - } - } - - /** - * Changes the interpolator such that from this point ({@link #mLastFraction}), the - * animation run towards {@link #mStartFraction}. This allows us to animate the UI back - * to the original point. - * @param endFraction expected end point for this animation. Should either be 0 or 1. - */ - public void goBackToStart(float endFraction) { - if (mLastFraction == mStartFraction || mLastFraction == endFraction) { - mInterpolator = (v) -> mStartFraction; - } else if (mLastFraction > mStartFraction && endFraction < mStartFraction) { - mInterpolator = (v) -> Math.max(v, mStartFraction); - } else if (mLastFraction < mStartFraction && endFraction > mStartFraction) { - mInterpolator = (v) -> Math.min(mStartFraction, v); } else { - final float start = mLastFraction; - final float range = endFraction - mLastFraction; - mInterpolator = (v) -> - SwipeDetector.interpolate(start, mStartFraction, (v - start) / range); + // mRange.start == mRange.end + mTarget.setPlayFraction(0); } } } diff --git a/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java b/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java index 095b44518..09fd8f02a 100644 --- a/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java +++ b/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java @@ -44,6 +44,7 @@ import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.states.InternalStateHandler; import com.android.launcher3.uioverrides.RecentsViewStateController; import com.android.launcher3.util.TraceHelper; +import com.android.launcher3.views.AllAppsScrim; import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.Task.TaskKey; @@ -97,6 +98,7 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler { private RecentsView mRecentsView; private RecentsViewStateController mStateController; private Hotseat mHotseat; + private AllAppsScrim mAllAppsScrim; private RecentsTaskLoadPlan mLoadPlan; private boolean mLauncherReady; @@ -182,6 +184,7 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler { mRecentsView = mLauncher.getOverviewPanel(); mStateController = mRecentsView.getStateController(); mHotseat = mLauncher.getHotseat(); + mAllAppsScrim = mLauncher.findViewById(R.id.all_apps_scrim); // Optimization mLauncher.getAppsView().setVisibility(View.GONE); @@ -222,7 +225,9 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler { float shift = mCurrentShift.value * mActivityMultiplier.value; int hotseatSize = getHotseatSize(); - mHotseat.setTranslationY((1 - shift) * hotseatSize); + float hotseatTranslation = (1 - shift) * hotseatSize; + mHotseat.setTranslationY(hotseatTranslation); + mAllAppsScrim.setTranslationY(hotseatTranslation); mRectEvaluator.evaluate(shift, mSourceRect, mTargetRect); @@ -324,6 +329,7 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler { private void cleanupLauncher() { // TODO: These should be done as part of ActivityOptions#OnAnimationStarted mHotseat.setTranslationY(0); + mAllAppsScrim.setTranslationY(0); mLauncher.setOnResumeCallback(() -> mDragView.close(false)); } diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java new file mode 100644 index 000000000..112f1569c --- /dev/null +++ b/quickstep/src/com/android/quickstep/RecentsModel.java @@ -0,0 +1,104 @@ +/* + * 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.quickstep; + +import android.content.Context; +import android.content.res.Resources; +import android.os.Looper; +import android.os.UserHandle; + +import com.android.launcher3.MainThreadExecutor; +import com.android.launcher3.R; +import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan; +import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan.PreloadOptions; +import com.android.systemui.shared.recents.model.RecentsTaskLoader; +import com.android.systemui.shared.system.BackgroundExecutor; + +import java.util.concurrent.ExecutionException; +import java.util.function.Consumer; + +/** + * Singleton class to load and manage recents model. + */ +public class RecentsModel { + + // We do not need any synchronization for this variable as its only written on UI thread. + private static RecentsModel INSTANCE; + + public static RecentsModel getInstance(final Context context) { + if (INSTANCE == null) { + if (Looper.myLooper() == Looper.getMainLooper()) { + INSTANCE = new RecentsModel(context.getApplicationContext()); + } else { + try { + return new MainThreadExecutor().submit( + () -> RecentsModel.getInstance(context)).get(); + } catch (InterruptedException|ExecutionException e) { + throw new RuntimeException(e); + } + } + } + return INSTANCE; + } + + private final Context mContext; + private final RecentsTaskLoader mRecentsTaskLoader; + private final MainThreadExecutor mMainThreadExecutor; + + private RecentsTaskLoadPlan mLastLoadPlan; + private RecentsModel(Context context) { + mContext = context; + + Resources res = context.getResources(); + mRecentsTaskLoader = new RecentsTaskLoader(mContext, + res.getInteger(R.integer.config_recentsMaxThumbnailCacheSize), + res.getInteger(R.integer.config_recentsMaxIconCacheSize), 0); + mRecentsTaskLoader.startLoader(mContext); + + mMainThreadExecutor = new MainThreadExecutor(); + } + + public RecentsTaskLoader getRecentsTaskLoader() { + return mRecentsTaskLoader; + } + + /** + * Preloads the task plan + * @param taskId The running task id or -1 + * @param callback The callback to receive the task plan once its complete or null. This is + * always called on the UI thread. + */ + public void loadTasks(int taskId, Consumer<RecentsTaskLoadPlan> callback) { + BackgroundExecutor.get().submit(() -> { + // Preload the plan + RecentsTaskLoadPlan loadPlan = new RecentsTaskLoadPlan(mContext); + PreloadOptions opts = new PreloadOptions(); + opts.loadTitles = false; + loadPlan.preloadPlan(opts, mRecentsTaskLoader, taskId, UserHandle.myUserId()); + // Set the load plan on UI thread + mMainThreadExecutor.execute(() -> { + mLastLoadPlan = loadPlan; + if (callback != null) { + callback.accept(loadPlan); + } + }); + }); + } + + public RecentsTaskLoadPlan getLastLoadPlan() { + return mLastLoadPlan; + } +} diff --git a/quickstep/src/com/android/quickstep/RecentsView.java b/quickstep/src/com/android/quickstep/RecentsView.java index 6161858cb..00901c686 100644 --- a/quickstep/src/com/android/quickstep/RecentsView.java +++ b/quickstep/src/com/android/quickstep/RecentsView.java @@ -146,7 +146,8 @@ public class RecentsView extends PagedView { } public void update(RecentsTaskLoadPlan loadPlan) { - final RecentsTaskLoader loader = TouchInteractionService.getRecentsTaskLoader(); + final RecentsTaskLoader loader = RecentsModel.getInstance(getContext()) + .getRecentsTaskLoader(); TaskStack stack = loadPlan != null ? loadPlan.getTaskStack() : null; if (stack == null) { removeAllViews(); diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/TaskThumbnailView.java index 4a9bfead5..3d4d45117 100644 --- a/quickstep/src/com/android/quickstep/TaskThumbnailView.java +++ b/quickstep/src/com/android/quickstep/TaskThumbnailView.java @@ -173,4 +173,10 @@ public class TaskThumbnailView extends FrameLayout { } invalidate(); } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + updateThumbnailMatrix(); + } } diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index f457a59cb..432179135 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -28,10 +28,8 @@ import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityOptions; import android.app.Service; import android.content.ComponentName; -import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; -import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.PointF; @@ -39,7 +37,6 @@ import android.graphics.Rect; import android.os.Build; import android.os.IBinder; import android.os.RemoteException; -import android.os.UserHandle; import android.util.Log; import android.view.Choreographer; import android.view.Display; @@ -52,14 +49,9 @@ import android.view.WindowManager; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; -import com.android.launcher3.MainThreadExecutor; -import com.android.launcher3.R; import com.android.launcher3.util.TraceHelper; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.ISystemUiProxy; -import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan; -import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan.PreloadOptions; -import com.android.systemui.shared.recents.model.RecentsTaskLoader; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.BackgroundExecutor; import com.android.systemui.shared.system.WindowManagerWrapper; @@ -74,8 +66,6 @@ public class TouchInteractionService extends Service { private static final String TAG = "TouchInteractionService"; - private static RecentsTaskLoader sRecentsTaskLoader; - private final IBinder mMyBinder = new IOverviewProxy.Stub() { @Override @@ -93,12 +83,18 @@ public class TouchInteractionService extends Service { = this::handleTouchDownOnOtherActivity; private final Consumer<MotionEvent> mNoOpTouchConsumer = (ev) -> {}; + private static boolean sConnected = false; + + public static boolean isConnected() { + return sConnected; + } + private ActivityManagerWrapper mAM; private RunningTaskInfo mRunningTask; + private RecentsModel mRecentsModel; private Intent mHomeIntent; private ComponentName mLauncher; private MotionEventQueue mEventQueue; - private MainThreadExecutor mMainThreadExecutor; private final PointF mDownPos = new PointF(); private final PointF mLastPos = new PointF(); @@ -117,6 +113,7 @@ public class TouchInteractionService extends Service { public void onCreate() { super.onCreate(); mAM = ActivityManagerWrapper.getInstance(); + mRecentsModel = RecentsModel.getInstance(this); mHomeIntent = new Intent(Intent.ACTION_MAIN) .addCategory(Intent.CATEGORY_HOME) @@ -126,16 +123,15 @@ public class TouchInteractionService extends Service { mLauncher = new ComponentName(getPackageName(), info.activityInfo.name); mHomeIntent.setComponent(mLauncher); - Resources res = getResources(); - if (sRecentsTaskLoader == null) { - sRecentsTaskLoader = new RecentsTaskLoader(this, - res.getInteger(R.integer.config_recentsMaxThumbnailCacheSize), - res.getInteger(R.integer.config_recentsMaxIconCacheSize), 0); - sRecentsTaskLoader.startLoader(this); - } - - mMainThreadExecutor = new MainThreadExecutor(); mEventQueue = new MotionEventQueue(Choreographer.getInstance(), this::handleMotionEvent); + mRecentsModel.loadTasks(-1, null); + sConnected = true; + } + + @Override + public void onDestroy() { + sConnected = false; + super.onDestroy(); } @Override @@ -144,10 +140,6 @@ public class TouchInteractionService extends Service { return mMyBinder; } - public static RecentsTaskLoader getRecentsTaskLoader() { - return sRecentsTaskLoader; - } - private void handleMotionEvent(MotionEvent ev) { if (ev.getActionMasked() == ACTION_DOWN) { mRunningTask = mAM.getRunningTask(); @@ -255,12 +247,9 @@ public class TouchInteractionService extends Service { final NavBarSwipeInteractionHandler handler = new NavBarSwipeInteractionHandler(mRunningTask, this); - // Preload and start the recents activity on a background thread - final Context context = this; - final RecentsTaskLoadPlan loadPlan = new RecentsTaskLoadPlan(context); - final int taskId = mRunningTask.id; TraceHelper.partitionSection("TouchInt", "Thershold crossed "); + // Start the recents activity on a background thread BackgroundExecutor.get().submit(() -> { // Get the snap shot before handler.setTaskSnapshot(getCurrentTaskSnapshot()); @@ -275,15 +264,10 @@ public class TouchInteractionService extends Service { ActivityOptions.makeCustomAnimation(this, 0, 0), UserHandle.myUserId(), null, null); */ - - // Preload the plan - RecentsTaskLoader loader = TouchInteractionService.getRecentsTaskLoader(); - PreloadOptions opts = new PreloadOptions(); - opts.loadTitles = false; - loadPlan.preloadPlan(opts, loader, taskId, UserHandle.myUserId()); - // Set the load plan on UI thread - mMainThreadExecutor.execute(() -> handler.setRecentsTaskLoadPlan(loadPlan)); }); + + // Preload the plan + mRecentsModel.loadTasks(mRunningTask.id, handler::setRecentsTaskLoadPlan); mInteractionHandler = handler; } |