Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5ab4907 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 9898483 from 4bce4f61 to tm-qpr3-release

Change-Id: I4d9ddcaa428f57d567e8c0125b5d6d879bad5800
parents d4dba092 4bce4f61
Loading
Loading
Loading
Loading
+83 −41
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_I
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -43,6 +44,7 @@ import android.animation.AnimatorSet;
import android.app.RemoteAction;
import android.content.SharedPreferences;
import android.graphics.drawable.Icon;
import android.os.SystemClock;
import android.util.Log;
import android.view.InsetsController;
import android.view.View;
@@ -187,6 +189,10 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
    // Auto stashes when user has not interacted with the Taskbar after X ms.
    private static final long NO_TOUCH_TIMEOUT_TO_STASH_MS = 5000;

    // Duration for which an unlock event is considered "current", as other events are received
    // asynchronously.
    private static final long UNLOCK_TRANSITION_MEMOIZATION_MS = 200;

    /**
     * The default stash animation, morphing the taskbar into the navbar.
     */
@@ -743,56 +749,77 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba

    private void createTransientAnimToIsStashed(AnimatorSet as, boolean isStashed, long duration,
            @StashAnimation int animationType) {
        Interpolator skipInterpolator = null;
        // Target values of the properties this is going to set
        final float backgroundOffsetTarget = isStashed ? 1 : 0;
        final float iconAlphaTarget = isStashed ? 0 : 1;
        final float stashedHandleAlphaTarget = isStashed ? 1 : 0;

        // Timing for the alpha values depend on the animation played
        long iconAlphaStartDelay = 0, iconAlphaDuration = 0, stashedHandleAlphaDelay = 0,
                stashedHandleAlphaDuration = 0;
        if (duration > 0) {
            if (animationType == TRANSITION_HANDLE_FADE) {
                // When fading, the handle fades in/out at the beginning of the transition with
                // TASKBAR_STASH_ALPHA_DURATION.
                stashedHandleAlphaDuration = TASKBAR_STASH_ALPHA_DURATION;
                // The iconAlphaDuration must be set to duration for the skippable interpolators
                // below to work.
                iconAlphaDuration = duration;
            } else {
                iconAlphaStartDelay = TASKBAR_STASH_ALPHA_START_DELAY;
                iconAlphaDuration = TASKBAR_STASH_ALPHA_DURATION;
                stashedHandleAlphaDuration = TASKBAR_STASH_ALPHA_DURATION;

                if (isStashed) {
            play(as, mTaskbarBackgroundOffset.animateToValue(1), 0, duration, EMPHASIZED);
                    if (animationType == TRANSITION_HOME_TO_APP) {
                        iconAlphaStartDelay = TASKBAR_STASH_ICON_ALPHA_HOME_TO_APP_START_DELAY;
                    }
                    stashedHandleAlphaDelay = iconAlphaStartDelay;
                    stashedHandleAlphaDuration = Math.max(0, duration - iconAlphaStartDelay);
                }

            long alphaStartDelay = duration == 0 ? 0 : animationType == TRANSITION_HOME_TO_APP
                    ? TASKBAR_STASH_ICON_ALPHA_HOME_TO_APP_START_DELAY
                    : TASKBAR_STASH_ALPHA_START_DELAY;
            long alphaDuration = duration == 0 ? 0 : TASKBAR_STASH_ALPHA_DURATION;
            play(as, mIconAlphaForStash.animateToValue(0), alphaStartDelay, alphaDuration, LINEAR);
            play(as, mTaskbarStashedHandleAlpha.animateToValue(1), alphaStartDelay,
                    Math.max(0, duration - alphaStartDelay), LINEAR);
            }
        }

            play(as, mControllers.taskbarSpringOnStashController.createSpringToStash(), 0, duration,
                    LINEAR);
        play(as, mTaskbarStashedHandleAlpha.animateToValue(stashedHandleAlphaTarget),
                stashedHandleAlphaDelay,
                stashedHandleAlphaDuration, LINEAR);

        // The rest of the animations might be "skipped" in TRANSITION_HANDLE_FADE transitions.
        AnimatorSet skippable = as;
        if (animationType == TRANSITION_HANDLE_FADE) {
                skipInterpolator = INSTANT;
            skippable = new AnimatorSet();
            as.play(skippable);
            skippable.setInterpolator(isStashed ? INSTANT : FINAL_FRAME);
        }
        } else  {

        final boolean animateBg = animationType != TRANSITION_UNSTASH_SUW_MANUAL;
        if (animateBg) {
                play(as, mTaskbarBackgroundOffset.animateToValue(0), 0, duration, EMPHASIZED);
            play(skippable, mTaskbarBackgroundOffset.animateToValue(backgroundOffsetTarget), 0,
                    duration, EMPHASIZED);
        } else {
                as.addListener(AnimatorListeners.forEndCallback(
                        () -> mTaskbarBackgroundOffset.updateValue(0)));
            skippable.addListener(AnimatorListeners.forEndCallback(
                    () -> mTaskbarBackgroundOffset.updateValue(backgroundOffsetTarget)));
        }

            long alphaStartDelay = duration == 0 ? 0 : TASKBAR_STASH_ALPHA_START_DELAY;
            long alphaDuration = duration == 0 ? 0 : TASKBAR_STASH_ALPHA_DURATION;
            play(as, mIconAlphaForStash.animateToValue(1), alphaStartDelay, alphaDuration, LINEAR);
            play(as, mTaskbarStashedHandleAlpha.animateToValue(0), 0, alphaDuration, LINEAR);
        play(skippable, mIconAlphaForStash.animateToValue(iconAlphaTarget), iconAlphaStartDelay,
                iconAlphaDuration,
                LINEAR);

            if (animationType == TRANSITION_HANDLE_FADE) {
                skipInterpolator = FINAL_FRAME;
            }
        if (isStashed) {
            play(skippable, mControllers.taskbarSpringOnStashController.createSpringToStash(),
                    0, duration, LINEAR);
        }
        mControllers.taskbarViewController.addRevealAnimToIsStashed(as, isStashed, duration,
                EMPHASIZED);

        if (skipInterpolator != null) {
            as.setInterpolator(skipInterpolator);
        }
        mControllers.taskbarViewController.addRevealAnimToIsStashed(skippable, isStashed, duration,
                EMPHASIZED);

        play(as, mControllers.stashedHandleViewController
        play(skippable, mControllers.stashedHandleViewController
                .createRevealAnimToIsStashed(isStashed), 0, duration, EMPHASIZED);

        // Return the stashed handle to its default scale in case it was changed as part of the
        // feedforward hint. Note that the reveal animation above also visually scales it.
        as.play(mTaskbarStashedHandleHintScale.animateToValue(1f)
        skippable.play(mTaskbarStashedHandleHintScale.animateToValue(1f)
                .setDuration(isStashed ? duration / 2 : duration));
    }

@@ -951,7 +978,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
        updateStateForFlag(FLAG_STASHED_SYSUI,
                hasAnyFlag(systemUiStateFlags, SYSUI_STATE_SCREEN_PINNING));

        boolean isLocked = hasAnyFlag(systemUiStateFlags, MASK_ANY_SYSUI_LOCKED);
        boolean isLocked = hasAnyFlag(systemUiStateFlags, MASK_ANY_SYSUI_LOCKED)
                && !hasAnyFlag(systemUiStateFlags, SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY);
        updateStateForFlag(FLAG_STASHED_DEVICE_LOCKED, isLocked);

        // Only update FLAG_STASHED_IN_APP_IME when system gesture is not in progress.
@@ -1169,6 +1197,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
        private @StashAnimation int mLastStartedTransitionType = TRANSITION_DEFAULT;
        private int mPrevFlags;

        private long mLastUnlockTransitionTimeout = 0;

        StatePropertyHolder(IntPredicate stashCondition) {
            mStashCondition = stashCondition;
        }
@@ -1199,6 +1229,17 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
                mPrevFlags = flags;
            }

            boolean isUnlockTransition = hasAnyFlag(changedFlags, FLAG_STASHED_DEVICE_LOCKED)
                    && !hasAnyFlag(FLAG_STASHED_DEVICE_LOCKED);
            if (isUnlockTransition) {
                // the launcher might not be resumed at the time the device is considered
                // unlocked (when the keyguard goes away), but possibly shortly afterwards.
                // To play the unlock transition at the time the unstash animation actually happens,
                // this memoizes the state transition for UNLOCK_TRANSITION_MEMOIZATION_MS.
                mLastUnlockTransitionTimeout =
                        SystemClock.elapsedRealtime() + UNLOCK_TRANSITION_MEMOIZATION_MS;
            }

            @StashAnimation int animationType = computeTransitionType(changedFlags);

            // Allow re-starting animation if upgrading from default animation type, otherwise
@@ -1229,6 +1270,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
        }

        private @StashAnimation int computeTransitionType(int changedFlags) {

            boolean hotseatHiddenDuringAppLaunch =
                    !mControllers.uiController.isHotseatIconOnTopWhenAligned()
                            && hasAnyFlag(changedFlags, FLAG_IN_APP);
@@ -1240,8 +1282,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
                return TRANSITION_HANDLE_FADE;
            }

            boolean isUnlockTransition = hasAnyFlag(changedFlags, FLAG_STASHED_DEVICE_LOCKED)
                    && !hasAnyFlag(FLAG_STASHED_DEVICE_LOCKED);
            boolean isUnlockTransition =
                    SystemClock.elapsedRealtime() < mLastUnlockTransitionTimeout;
            if (isUnlockTransition) {
                // When transitioning to unlocked device, the  hotseat will already be visible on
                // the homescreen, thus do not play an un-stash animation.
+4 −2
Original line number Diff line number Diff line
@@ -244,7 +244,8 @@ public class TaskbarUIController {
                                    taskAttributes.getIconView().getDrawable(),
                                    taskAttributes.getThumbnailView(),
                                    taskAttributes.getThumbnailView().getThumbnail(),
                                    null /* intent */);
                                    null /* intent */,
                                    null /* user */);
                            return;
                        }
                    }
@@ -256,7 +257,8 @@ public class TaskbarUIController {
                            new BitmapDrawable(info.bitmap.icon),
                            startingView,
                            null /* thumbnail */,
                            intent);
                            intent,
                            info.user);
                }
        );
    }
+55 −39
Original line number Diff line number Diff line
@@ -88,11 +88,17 @@ public class SplitSelectStateController {
    private final StateManager mStateManager;
    @Nullable
    private DepthController mDepthController;
    private @StagePosition int mStagePosition;
    private @StagePosition int mInitialStagePosition;
    private ItemInfo mItemInfo;
    /** {@link #mInitialTaskIntent} and {@link #mInitialUser} (the user of the Intent) are set
     * together when split is initiated from an Intent. */
    private Intent mInitialTaskIntent;
    private UserHandle mInitialUser;
    private int mInitialTaskId = INVALID_TASK_ID;
    /** {@link #mSecondTaskIntent} and {@link #mSecondUser} (the user of the Intent) are set
     * together when split is confirmed with an Intent. */
    private Intent mSecondTaskIntent;
    private UserHandle mSecondUser;
    private int mSecondTaskId = INVALID_TASK_ID;
    private boolean mRecentsAnimationRunning;
    /** If {@code true}, animates the existing task view split placeholder view */
@@ -102,8 +108,6 @@ public class SplitSelectStateController {
     * split pair task view without wanting to animate current task dismissal overall
     */
    private boolean mDismissingFromSplitPair;
    @Nullable
    private UserHandle mUser;
    /** If not null, this is the TaskView we want to launch from */
    @Nullable
    private GroupedTaskView mLaunchingTaskView;
@@ -137,7 +141,7 @@ public class SplitSelectStateController {
            mInitialTaskId = alreadyRunningTask;
        } else {
            mInitialTaskIntent = intent;
            mUser = itemInfo.user;
            mInitialUser = itemInfo.user;
        }

        setInitialData(stagePosition, splitEvent, itemInfo);
@@ -157,7 +161,7 @@ public class SplitSelectStateController {
    private void setInitialData(@StagePosition int stagePosition,
            StatsLogManager.EventEnum splitEvent, ItemInfo itemInfo) {
        mItemInfo = itemInfo;
        mStagePosition = stagePosition;
        mInitialStagePosition = stagePosition;
        mSplitEvent = splitEvent;
    }

@@ -214,7 +218,7 @@ public class SplitSelectStateController {
        Pair<InstanceId, com.android.launcher3.logging.InstanceId> instanceIds =
                LogUtils.getShellShareableInstanceId();
        launchTasks(mInitialTaskId, mInitialTaskIntent, mSecondTaskId, mSecondTaskIntent,
                mStagePosition, callback, false /* freezeTaskList */, DEFAULT_SPLIT_RATIO,
                mInitialStagePosition, callback, false /* freezeTaskList */, DEFAULT_SPLIT_RATIO,
                instanceIds.first);

        mStatsLogManager.logger()
@@ -231,8 +235,14 @@ public class SplitSelectStateController {
        mSecondTaskId = task.key.id;
    }

    public void setSecondTask(Intent intent) {
    /**
     * To be called as soon as user selects the second app (even if animations aren't complete)
     * @param intent The second intent that will be launched.
     * @param user The user of that intent.
     */
    public void setSecondTask(Intent intent, UserHandle user) {
        mSecondTaskIntent = intent;
        mSecondUser = user;
    }

    /**
@@ -289,16 +299,17 @@ public class SplitSelectStateController {
                        null /* options2 */, stagePosition, splitRatio, remoteTransition,
                        shellInstanceId);
            } else if (intent2 == null) {
                launchIntentOrShortcut(intent1, options1, taskId2, stagePosition, splitRatio,
                        remoteTransition, shellInstanceId);
                launchIntentOrShortcut(intent1, mInitialUser, options1, taskId2, stagePosition,
                        splitRatio, remoteTransition, shellInstanceId);
            } else if (intent1 == null) {
                launchIntentOrShortcut(intent2, options1, taskId1,
                launchIntentOrShortcut(intent2, mSecondUser, options1, taskId1,
                        getOppositeStagePosition(stagePosition), splitRatio, remoteTransition,
                        shellInstanceId);
            } else {
                mSystemUiProxy.startIntents(getPendingIntent(intent1), options1.toBundle(),
                        getPendingIntent(intent2), null /* options2 */, stagePosition,
                        splitRatio, remoteTransition, shellInstanceId);
                mSystemUiProxy.startIntents(getPendingIntent(intent1, mInitialUser),
                        options1.toBundle(), getPendingIntent(intent2, mSecondUser),
                        null /* options2 */, stagePosition, splitRatio, remoteTransition,
                        shellInstanceId);
            }
        } else {
            final RemoteSplitLaunchAnimationRunner animationRunner =
@@ -312,60 +323,63 @@ public class SplitSelectStateController {
                        taskId2, null /* options2 */, stagePosition, splitRatio, adapter,
                        shellInstanceId);
            } else if (intent2 == null) {
                launchIntentOrShortcutLegacy(intent1, options1, taskId2, stagePosition, splitRatio,
                        adapter, shellInstanceId);
                launchIntentOrShortcutLegacy(intent1, mInitialUser, options1, taskId2,
                        stagePosition, splitRatio, adapter, shellInstanceId);
            } else if (intent1 == null) {
                launchIntentOrShortcutLegacy(intent2, options1, taskId1,
                launchIntentOrShortcutLegacy(intent2, mSecondUser, options1, taskId1,
                        getOppositeStagePosition(stagePosition), splitRatio, adapter,
                        shellInstanceId);
            } else {
                mSystemUiProxy.startIntentsWithLegacyTransition(
                        getPendingIntent(intent1), getShortcutInfo(intent1), options1.toBundle(),
                        getPendingIntent(intent2), getShortcutInfo(intent2), null /* options2 */,
                        stagePosition, splitRatio, adapter, shellInstanceId);
                        getPendingIntent(intent1, mInitialUser),
                        getShortcutInfo(intent1, mInitialUser), options1.toBundle(),
                        getPendingIntent(intent2, mSecondUser),
                        getShortcutInfo(intent2, mSecondUser), null /* options2 */, stagePosition,
                        splitRatio, adapter, shellInstanceId);
            }
        }
    }

    private void launchIntentOrShortcut(Intent intent, ActivityOptions options1, int taskId,
            @StagePosition int stagePosition, float splitRatio, RemoteTransition remoteTransition,
            @Nullable InstanceId shellInstanceId) {
        final ShortcutInfo shortcutInfo = getShortcutInfo(intent);
    private void launchIntentOrShortcut(Intent intent, UserHandle user, ActivityOptions options1,
            int taskId, @StagePosition int stagePosition, float splitRatio,
            RemoteTransition remoteTransition, @Nullable InstanceId shellInstanceId) {
        final ShortcutInfo shortcutInfo = getShortcutInfo(intent, user);
        if (shortcutInfo != null) {
            mSystemUiProxy.startShortcutAndTask(shortcutInfo,
                    options1.toBundle(), taskId, null /* options2 */, stagePosition,
                    splitRatio, remoteTransition, shellInstanceId);
        } else {
            mSystemUiProxy.startIntentAndTask(getPendingIntent(intent), options1.toBundle(), taskId,
                    null /* options2 */, stagePosition, splitRatio, remoteTransition,
                    shellInstanceId);
            mSystemUiProxy.startIntentAndTask(getPendingIntent(intent, user),
                    options1.toBundle(), taskId, null /* options2 */, stagePosition, splitRatio,
                    remoteTransition, shellInstanceId);
        }
    }

    private void launchIntentOrShortcutLegacy(Intent intent, ActivityOptions options1, int taskId,
            @StagePosition int stagePosition, float splitRatio, RemoteAnimationAdapter adapter,
    private void launchIntentOrShortcutLegacy(Intent intent, UserHandle user,
            ActivityOptions options1, int taskId, @StagePosition int stagePosition,
            float splitRatio, RemoteAnimationAdapter adapter,
            @Nullable InstanceId shellInstanceId) {
        final ShortcutInfo shortcutInfo = getShortcutInfo(intent);
        final ShortcutInfo shortcutInfo = getShortcutInfo(intent, user);
        if (shortcutInfo != null) {
            mSystemUiProxy.startShortcutAndTaskWithLegacyTransition(shortcutInfo,
                    options1.toBundle(), taskId, null /* options2 */, stagePosition,
                    splitRatio, adapter, shellInstanceId);
        } else {
            mSystemUiProxy.startIntentAndTaskWithLegacyTransition(getPendingIntent(intent),
                    options1.toBundle(), taskId, null /* options2 */, stagePosition, splitRatio,
                    adapter, shellInstanceId);
            mSystemUiProxy.startIntentAndTaskWithLegacyTransition(
                    getPendingIntent(intent, user), options1.toBundle(), taskId,
                    null /* options2 */, stagePosition, splitRatio, adapter, shellInstanceId);
        }
    }

    private PendingIntent getPendingIntent(Intent intent) {
        return intent == null ? null : (mUser != null
    private PendingIntent getPendingIntent(Intent intent, UserHandle user) {
        return intent == null ? null : (user != null
                ? PendingIntent.getActivityAsUser(mContext, 0, intent,
                FLAG_MUTABLE, null /* options */, mUser)
                FLAG_MUTABLE, null /* options */, user)
                : PendingIntent.getActivity(mContext, 0, intent, FLAG_MUTABLE));
    }

    public @StagePosition int getActiveSplitStagePosition() {
        return mStagePosition;
        return mInitialStagePosition;
    }

    public StatsLogManager.EventEnum getSplitEvent() {
@@ -377,7 +391,7 @@ public class SplitSelectStateController {
    }

    @Nullable
    private ShortcutInfo getShortcutInfo(Intent intent) {
    private ShortcutInfo getShortcutInfo(Intent intent, UserHandle user) {
        if (intent == null || intent.getPackage() == null) {
            return null;
        }
@@ -389,7 +403,7 @@ public class SplitSelectStateController {

        try {
            final Context context = mContext.createPackageContextAsUser(
                    intent.getPackage(), 0 /* flags */, mUser);
                    intent.getPackage(), 0 /* flags */, user);
            return new ShortcutInfo.Builder(context, shortcutId).build();
        } catch (PackageManager.NameNotFoundException e) {
            Log.w(TAG, "Failed to create a ShortcutInfo for " + intent.getPackage());
@@ -519,7 +533,9 @@ public class SplitSelectStateController {
        mInitialTaskIntent = null;
        mSecondTaskId = INVALID_TASK_ID;
        mSecondTaskIntent = null;
        mStagePosition = SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
        mInitialUser = null;
        mSecondUser = null;
        mInitialStagePosition = SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
        mRecentsAnimationRunning = false;
        mLaunchingTaskView = null;
        mItemInfo = null;
+5 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.animation.AnimatorListenerAdapter;
import android.content.Intent;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.UserHandle;
import android.view.View;

import com.android.launcher3.DeviceProfile;
@@ -66,21 +67,24 @@ public class SplitToWorkspaceController {
        }
        Object tag = view.getTag();
        Intent intent;
        UserHandle user;
        BitmapInfo bitmapInfo;
        if (tag instanceof WorkspaceItemInfo) {
            final WorkspaceItemInfo workspaceItemInfo = (WorkspaceItemInfo) tag;
            intent = workspaceItemInfo.intent;
            user = workspaceItemInfo.user;
            bitmapInfo = workspaceItemInfo.bitmap;
        } else if (tag instanceof com.android.launcher3.model.data.AppInfo) {
            final com.android.launcher3.model.data.AppInfo appInfo =
                    (com.android.launcher3.model.data.AppInfo) tag;
            intent = appInfo.intent;
            user = appInfo.user;
            bitmapInfo = appInfo.bitmap;
        } else {
            return false;
        }

        mController.setSecondTask(intent);
        mController.setSecondTask(intent, user);

        boolean isTablet = mLauncher.getDeviceProfile().isTablet;
        SplitAnimationTimings timings = AnimUtils.getDeviceSplitToConfirmTimings(isTablet);
+4 −2
Original line number Diff line number Diff line
@@ -4575,11 +4575,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
     *                   is (either the ThumbnailView or the tapped icon).
     * @param intent If we are launching a fresh instance of the app, this is the Intent for it. If
     *               the second app is already running in Recents, this will be null.
     * @param user If we are launching a fresh instance of the app, this is the UserHandle for it.
     *             If the second app is already running in Recents, this will be null.
     * @return true if waiting for confirmation of second app or if split animations are running,
     *          false otherwise
     */
    public boolean confirmSplitSelect(TaskView containerTaskView, Task task, Drawable drawable,
            View secondView, @Nullable Bitmap thumbnail, Intent intent) {
            View secondView, @Nullable Bitmap thumbnail, Intent intent, UserHandle user) {
        if (canLaunchFullscreenTask()) {
            return false;
        }
@@ -4595,7 +4597,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
            }
            mSplitSelectStateController.setSecondTask(task);
        } else {
            mSplitSelectStateController.setSecondTask(intent);
            mSplitSelectStateController.setSecondTask(intent, user);
        }

        RectF secondTaskStartingBounds = new RectF();
Loading