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

Commit e1261d85 authored by Jorim Jaggi's avatar Jorim Jaggi Committed by Android (Google) Code Review
Browse files

Merge "resolve merge conflicts of 3c1b0f04 to master"

parents 7475ba9a 526694ea
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ public final class Looper {
            }

            final long traceTag = me.mTraceTag;
            if (traceTag != 0) {
            if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
                Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
            }
            try {
+71 −6
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.graphics.Region.Op;
import android.hardware.display.DisplayManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.Display;
import android.view.DisplayInfo;
@@ -106,6 +107,11 @@ public class DividerView extends FrameLayout implements OnTouchListener,
    private static final Interpolator IME_ADJUST_INTERPOLATOR =
            new PathInterpolator(0.2f, 0f, 0.1f, 1f);

    private static final long ONE_MS_IN_NS = 1000000;
    private static final long ONE_S_IN_NS = ONE_MS_IN_NS * 1000;

    private static final int MSG_RESIZE_STACK = 0;

    private DividerHandleView mHandle;
    private View mBackground;
    private MinimizedDockShadow mMinimizedShadow;
@@ -150,7 +156,25 @@ public class DividerView extends FrameLayout implements OnTouchListener,
    private boolean mDockedStackMinimized;
    private boolean mAdjustedForIme;
    private DividerState mState;
    private final Handler mHandler = new Handler();

    /**
     * The offset between vsync-app and vsync-surfaceflinger. See
     * {@link #calculateAppSurfaceFlingerVsyncOffsetMs} why this is necessary.
     */
    private long mSurfaceFlingerOffsetMs;

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_RESIZE_STACK:
                    resizeStack(msg.arg1, msg.arg2, (SnapTarget) msg.obj);
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    };

    private final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() {
        @Override
@@ -290,6 +314,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        EventBus.getDefault().register(this);
        mSurfaceFlingerOffsetMs = calculateAppSurfaceFlingerVsyncOffsetMs();
    }

    @Override
@@ -298,6 +323,25 @@ public class DividerView extends FrameLayout implements OnTouchListener,
        EventBus.getDefault().unregister(this);
    }

    /**
     * This method calculates the offset between vsync-surfaceflinger and vsync-app. If vsync-app
     * is a couple of milliseconds before vsync-sf, a touch or animation event that causes the
     * stacks to be resized are sometimes processed before the vsync-sf tick, and sometimes after,
     * which leads to jank. Figure out this difference here and then post all the touch/animation
     * events to start being processed at vsync-sf.
     *
     * @return The offset between vsync-app and vsync-sf, or 0 if vsync app happens after vsync-sf.
     */
    private long calculateAppSurfaceFlingerVsyncOffsetMs() {
        Display display = getDisplay();

        // Calculate vsync offset from SurfaceFlinger.
        // See frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp:getDisplayConfigs
        long vsyncPeriod = (long) (ONE_S_IN_NS / display.getRefreshRate());
        long sfVsyncOffset = vsyncPeriod - (display.getPresentationDeadlineNanos() - ONE_MS_IN_NS);
        return Math.max(0, (sfVsyncOffset - display.getAppVsyncOffsetNanos()) / ONE_MS_IN_NS);
    }

    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        if (mStableInsets.left != insets.getStableInsetLeft()
@@ -453,7 +497,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
                if (mMoving && mDockSide != WindowManager.DOCKED_INVALID) {
                    SnapTarget snapTarget = mSnapAlgorithm.calculateSnapTarget(
                            mStartPosition, 0 /* velocity */, false /* hardDismiss */);
                    resizeStack(calculatePosition(x, y), mStartPosition, snapTarget);
                    resizeStackDelayed(calculatePosition(x, y), mStartPosition, snapTarget);
                }
                break;
            case MotionEvent.ACTION_UP:
@@ -532,10 +576,11 @@ public class DividerView extends FrameLayout implements OnTouchListener,
            final long endDelay) {
        final boolean taskPositionSameAtEnd = snapTarget.flag == SnapTarget.FLAG_NONE;
        ValueAnimator anim = ValueAnimator.ofInt(position, snapTarget.position);
        anim.addUpdateListener(animation -> resizeStack((Integer) animation.getAnimatedValue(),
        anim.addUpdateListener(animation -> resizeStackDelayed((int) animation.getAnimatedValue(),
                taskPositionSameAtEnd && animation.getAnimatedFraction() == 1f
                        ? TASK_POSITION_SAME
                        : snapTarget.taskPosition, snapTarget));
                        : snapTarget.taskPosition,
                snapTarget));
        Runnable endAction = () -> {
            commitSnapFlags(snapTarget);
            mWindowManagerProxy.setResizing(false);
@@ -551,15 +596,24 @@ public class DividerView extends FrameLayout implements OnTouchListener,

            @Override
            public void onAnimationCancel(Animator animation) {
                mHandler.removeMessages(MSG_RESIZE_STACK);
                mCancelled = true;
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (endDelay == 0 || mCancelled) {
                long delay = 0;
                if (endDelay != 0) {
                    delay = endDelay;
                } else if (mCancelled) {
                    delay = 0;
                } else if (mSurfaceFlingerOffsetMs != 0) {
                    delay = mSurfaceFlingerOffsetMs;
                }
                if (delay == 0) {
                    endAction.run();
                } else {
                    mHandler.postDelayed(endAction, endDelay);
                    mHandler.postDelayed(endAction, delay);
                }
            }
        });
@@ -793,6 +847,17 @@ public class DividerView extends FrameLayout implements OnTouchListener,
                mDisplayHeight, mDividerSize);
    }

    public void resizeStackDelayed(int position, int taskPosition, SnapTarget taskSnapTarget) {
        if (mSurfaceFlingerOffsetMs != 0) {
            Message message = mHandler.obtainMessage(MSG_RESIZE_STACK, position, taskPosition,
                    taskSnapTarget);
            message.setAsynchronous(true);
            mHandler.sendMessageDelayed(message, mSurfaceFlingerOffsetMs);
        } else {
            resizeStack(position, taskPosition, taskSnapTarget);
        }
    }

    public void resizeStack(int position, int taskPosition, SnapTarget taskSnapTarget) {
        calculateBoundsForPosition(position, mDockSide, mDockedRect);

+28 −13
Original line number Diff line number Diff line
@@ -292,6 +292,7 @@ final class UserController {
     */
    private void finishUserUnlocking(final UserState uss) {
        final int userId = uss.mHandle.getIdentifier();
        boolean proceedWithUnlock = false;
        synchronized (mLock) {
            // Bail if we ended up with a stale user
            if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
@@ -301,6 +302,11 @@ final class UserController {

            if (uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
                mInjector.getUserManagerInternal().setUserState(userId, uss.state);
                proceedWithUnlock = true;
            }
        }

        if (proceedWithUnlock) {
            uss.mUnlockProgress.start();

            // Prepare app storage before we go any further
@@ -315,7 +321,6 @@ final class UserController {
                    .sendToTarget();
        }
    }
    }

    /**
     * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
@@ -961,6 +966,7 @@ final class UserController {

    boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
            IProgressListener listener) {
        UserState uss;
        synchronized (mLock) {
            // TODO Move this block outside of synchronized if it causes lock contention
            if (!StorageManager.isUserKeyUnlocked(userId)) {
@@ -975,7 +981,7 @@ final class UserController {
            }
            // Bail if user isn't actually running, otherwise register the given
            // listener to watch for unlock progress
            final UserState uss = mStartedUsers.get(userId);
            uss = mStartedUsers.get(userId);
            if (uss == null) {
                notifyFinished(userId, listener);
                return false;
@@ -983,9 +989,13 @@ final class UserController {
                uss.mUnlockProgress.addListener(listener);
                uss.tokenProvided = (token != null);
            }
        }

        finishUserUnlocking(uss);

        final ArraySet<Integer> childProfilesToUnlock = new ArraySet<>();
        synchronized (mLock) {

            // We just unlocked a user, so let's now attempt to unlock any
            // managed profiles under that user.
            for (int i = 0; i < mStartedUsers.size(); i++) {
@@ -994,11 +1004,16 @@ final class UserController {
                if (parent != null && parent.id == userId && testUserId != userId) {
                    Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
                            + "): attempting unlock because parent was just unlocked");
                    maybeUnlockUser(testUserId);
                    childProfilesToUnlock.add(testUserId);
                }
            }
        }

        final int size = childProfilesToUnlock.size();
        for (int i = 0; i < size; i++) {
            maybeUnlockUser(childProfilesToUnlock.valueAt(i));
        }

        return true;
    }