From 02a0381e516f1782ff5a2170ed3b3e1bda7284fe Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Fri, 22 Apr 2016 17:32:00 -0700 Subject: [PATCH] Fix deadlock between VrManager, ActivityManager and WindowManager Let WM register to listen for Vr mode state changes and keep track of it locally to avoid calling out to vr manager. Bug: 28342910 Change-Id: I071666fab7319f315021f48058177dd3141acc3a --- .../policy/ImmersiveModeConfirmation.java | 33 +++++++++++-------- .../server/policy/PhoneWindowManager.java | 3 +- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java index 553c5de76cbac..29b9b92e8183f 100644 --- a/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java +++ b/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java @@ -32,6 +32,7 @@ import android.os.ServiceManager; import android.os.UserHandle; import android.provider.Settings; import android.service.vr.IVrManager; +import android.service.vr.IVrStateCallbacks; import android.util.DisplayMetrics; import android.util.Slog; import android.util.SparseBooleanArray; @@ -70,7 +71,9 @@ public class ImmersiveModeConfirmation { private long mPanicTime; private WindowManager mWindowManager; private int mCurrentUserId; - private IVrManager mVrManager; + // Local copy of vr mode enabled state, to avoid calling into VrManager with + // the lock held. + boolean mVrModeEnabled = false; public ImmersiveModeConfirmation(Context context) { mContext = context; @@ -117,22 +120,19 @@ public class ImmersiveModeConfirmation { } } - private boolean getVrMode() { - boolean vrMode = false; - if (mVrManager == null) { - // lazily grab this service since it may not be available at construction time - mVrManager = (IVrManager) IVrManager.Stub.asInterface( + void systemReady() { + IVrManager vrManager = IVrManager.Stub.asInterface( ServiceManager.getService(VrManagerService.VR_MANAGER_BINDER_SERVICE)); - } - if (mVrManager != null) { + if (vrManager != null) { try { - vrMode = mVrManager.getVrModeState(); - } catch (RemoteException ex) { } + vrManager.registerListener(mVrStateCallbacks); + mVrModeEnabled = vrManager.getVrModeState(); + } catch (RemoteException re) { + } } - return vrMode; } - public void immersiveModeChanged(String pkg, boolean isImmersiveMode, + public void immersiveModeChangedLw(String pkg, boolean isImmersiveMode, boolean userSetupComplete) { mHandler.removeMessages(H.SHOW); if (isImmersiveMode) { @@ -142,7 +142,7 @@ public class ImmersiveModeConfirmation { if (!disabled && (DEBUG_SHOW_EVERY_TIME || !mConfirmed) && userSetupComplete - && !getVrMode()) { + && !mVrModeEnabled) { mHandler.sendEmptyMessageDelayed(H.SHOW, mShowDelayMs); } } else { @@ -375,4 +375,11 @@ public class ImmersiveModeConfirmation { } } } + + private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() { + @Override + public void onVrStateChanged(boolean enabled) throws RemoteException { + mVrModeEnabled = enabled; + } + }; } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 007190dff3f8e..b20b9d9465cb8 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -6643,6 +6643,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mKeyguardDelegate.onBootCompleted(); } mSystemGestures.systemReady(); + mImmersiveModeConfirmation.systemReady(); } /** {@inheritDoc} */ @@ -7347,7 +7348,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean newImmersiveMode = isImmersiveMode(vis); if (win != null && oldImmersiveMode != newImmersiveMode) { final String pkg = win.getOwningPackage(); - mImmersiveModeConfirmation.immersiveModeChanged(pkg, newImmersiveMode, + mImmersiveModeConfirmation.immersiveModeChangedLw(pkg, newImmersiveMode, isUserSetupComplete()); }