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

Commit 526694ea authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

resolve merge conflicts of 3c1b0f04 to master

Change-Id: I2314728cba47c28ff580f4dfc69868f8cb5ff5db
parents 3e27a25b 3c1b0f04
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;
    }