VrManagerService.java revision e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312
1e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk/** 2dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * Copyright (C) 2015 The Android Open Source Project 3dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * 4dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License"); 5dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * you may not use this file except in compliance with the License. 6dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * You may obtain a copy of the License at 7dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * 8dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * http://www.apache.org/licenses/LICENSE-2.0 9dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * 10dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * Unless required by applicable law or agreed to in writing, software 11dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS, 12dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * See the License for the specific language governing permissions and 14dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * limitations under the License. 15dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk */ 16dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkpackage com.android.server.vr; 17dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 1847d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganovimport android.app.AppOpsManager; 19e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.annotation.NonNull; 20dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport android.content.Context; 21e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.content.ComponentName; 22dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport android.content.Intent; 23dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport android.content.pm.PackageManager; 2447d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganovimport android.os.Binder; 25e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.os.Handler; 2647d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganovimport android.os.IBinder; 27e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.os.IInterface; 28e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.os.Looper; 29dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport android.os.UserHandle; 30e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.provider.Settings; 31e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.service.vr.IVrListener; 32e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.service.vr.VrListenerService; 33dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport android.util.ArraySet; 34dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport android.util.Slog; 35dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 36e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport com.android.internal.R; 37dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport com.android.server.SystemService; 38e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport com.android.server.vr.EnabledComponentsObserver.EnabledComponentChangeListener; 39e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport com.android.server.utils.ManagedApplicationService; 40e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport com.android.server.utils.ManagedApplicationService.BinderChecker; 41dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 42dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport java.util.ArrayList; 43e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport java.util.Set; 44dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 45dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk/** 46e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Service tracking whether VR mode is active, and notifying listening services of state changes. 47e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 48e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Services running in system server may modify the state of VrManagerService via the interface in 49e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * VrManagerInternal, and may register to receive callbacks when the system VR mode changes via the 50e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * interface given in VrStateListener. 51e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 52e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Device vendors may choose to receive VR state changes by implementing the VR mode HAL, e.g.: 53e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * hardware/libhardware/modules/vr 54e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 55e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * In general applications may enable or disable VR mode by calling 56e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * {@link android.app.Activity#setVrMode)}. An application may also implement a service to be run 57e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * while in VR mode by implementing {@link android.service.vr.VrListenerService}. 58e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * 59e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @see {@link android.service.vr.VrListenerService} 60e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @see {@link com.android.server.vr.VrManagerInternal} 61e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @see {@link com.android.server.vr.VrStateListener} 62dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * 63e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @hide 64dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk */ 65e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkpublic class VrManagerService extends SystemService implements EnabledComponentChangeListener{ 66dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 67dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk public static final String TAG = "VrManagerService"; 68dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 69baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk private static native void initializeNative(); 70baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk private static native void setVrModeNative(boolean enabled); 71baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk 72dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk private final Object mLock = new Object(); 7347d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov 7447d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov private final IBinder mOverlayToken = new Binder(); 7547d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov 76e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk // State protected by mLock 77dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk private boolean mVrModeEnabled = false; 78e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private final Set<VrStateListener> mListeners = new ArraySet<>(); 79e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private EnabledComponentsObserver mComponentObserver; 80e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private ManagedApplicationService mCurrentVrService; 81e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private Context mContext; 82e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 83e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private static final BinderChecker sBinderChecker = new BinderChecker() { 84e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 85e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public IInterface asInterface(IBinder binder) { 86e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return IVrListener.Stub.asInterface(binder); 87e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 88e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 89e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 90e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public boolean checkType(IInterface service) { 91e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return service instanceof IVrListener; 92e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 93e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk }; 94e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 95e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /** 96e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Called when a user, package, or setting changes that could affect whether or not the 97e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * currently bound VrListenerService is changed. 98e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 99e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 100e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onEnabledComponentChanged() { 101e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 102e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk if (mCurrentVrService == null) { 103e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return; // No active services 104e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 105e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 106e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk // There is an active service, update it if needed 107e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk updateCurrentVrServiceLocked(mVrModeEnabled, mCurrentVrService.getComponent(), 108e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mCurrentVrService.getUserId()); 109e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 110e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 111dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 112e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /** 113e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Implementation of VrManagerInternal. Callable only from system services. 114e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 115dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk private final class LocalService extends VrManagerInternal { 116dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk @Override 117dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk public boolean isInVrMode() { 118dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk return VrManagerService.this.getVrMode(); 119dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 120dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 121dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk @Override 122e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void setVrMode(boolean enabled, ComponentName packageName, int userId) { 123e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk VrManagerService.this.setVrMode(enabled, packageName, userId); 124dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 125dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 126dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk @Override 127dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk public void registerListener(VrStateListener listener) { 128dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk VrManagerService.this.addListener(listener); 129dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 130dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 131dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk @Override 132dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk public void unregisterListener(VrStateListener listener) { 133dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk VrManagerService.this.removeListener(listener); 134dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 135e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 136e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 137e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public int hasVrPackage(ComponentName packageName, int userId) { 138e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return VrManagerService.this.hasVrPackage(packageName, userId); 139e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 140dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 141dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 142dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk public VrManagerService(Context context) { 143dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk super(context); 144dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 145dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 146dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk @Override 147dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk public void onStart() { 148baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk synchronized(mLock) { 149baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk initializeNative(); 150e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mContext = getContext(); 151baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk } 152baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk 153dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk publishLocalService(VrManagerInternal.class, new LocalService()); 154dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 155dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 156e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 157e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onBootPhase(int phase) { 158e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { 159e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 160e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Looper looper = Looper.getMainLooper(); 161e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Handler handler = new Handler(looper); 162e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk ArrayList<EnabledComponentChangeListener> listeners = new ArrayList<>(); 163e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk listeners.add(this); 164e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver = EnabledComponentsObserver.build(mContext, handler, 165e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Settings.Secure.ENABLED_VR_LISTENERS, looper, 166e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk android.Manifest.permission.BIND_VR_LISTENER_SERVICE, 167e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk VrListenerService.SERVICE_INTERFACE, mLock, listeners); 168e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 169e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver.rebuildAll(); 170e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 171e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 172e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 173e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 174e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 175e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onStartUser(int userHandle) { 176dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk synchronized (mLock) { 177e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver.onUsersChanged(); 178dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 179dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 180dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 181e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 182e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onSwitchUser(int userHandle) { 183dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk synchronized (mLock) { 184e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver.onUsersChanged(); 185e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 186e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 187e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 188e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 189e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 190e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onStopUser(int userHandle) { 191e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 192e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver.onUsersChanged(); 193dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 194e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 195dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 196dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 197e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 198e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onCleanupUser(int userHandle) { 199dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk synchronized (mLock) { 200e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver.onUsersChanged(); 201dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 202dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 203dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 20447d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov private void updateOverlayStateLocked() { 20547d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 20647d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov try { 20747d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class); 20847d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov if (appOpsManager != null) { 20947d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov appOpsManager.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, 21047d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov mVrModeEnabled, mOverlayToken); 21147d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov } 21247d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov } finally { 21347d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov Binder.restoreCallingIdentity(identity); 21447d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov } 21547d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov } 21647d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov 217e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /** 218e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Send VR mode changes (if the mode state has changed), and update the bound/unbound state of 219e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * the currently selected VR listener service. If the component selected for the VR listener 220e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * service has changed, unbind the previous listener and bind the new listener (if enabled). 221e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 222e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Note: Must be called while holding {@code mLock}. 223e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * 224e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @param enabled new state for VR mode. 225e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @param component new component to be bound as a VR listener. 226e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @param userId user owning the component to be bound. 227e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * 228e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @return {@code true} if the component/user combination specified is valid. 229e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 230e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private boolean updateCurrentVrServiceLocked(boolean enabled, 231e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @NonNull ComponentName component, int userId) { 232e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 233e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk // Always send mode change events. 234e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk changeVrModeLocked(enabled); 235e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 236e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk boolean validUserComponent = (mComponentObserver.isValid(component, userId) == 237e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk EnabledComponentsObserver.NO_ERROR); 238e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 239e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk if (!enabled || !validUserComponent) { 240e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk // Unbind whatever is running 241e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk if (mCurrentVrService != null) { 242e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + " for user " + 243e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mCurrentVrService.getUserId()); 244e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mCurrentVrService.disconnect(); 245e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mCurrentVrService = null; 246e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 247e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return validUserComponent; 248e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 249e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 250e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk if (mCurrentVrService != null) { 251e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk // Unbind any running service that doesn't match the component/user selection 252e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk if (mCurrentVrService.disconnectIfNotMatching(component, userId)) { 253e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + " for user " + 254e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mCurrentVrService.getUserId()); 255e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mCurrentVrService = VrManagerService.create(mContext, component, userId); 256e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mCurrentVrService.connect(); 257e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Slog.i(TAG, "Connecting " + mCurrentVrService.getComponent() + " for user " + 258e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mCurrentVrService.getUserId()); 259e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 260e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk // The service with the correct component/user is bound 261e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } else { 262e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk // Nothing was previously running, bind a new service 263e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mCurrentVrService = VrManagerService.create(mContext, component, userId); 264e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mCurrentVrService.connect(); 265e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Slog.i(TAG, "Connecting " + mCurrentVrService.getComponent() + " for user " + 266e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mCurrentVrService.getUserId()); 267e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 268e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 269e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return validUserComponent; 270e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 271e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 272e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /** 273e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Send VR mode change callbacks to HAL and system services if mode has actually changed. 274e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 275e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Note: Must be called while holding {@code mLock}. 276e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * 277e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @param enabled new state of the VR mode. 278e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 279e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private void changeVrModeLocked(boolean enabled) { 280e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk if (mVrModeEnabled != enabled) { 281e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mVrModeEnabled = enabled; 282e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 283e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk // Log mode change event. 284e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled")); 285e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk setVrModeNative(mVrModeEnabled); 286e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 287e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk updateOverlayStateLocked(); 288e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk onVrModeChangedLocked(); 289dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 290dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 291dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 292dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk /** 293dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * Notify system services of VR mode change. 294e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 295e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Note: Must be called while holding {@code mLock}. 296dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk */ 297dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk private void onVrModeChangedLocked() { 298dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk for (VrStateListener l : mListeners) { 299dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk l.onVrStateChanged(mVrModeEnabled); 300dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 301dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 302e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 303e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /** 304e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Helper function for making ManagedApplicationService instances. 305e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 306e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private static ManagedApplicationService create(@NonNull Context context, 307e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @NonNull ComponentName component, int userId) { 308e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return ManagedApplicationService.build(context, component, userId, 309e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk R.string.vr_listener_binding_label, Settings.ACTION_VR_LISTENER_SETTINGS, 310e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk sBinderChecker); 311e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 312e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 313e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /* 314e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Implementation of VrManagerInternal calls. These are callable from system services. 315e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 316e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 317e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private boolean setVrMode(boolean enabled, @NonNull ComponentName targetPackageName, 318e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk int userId) { 319e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 320e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return updateCurrentVrServiceLocked(enabled, targetPackageName, userId); 321e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 322e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 323e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 324e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private boolean getVrMode() { 325e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 326e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return mVrModeEnabled; 327e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 328e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 329e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 330e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private void addListener(VrStateListener listener) { 331e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 332e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mListeners.add(listener); 333e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 334e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 335e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 336e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private void removeListener(VrStateListener listener) { 337e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 338e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mListeners.remove(listener); 339e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 340e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 341e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 342e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) { 343e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 344e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return mComponentObserver.isValid(targetPackageName, userId); 345e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 346e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 347dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk} 348