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

Commit 12446081 authored by Ruben Brunk's avatar Ruben Brunk Committed by android-build-merger
Browse files

Fix VR interaction with screen on/off/lockscreen.

am: 040484cf

Change-Id: I16023e2b02d9660b8c109c1586125316526f3fc9
parents ee39ac1c 040484cf
Loading
Loading
Loading
Loading
+17 −39
Original line number Original line Diff line number Diff line
@@ -1212,6 +1212,15 @@ public final class ActivityManagerService extends ActivityManagerNative
    /**
    /**
     * Set while we are wanting to sleep, to prevent any
     * Set while we are wanting to sleep, to prevent any
     * activities from being started/resumed.
     * activities from being started/resumed.
     *
     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
     *
     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
     * while in the sleep state until there is a pending transition out of sleep, in which case
     * mSleeping is set to false, and remains false while awake.
     *
     * Whether mSleeping can quickly toggled between true/false without the device actually
     * display changing states is undefined.
     */
     */
    private boolean mSleeping = false;
    private boolean mSleeping = false;
@@ -1537,8 +1546,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 69;
    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
    static final int FIRST_ACTIVITY_STACK_MSG = 100;
    static final int FIRST_ACTIVITY_STACK_MSG = 100;
    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -2355,14 +2363,6 @@ public final class ActivityManagerService extends ActivityManagerNative
                }
                }
                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
            } break;
            } break;
            case VR_MODE_APPLY_IF_NEEDED_MSG: {
                final ActivityRecord r = (ActivityRecord) msg.obj;
                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
                if (needsVrMode) {
                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
                            r.info.getComponentName(), false);
                }
            } break;
            }
            }
        }
        }
    };
    };
@@ -3166,20 +3166,12 @@ public final class ActivityManagerService extends ActivityManagerNative
                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
    }
    }
    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
    private void notifyVrManagerOfSleepState(boolean isSleeping) {
        mHandler.sendMessage(
        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
        if (vrService == null) {
    }
            return;
    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
            ComponentName callingPackage, boolean immediate) {
        VrManagerInternal vrService =
                LocalServices.getService(VrManagerInternal.class);
        if (immediate) {
            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
        } else {
            vrService.setVrMode(enabled, packageName, userId, callingPackage);
        }
        }
        vrService.onSleepStateChanged(isSleeping);
    }
    }
    final void showAskCompatModeDialogLocked(ActivityRecord r) {
    final void showAskCompatModeDialogLocked(ActivityRecord r) {
@@ -6789,7 +6781,6 @@ public final class ActivityManagerService extends ActivityManagerNative
                    // Some stack visibility might change (e.g. docked stack)
                    // Some stack visibility might change (e.g. docked stack)
                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                    applyVrModeIfNeededLocked(mFocusedActivity, true);
                }
                }
            }
            }
        } finally {
        } finally {
@@ -11719,6 +11710,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            startTimeTrackingFocusedActivityLocked();
            startTimeTrackingFocusedActivityLocked();
            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
            mStackSupervisor.comeOutOfSleepIfNeededLocked();
            mStackSupervisor.comeOutOfSleepIfNeededLocked();
            notifyVrManagerOfSleepState(false);
            updateOomAdjLocked();
            updateOomAdjLocked();
        } else if (!mSleeping && shouldSleepLocked()) {
        } else if (!mSleeping && shouldSleepLocked()) {
            mSleeping = true;
            mSleeping = true;
@@ -11727,6 +11719,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            }
            }
            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
            mStackSupervisor.goingToSleepLocked();
            mStackSupervisor.goingToSleepLocked();
            notifyVrManagerOfSleepState(true);
            updateOomAdjLocked();
            updateOomAdjLocked();
            // Initialize the wake times of all processes.
            // Initialize the wake times of all processes.
@@ -21959,21 +21952,6 @@ public final class ActivityManagerService extends ActivityManagerNative
        public SleepToken acquireSleepToken(String tag) {
        public SleepToken acquireSleepToken(String tag) {
            Preconditions.checkNotNull(tag);
            Preconditions.checkNotNull(tag);
            ComponentName requestedVrService = null;
            ComponentName callingVrActivity = null;
            int userId = -1;
            synchronized (ActivityManagerService.this) {
                if (mFocusedActivity != null) {
                    requestedVrService = mFocusedActivity.requestedVrComponent;
                    callingVrActivity = mFocusedActivity.info.getComponentName();
                    userId = mFocusedActivity.userId;
                }
            }
            if (requestedVrService != null) {
                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
            }
            synchronized (ActivityManagerService.this) {
            synchronized (ActivityManagerService.this) {
                SleepTokenImpl token = new SleepTokenImpl(tag);
                SleepTokenImpl token = new SleepTokenImpl(tag);
                mSleepTokens.add(token);
                mSleepTokens.add(token);
+11 −0
Original line number Original line Diff line number Diff line
@@ -152,6 +152,7 @@ import com.android.server.LocalServices;
import com.android.server.policy.keyguard.KeyguardServiceDelegate;
import com.android.server.policy.keyguard.KeyguardServiceDelegate;
import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener;
import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.vr.VrManagerInternal;


import java.io.File;
import java.io.File;
import java.io.FileReader;
import java.io.FileReader;
@@ -6513,6 +6514,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                mKeyguardDelegate.onScreenTurnedOff();
                mKeyguardDelegate.onScreenTurnedOff();
            }
            }
        }
        }
        reportScreenStateToVrManager(false);
    }
    }


    // Called on the DisplayManager's DisplayPowerController thread.
    // Called on the DisplayManager's DisplayPowerController thread.
@@ -6548,6 +6550,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                mKeyguardDelegate.onScreenTurnedOn();
                mKeyguardDelegate.onScreenTurnedOn();
            }
            }
        }
        }
        reportScreenStateToVrManager(true);
    }

    private void reportScreenStateToVrManager(boolean isScreenOn) {
        VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
        if (vrService == null) {
            return;
        }
        vrService.onScreenStateChanged(isScreenOn);
    }
    }


    private void finishWindowsDrawn() {
    private void finishWindowsDrawn() {
+18 −16
Original line number Original line Diff line number Diff line
@@ -56,16 +56,19 @@ public abstract class VrManagerInternal {
            int userId, @NonNull ComponentName calling);
            int userId, @NonNull ComponentName calling);


    /**
    /**
     * Set the current VR mode state immediately.
     * Set whether the system has acquired a sleep token.
     *
     *
     * @param enabled {@code true} to enable VR mode.
     * @param isAsleep is {@code true} if the device is asleep, or {@code false} otherwise.
     * @param packageName The package name of the requested VrListenerService to bind.
     * @param userId the user requesting the VrListenerService component.
     * @param calling the component currently using VR mode, or null to leave unchanged.
     */
     */
    public abstract void setVrModeImmediate(boolean enabled, @NonNull ComponentName packageName,
    public abstract void onSleepStateChanged(boolean isAsleep);
            int userId, @NonNull ComponentName calling);


    /**
     * Set whether the display used for VR output is on.
     *
     * @param isScreenOn is {@code true} if the display is on and can receive commands,
     *      or {@code false} otherwise.
     */
    public abstract void onScreenStateChanged(boolean isScreenOn);


    /**
    /**
     * Return NO_ERROR if the given package is installed on the device and enabled as a
     * Return NO_ERROR if the given package is installed on the device and enabled as a
@@ -76,5 +79,4 @@ public abstract class VrManagerInternal {
     *       given in {@link android.service.vr.VrModeException} on failure.
     *       given in {@link android.service.vr.VrModeException} on failure.
     */
     */
    public abstract int hasVrPackage(@NonNull ComponentName packageName, int userId);
    public abstract int hasVrPackage(@NonNull ComponentName packageName, int userId);

}
}
+121 −21
Original line number Original line Diff line number Diff line
@@ -101,6 +101,14 @@ public class VrManagerService extends SystemService implements EnabledComponentC
    private static final int PENDING_STATE_DELAY_MS = 300;
    private static final int PENDING_STATE_DELAY_MS = 300;
    private static final int EVENT_LOG_SIZE = 32;
    private static final int EVENT_LOG_SIZE = 32;
    private static final int INVALID_APPOPS_MODE = -1;
    private static final int INVALID_APPOPS_MODE = -1;
    /** Null set of sleep sleep flags. */
    private static final int FLAG_NONE = 0;
    /** Flag set when the device is not sleeping. */
    private static final int FLAG_AWAKE = 1;
    /** Flag set when the screen has been turned on. */
    private static final int FLAG_SCREEN_ON = 2;
    /** Flag indicating that all system sleep flags have been set.*/
    private static final int FLAG_ALL = FLAG_AWAKE | FLAG_SCREEN_ON;


    private static native void initializeNative();
    private static native void initializeNative();
    private static native void setVrModeNative(boolean enabled);
    private static native void setVrModeNative(boolean enabled);
@@ -110,6 +118,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC
    private final IBinder mOverlayToken = new Binder();
    private final IBinder mOverlayToken = new Binder();


    // State protected by mLock
    // State protected by mLock
    private boolean mVrModeAllowed;
    private boolean mVrModeEnabled;
    private boolean mVrModeEnabled;
    private EnabledComponentsObserver mComponentObserver;
    private EnabledComponentsObserver mComponentObserver;
    private ManagedApplicationService mCurrentVrService;
    private ManagedApplicationService mCurrentVrService;
@@ -125,10 +134,64 @@ public class VrManagerService extends SystemService implements EnabledComponentC
    private VrState mPendingState;
    private VrState mPendingState;
    private final ArrayDeque<VrState> mLoggingDeque = new ArrayDeque<>(EVENT_LOG_SIZE);
    private final ArrayDeque<VrState> mLoggingDeque = new ArrayDeque<>(EVENT_LOG_SIZE);
    private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager();
    private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager();
    /** Tracks the state of the screen and keyguard UI.*/
    private int mSystemSleepFlags = FLAG_NONE;


    private static final int MSG_VR_STATE_CHANGE = 0;
    private static final int MSG_VR_STATE_CHANGE = 0;
    private static final int MSG_PENDING_VR_STATE_CHANGE = 1;
    private static final int MSG_PENDING_VR_STATE_CHANGE = 1;


    /**
     * Set whether VR mode may be enabled.
     * <p/>
     * If VR mode is not allowed to be enabled, calls to set VR mode will be cached.  When VR mode
     * is again allowed to be enabled, the most recent cached state will be applied.
     *
     * @param allowed {@code true} if calling any of the setVrMode methods may cause the device to
     *   enter VR mode.
     */
    private void setVrModeAllowedLocked(boolean allowed) {
        if (mVrModeAllowed != allowed) {
            mVrModeAllowed = allowed;
            Slog.i(TAG, "VR mode is " + ((allowed) ? "allowed" : "disallowed"));
            if (mVrModeAllowed) {
                consumeAndApplyPendingStateLocked();
            } else {
                // Set pending state to current state.
                mPendingState = (mVrModeEnabled && mCurrentVrService != null)
                    ? new VrState(mVrModeEnabled, mCurrentVrService.getComponent(),
                        mCurrentVrService.getUserId(), mCurrentVrModeComponent)
                    : null;

                // Unbind current VR service and do necessary callbacks.
                updateCurrentVrServiceLocked(false, null, 0, null);
            }
        }
    }

    private void setSleepState(boolean isAsleep) {
        synchronized(mLock) {

            if (!isAsleep) {
                mSystemSleepFlags |= FLAG_AWAKE;
            } else {
                mSystemSleepFlags &= ~FLAG_AWAKE;
            }

            setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL);
        }
    }

    private void setScreenOn(boolean isScreenOn) {
        synchronized(mLock) {
            if (isScreenOn) {
                mSystemSleepFlags |= FLAG_SCREEN_ON;
            } else {
                mSystemSleepFlags &= ~FLAG_SCREEN_ON;
            }
            setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL);
        }
    }

    private final Handler mHandler = new Handler() {
    private final Handler mHandler = new Handler() {
        @Override
        @Override
        public void handleMessage(Message msg) {
        public void handleMessage(Message msg) {
@@ -148,8 +211,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC
                } break;
                } break;
                case MSG_PENDING_VR_STATE_CHANGE : {
                case MSG_PENDING_VR_STATE_CHANGE : {
                    synchronized(mLock) {
                    synchronized(mLock) {
                        if (mVrModeAllowed) {
                           VrManagerService.this.consumeAndApplyPendingStateLocked();
                           VrManagerService.this.consumeAndApplyPendingStateLocked();
                        }
                        }
                    }
                } break;
                } break;
                default :
                default :
                    throw new IllegalStateException("Unknown message type: " + msg.what);
                    throw new IllegalStateException("Unknown message type: " + msg.what);
@@ -268,8 +333,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC
            }
            }
            mNotifAccessManager.update(enabledPackages);
            mNotifAccessManager.update(enabledPackages);


            if (mCurrentVrService == null) {
            if (!mVrModeAllowed) {
                return; // No active services
                return; // Don't do anything, we shouldn't be in VR mode.
            }
            }


            // If there is a pending state change, we'd better deal with that first
            // If there is a pending state change, we'd better deal with that first
@@ -321,6 +386,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC
                return;
                return;
            }
            }
            pw.println("********* Dump of VrManagerService *********");
            pw.println("********* Dump of VrManagerService *********");
            pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed"));
            pw.println("Previous state transitions:\n");
            pw.println("Previous state transitions:\n");
            String tab = "  ";
            String tab = "  ";
            dumpStateTransitions(pw);
            dumpStateTransitions(pw);
@@ -374,13 +440,17 @@ public class VrManagerService extends SystemService implements EnabledComponentC
        @Override
        @Override
        public void setVrMode(boolean enabled, ComponentName packageName, int userId,
        public void setVrMode(boolean enabled, ComponentName packageName, int userId,
                ComponentName callingPackage) {
                ComponentName callingPackage) {
            VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage, false);
            VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage);
        }
        }


        @Override
        @Override
        public void setVrModeImmediate(boolean enabled, ComponentName packageName, int userId,
        public void onSleepStateChanged(boolean isAsleep) {
                ComponentName callingPackage) {
            VrManagerService.this.setSleepState(isAsleep);
            VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage, true);
        }

        @Override
        public void onScreenStateChanged(boolean isScreenOn) {
            VrManagerService.this.setScreenOn(isScreenOn);
        }
        }


        @Override
        @Override
@@ -424,6 +494,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC


                mComponentObserver.rebuildAll();
                mComponentObserver.rebuildAll();
            }
            }
        } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
            synchronized (mLock) {
                mVrModeAllowed = true;
            }
        }
        }
    }
    }


@@ -466,12 +540,16 @@ public class VrManagerService extends SystemService implements EnabledComponentC
                    false, mOverlayToken, null, oldUserId);
                    false, mOverlayToken, null, oldUserId);
        }
        }


        if (!mVrModeEnabled) {
            return;
        }

        // Apply the restrictions for the current user based on vr state
        // Apply the restrictions for the current user based on vr state
        String[] exemptions = (exemptedPackage == null) ? new String[0] :
        String[] exemptions = (exemptedPackage == null) ? new String[0] :
                new String[] { exemptedPackage };
                new String[] { exemptedPackage };


        appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
        appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
                mVrModeEnabled, mOverlayToken, exemptions, newUserId);
                true, mOverlayToken, exemptions, newUserId);
    }
    }


    private void updateDependentAppOpsLocked(String newVrServicePackage, int newUserId,
    private void updateDependentAppOpsLocked(String newVrServicePackage, int newUserId,
@@ -512,7 +590,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC


            boolean validUserComponent = (mComponentObserver.isValid(component, userId) ==
            boolean validUserComponent = (mComponentObserver.isValid(component, userId) ==
                    EnabledComponentsObserver.NO_ERROR);
                    EnabledComponentsObserver.NO_ERROR);
            if (!mVrModeEnabled && !enabled) {
            boolean goingIntoVrMode = validUserComponent && enabled;
            if (!mVrModeEnabled && !goingIntoVrMode) {
                return validUserComponent; // Disabled -> Disabled transition does nothing.
                return validUserComponent; // Disabled -> Disabled transition does nothing.
            }
            }


@@ -520,29 +599,37 @@ public class VrManagerService extends SystemService implements EnabledComponentC
                    ? mCurrentVrService.getComponent().getPackageName() : null;
                    ? mCurrentVrService.getComponent().getPackageName() : null;
            final int oldUserId = mCurrentVrModeUser;
            final int oldUserId = mCurrentVrModeUser;


            // Always send mode change events.
            // Notify system services and VR HAL of mode change.
            changeVrModeLocked(enabled);
            changeVrModeLocked(goingIntoVrMode);


            if (!enabled || !validUserComponent) {
            boolean nothingChanged = false;
                // Unbind whatever is running
            if (!goingIntoVrMode) {
                // Not going into VR mode, unbind whatever is running
                if (mCurrentVrService != null) {
                if (mCurrentVrService != null) {
                    Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + " for user " +
                    Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + " for user " +
                            mCurrentVrService.getUserId());
                            mCurrentVrService.getUserId());
                    mCurrentVrService.disconnect();
                    mCurrentVrService.disconnect();
                    mCurrentVrService = null;
                    mCurrentVrService = null;
                } else {
                    nothingChanged = true;
                }
                }
            } else {
            } else {
                // Going into VR mode
                if (mCurrentVrService != null) {
                if (mCurrentVrService != null) {
                    // Unbind any running service that doesn't match the component/user selection
                    // Unbind any running service that doesn't match the latest component/user
                    // selection.
                    if (mCurrentVrService.disconnectIfNotMatching(component, userId)) {
                    if (mCurrentVrService.disconnectIfNotMatching(component, userId)) {
                        Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() +
                        Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() +
                                " for user " + mCurrentVrService.getUserId());
                                " for user " + mCurrentVrService.getUserId());
                        createAndConnectService(component, userId);
                        createAndConnectService(component, userId);
                        sendUpdatedCaller = true;
                        sendUpdatedCaller = true;
                    } else {
                        nothingChanged = true;
                    }
                    }
                    // The service with the correct component/user is bound
                    // The service with the correct component/user is already bound, do nothing.
                } else {
                } else {
                    // Nothing was previously running, bind a new service
                    // Nothing was previously running, bind a new service for the latest
                    // component/user selection.
                    createAndConnectService(component, userId);
                    createAndConnectService(component, userId);
                    sendUpdatedCaller = true;
                    sendUpdatedCaller = true;
                }
                }
@@ -577,7 +664,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC
                    }
                    }
                });
                });
            }
            }

            if (!nothingChanged) {
                logStateLocked();
                logStateLocked();
            }


            return validUserComponent;
            return validUserComponent;
        } finally {
        } finally {
@@ -784,7 +874,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC
                    mPendingState.targetPackageName, mPendingState.userId,
                    mPendingState.targetPackageName, mPendingState.userId,
                    mPendingState.callingPackage);
                    mPendingState.callingPackage);
            mPendingState = null;
            mPendingState = null;
        } else {
            updateCurrentVrServiceLocked(false, null, 0, null);
        }
        }

    }
    }


    private void logStateLocked() {
    private void logStateLocked() {
@@ -834,13 +927,20 @@ public class VrManagerService extends SystemService implements EnabledComponentC
    /*
    /*
     * Implementation of VrManagerInternal calls.  These are callable from system services.
     * Implementation of VrManagerInternal calls.  These are callable from system services.
     */
     */

    private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName,
    private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName,
            int userId, @NonNull ComponentName callingPackage, boolean immediate) {
            int userId, @NonNull ComponentName callingPackage) {


        synchronized (mLock) {
        synchronized (mLock) {
            VrState pending = new VrState(enabled, targetPackageName, userId, callingPackage);
            if (!mVrModeAllowed) {
                // We're not allowed to be in VR mode.  Make this state pending.  This will be
                // applied the next time we are allowed to enter VR mode unless it is superseded by
                // another call.
                mPendingState = pending;
                return;
            }


            if (!enabled && mCurrentVrService != null && !immediate) {
            if (!enabled && mCurrentVrService != null) {
                // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls
                // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls
                // and service bind/unbind in case we are immediately switching to another VR app.
                // and service bind/unbind in case we are immediately switching to another VR app.
                if (mPendingState == null) {
                if (mPendingState == null) {
@@ -848,7 +948,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC
                            PENDING_STATE_DELAY_MS);
                            PENDING_STATE_DELAY_MS);
                }
                }


                mPendingState = new VrState(enabled, targetPackageName, userId, callingPackage);
                mPendingState = pending;
                return;
                return;
            } else {
            } else {
                mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE);
                mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE);