From 74f6c79b513c5a6e032c009a037f67e256aab7ba Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Tue, 25 Aug 2015 21:15:12 +0100 Subject: [PATCH] Update rotation without holding the WOL lock. We need to make sure to only ever update the orientation of the device from WindowOrientationListener when we're not holding the WOL class lock, otherwise we can deadlock when WMS calls into us to set the orientation based on an apps preference. Bug: 23491348 Change-Id: Ifeded4d5d1dc923fa2ce0473bc4b7fe950dc0cfd --- .../policy/WindowOrientationListener.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java index 8b3c036594c65..991622398a481 100644 --- a/services/core/java/com/android/server/policy/WindowOrientationListener.java +++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java @@ -217,6 +217,8 @@ public abstract class WindowOrientationListener { * It is called each time the orientation determination transitions from being * uncertain to being certain again, even if it is the same orientation as before. * + * This should only be called on the Handler thread. + * * @param rotation The new orientation of the device, one of the Surface.ROTATION_* constants. * @see android.view.Surface */ @@ -995,9 +997,13 @@ public abstract class WindowOrientationListener { @Override public void onSensorChanged(SensorEvent event) { + int newRotation; synchronized (mLock) { mDesiredRotation = (int) event.values[0]; - evaluateRotationChangeLocked(); + newRotation = evaluateRotationChangeLocked(); + } + if (newRotation >=0) { + onProposedRotationChanged(newRotation); } } @@ -1023,18 +1029,19 @@ public abstract class WindowOrientationListener { unscheduleRotationEvaluationLocked(); } - public void evaluateRotationChangeLocked() { + public int evaluateRotationChangeLocked() { unscheduleRotationEvaluationLocked(); if (mDesiredRotation == mProposedRotation) { - return; + return -1; } final long now = SystemClock.elapsedRealtimeNanos(); if (isDesiredRotationAcceptableLocked(now)) { mProposedRotation = mDesiredRotation; - onProposedRotationChanged(mProposedRotation); + return mProposedRotation; } else { scheduleRotationEvaluationIfNecessaryLocked(now); } + return -1; } private boolean isDesiredRotationAcceptableLocked(long now) { @@ -1090,9 +1097,13 @@ public abstract class WindowOrientationListener { private Runnable mRotationEvaluator = new Runnable() { @Override public void run() { + int newRotation; synchronized (mLock) { mRotationEvaluationScheduled = false; - evaluateRotationChangeLocked(); + newRotation = evaluateRotationChangeLocked(); + } + if (newRotation >= 0) { + onProposedRotationChanged(newRotation); } } };