VrManagerService.java revision dc34df5d310245a268ee9ea3872a612c6f7950b5
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 18c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunkimport android.Manifest; 1947d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganovimport android.app.AppOpsManager; 2098576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.app.NotificationManager; 21e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.annotation.NonNull; 22e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.content.ComponentName; 2398576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.content.ContentResolver; 2498576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.content.Context; 2598576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.content.pm.ApplicationInfo; 2698576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.content.pm.PackageManager; 2798576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.content.pm.PackageManager.NameNotFoundException; 2847d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganovimport android.os.Binder; 29e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.os.Handler; 3047d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganovimport android.os.IBinder; 31e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.os.IInterface; 32e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.os.Looper; 33c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunkimport android.os.Message; 34c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunkimport android.os.RemoteCallbackList; 35c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunkimport android.os.RemoteException; 3698576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.os.UserHandle; 37e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.provider.Settings; 3898576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.service.notification.NotificationListenerService; 39e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.service.vr.IVrListener; 40c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunkimport android.service.vr.IVrManager; 41c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunkimport android.service.vr.IVrStateCallbacks; 42e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.service.vr.VrListenerService; 43dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport android.util.ArraySet; 44dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport android.util.Slog; 45dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 46e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport com.android.internal.R; 47dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport com.android.server.SystemService; 48c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunkimport com.android.server.utils.ManagedApplicationService.PendingEvent; 49e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport com.android.server.vr.EnabledComponentsObserver.EnabledComponentChangeListener; 50e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport com.android.server.utils.ManagedApplicationService; 51e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport com.android.server.utils.ManagedApplicationService.BinderChecker; 52dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 53dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandlerimport java.io.FileDescriptor; 54dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandlerimport java.io.PrintWriter; 5598576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport java.lang.StringBuilder; 56c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunkimport java.lang.ref.WeakReference; 57dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport java.util.ArrayList; 5898576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport java.util.Collection; 59c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunkimport java.util.Objects; 60e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport java.util.Set; 61dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 62dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk/** 63e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Service tracking whether VR mode is active, and notifying listening services of state changes. 64e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 65e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Services running in system server may modify the state of VrManagerService via the interface in 66e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * VrManagerInternal, and may register to receive callbacks when the system VR mode changes via the 67e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * interface given in VrStateListener. 68e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 69e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Device vendors may choose to receive VR state changes by implementing the VR mode HAL, e.g.: 70e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * hardware/libhardware/modules/vr 71e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 72e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * In general applications may enable or disable VR mode by calling 7398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * {@link android.app.Activity#setVrModeEnabled)}. An application may also implement a service to 7498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * be run while in VR mode by implementing {@link android.service.vr.VrListenerService}. 75e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * 76e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @see {@link android.service.vr.VrListenerService} 77e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @see {@link com.android.server.vr.VrManagerInternal} 78e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @see {@link com.android.server.vr.VrStateListener} 79dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * 80e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @hide 81dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk */ 82e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkpublic class VrManagerService extends SystemService implements EnabledComponentChangeListener{ 83dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 84dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk public static final String TAG = "VrManagerService"; 85dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 86c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk public static final String VR_MANAGER_BINDER_SERVICE = "vrmanager"; 87c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk 88baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk private static native void initializeNative(); 89baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk private static native void setVrModeNative(boolean enabled); 90baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk 91dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk private final Object mLock = new Object(); 9247d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov 9347d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov private final IBinder mOverlayToken = new Binder(); 9447d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov 95e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk // State protected by mLock 9698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private boolean mVrModeEnabled; 97e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private EnabledComponentsObserver mComponentObserver; 98e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private ManagedApplicationService mCurrentVrService; 99e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private Context mContext; 100c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk private ComponentName mCurrentVrModeComponent; 101c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk private int mCurrentVrModeUser; 10298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private boolean mWasDefaultGranted; 10398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private boolean mGuard; 104c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk private final RemoteCallbackList<IVrStateCallbacks> mRemoteCallbacks = 105c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk new RemoteCallbackList<>(); 10698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private final ArraySet<String> mPreviousToggledListenerSettings = new ArraySet<>(); 10798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private String mPreviousNotificationPolicyAccessPackage; 10898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private String mPreviousManageOverlayPackage; 109e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 110c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk private static final int MSG_VR_STATE_CHANGE = 0; 111c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk 112c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk private final Handler mHandler = new Handler() { 113c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk @Override 114c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk public void handleMessage(Message msg) { 115c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk switch(msg.what) { 116c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk case MSG_VR_STATE_CHANGE : { 117c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk boolean state = (msg.arg1 == 1); 118c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk int i = mRemoteCallbacks.beginBroadcast(); 119c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk while (i > 0) { 120c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk i--; 121c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk try { 122c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk mRemoteCallbacks.getBroadcastItem(i).onVrStateChanged(state); 123c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk } catch (RemoteException e) { 124c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk // Noop 125c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk } 126c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk } 127c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk mRemoteCallbacks.finishBroadcast(); 128c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk } break; 129c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk default : 130c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk throw new IllegalStateException("Unknown message type: " + msg.what); 131c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk } 132c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk } 133c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk }; 134c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk 135e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private static final BinderChecker sBinderChecker = new BinderChecker() { 136e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 137e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public IInterface asInterface(IBinder binder) { 138e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return IVrListener.Stub.asInterface(binder); 139e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 140e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 141e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 142e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public boolean checkType(IInterface service) { 143e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return service instanceof IVrListener; 144e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 145e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk }; 146e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 147e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /** 148e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Called when a user, package, or setting changes that could affect whether or not the 149e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * currently bound VrListenerService is changed. 150e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 151e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 152e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onEnabledComponentChanged() { 153e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 154e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk if (mCurrentVrService == null) { 155e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return; // No active services 156e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 157e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 158e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk // There is an active service, update it if needed 159e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk updateCurrentVrServiceLocked(mVrModeEnabled, mCurrentVrService.getComponent(), 160c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk mCurrentVrService.getUserId(), null); 161e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 162e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 163dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 164c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk private final IVrManager mVrManager = new IVrManager.Stub() { 165c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk 166dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk @Override 167c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk public void registerListener(IVrStateCallbacks cb) { 168c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); 169c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk if (cb == null) { 170c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk throw new IllegalArgumentException("Callback binder object is null."); 171c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk } 172c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk 173c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk VrManagerService.this.addStateCallback(cb); 174dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 175dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 176dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk @Override 177c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk public void unregisterListener(IVrStateCallbacks cb) { 178c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); 179c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk if (cb == null) { 180c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk throw new IllegalArgumentException("Callback binder object is null."); 181c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk } 182c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk 183c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk VrManagerService.this.removeStateCallback(cb); 184dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 185dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 186dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk @Override 187c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk public boolean getVrModeState() { 188c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk return VrManagerService.this.getVrMode(); 189c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk } 190c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk 191dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler @Override 192dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 193dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 194dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler != PackageManager.PERMISSION_GRANTED) { 195dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler pw.println("permission denied: can't dump VrManagerService from pid=" 196dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 197dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler return; 198dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler } 199dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler pw.print("mVrModeEnabled="); 200dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler pw.println(mVrModeEnabled); 201dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler pw.print("mCurrentVrModeUser="); 202dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler pw.println(mCurrentVrModeUser); 203dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler pw.print("mRemoteCallbacks="); 204dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler int i=mRemoteCallbacks.beginBroadcast(); // create the broadcast item array 205dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler while(i-->0) { 206dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler pw.print(mRemoteCallbacks.getBroadcastItem(i)); 207dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler if (i>0) pw.print(", "); 208dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler } 209dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler mRemoteCallbacks.finishBroadcast(); 210dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler pw.println(); 211dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler pw.print("mCurrentVrService="); 212dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler pw.println(mCurrentVrService != null ? mCurrentVrService.getComponent() : "(none)"); 213dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler pw.print("mCurrentVrModeComponent="); 214dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler pw.println(mCurrentVrModeComponent); 215dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler } 216dc34df5d310245a268ee9ea3872a612c6f7950b5Dan Sandler 217c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk }; 218c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk 219c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk private void enforceCallerPermission(String permission) { 220c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk if (mContext.checkCallingOrSelfPermission(permission) 221c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk != PackageManager.PERMISSION_GRANTED) { 222c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk throw new SecurityException("Caller does not hold the permission " + permission); 2238f1d5cbabb3bc4ef61b9c2edc70fcfd5d75efec8Ruben Brunk } 224c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk } 2258f1d5cbabb3bc4ef61b9c2edc70fcfd5d75efec8Ruben Brunk 226c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk /** 227c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk * Implementation of VrManagerInternal. Callable only from system services. 228c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk */ 229c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk private final class LocalService extends VrManagerInternal { 2308f1d5cbabb3bc4ef61b9c2edc70fcfd5d75efec8Ruben Brunk @Override 231c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk public void setVrMode(boolean enabled, ComponentName packageName, int userId, 232c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk ComponentName callingPackage) { 233c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage); 234dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 235dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 236dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk @Override 237c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk public boolean isCurrentVrListener(String packageName, int userId) { 238c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk return VrManagerService.this.isCurrentVrListener(packageName, userId); 239dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 240e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 241e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 242e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public int hasVrPackage(ComponentName packageName, int userId) { 243e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return VrManagerService.this.hasVrPackage(packageName, userId); 244e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 245dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 246dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 247dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk public VrManagerService(Context context) { 248dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk super(context); 249dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 250dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 251dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk @Override 252dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk public void onStart() { 253baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk synchronized(mLock) { 254baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk initializeNative(); 255e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mContext = getContext(); 256baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk } 257baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk 258dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk publishLocalService(VrManagerInternal.class, new LocalService()); 259c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk publishBinderService(VR_MANAGER_BINDER_SERVICE, mVrManager.asBinder()); 260dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 261dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 262e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 263e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onBootPhase(int phase) { 2648507004a35a94e9bb4653dc049505aa54d1e6175Ruben Brunk if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { 265e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 266e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Looper looper = Looper.getMainLooper(); 267e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Handler handler = new Handler(looper); 268e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk ArrayList<EnabledComponentChangeListener> listeners = new ArrayList<>(); 269e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk listeners.add(this); 270e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver = EnabledComponentsObserver.build(mContext, handler, 271e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Settings.Secure.ENABLED_VR_LISTENERS, looper, 272e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk android.Manifest.permission.BIND_VR_LISTENER_SERVICE, 273e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk VrListenerService.SERVICE_INTERFACE, mLock, listeners); 274e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 275e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver.rebuildAll(); 276e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 277e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 278e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 279e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 280e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 281e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onStartUser(int userHandle) { 282dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk synchronized (mLock) { 283e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver.onUsersChanged(); 284dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 285dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 286dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 287e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 288e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onSwitchUser(int userHandle) { 289dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk synchronized (mLock) { 290e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver.onUsersChanged(); 291e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 292e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 293e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 294e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 295e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 296e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onStopUser(int userHandle) { 297e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 298e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver.onUsersChanged(); 299dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 300e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 301dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 302dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 303e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 304e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onCleanupUser(int userHandle) { 305dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk synchronized (mLock) { 306e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver.onUsersChanged(); 307dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 308dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 309dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 31029931bc684bde6b430923122777684178ee2681cRuben Brunk private void updateOverlayStateLocked(ComponentName exemptedComponent) { 31147d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 31247d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov try { 31347d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class); 31447d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov if (appOpsManager != null) { 31529931bc684bde6b430923122777684178ee2681cRuben Brunk String[] exemptions = (exemptedComponent == null) ? new String[0] : 31629931bc684bde6b430923122777684178ee2681cRuben Brunk new String[] { exemptedComponent.getPackageName() }; 31729931bc684bde6b430923122777684178ee2681cRuben Brunk 31847d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov appOpsManager.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, 31929931bc684bde6b430923122777684178ee2681cRuben Brunk mVrModeEnabled, mOverlayToken, exemptions); 32047d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov } 32147d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov } finally { 32247d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov Binder.restoreCallingIdentity(identity); 32347d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov } 32447d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov } 32547d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov 326e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /** 327e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Send VR mode changes (if the mode state has changed), and update the bound/unbound state of 328e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * the currently selected VR listener service. If the component selected for the VR listener 329e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * service has changed, unbind the previous listener and bind the new listener (if enabled). 330e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 331e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Note: Must be called while holding {@code mLock}. 332e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * 333e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @param enabled new state for VR mode. 334e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @param component new component to be bound as a VR listener. 335e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @param userId user owning the component to be bound. 336c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk * @param calling the component currently using VR mode, or null to leave unchanged. 337e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * 338e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @return {@code true} if the component/user combination specified is valid. 339e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 34098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private boolean updateCurrentVrServiceLocked(boolean enabled, @NonNull ComponentName component, 34198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk int userId, ComponentName calling) { 342c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk 343c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk boolean sendUpdatedCaller = false; 34498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk final long identity = Binder.clearCallingIdentity(); 34598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk try { 346e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 34798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk boolean validUserComponent = (mComponentObserver.isValid(component, userId) == 34898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk EnabledComponentsObserver.NO_ERROR); 349e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 35098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk // Always send mode change events. 35198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk changeVrModeLocked(enabled, (enabled && validUserComponent) ? component : null); 35229931bc684bde6b430923122777684178ee2681cRuben Brunk 35398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (!enabled || !validUserComponent) { 35498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk // Unbind whatever is running 35598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mCurrentVrService != null) { 356c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + " for user " + 35798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mCurrentVrService.getUserId()); 35898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mCurrentVrService.disconnect(); 35998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk disableImpliedPermissionsLocked(mCurrentVrService.getComponent(), 36098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk new UserHandle(mCurrentVrService.getUserId())); 36198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mCurrentVrService = null; 36298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 36398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } else { 36498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mCurrentVrService != null) { 36598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk // Unbind any running service that doesn't match the component/user selection 36698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mCurrentVrService.disconnectIfNotMatching(component, userId)) { 36798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + 36898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk " for user " + mCurrentVrService.getUserId()); 36998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk disableImpliedPermissionsLocked(mCurrentVrService.getComponent(), 37098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk new UserHandle(mCurrentVrService.getUserId())); 37198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk createAndConnectService(component, userId); 37298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk enableImpliedPermissionsLocked(mCurrentVrService.getComponent(), 37398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk new UserHandle(mCurrentVrService.getUserId())); 37498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk sendUpdatedCaller = true; 37598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 37698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk // The service with the correct component/user is bound 37798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } else { 37898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk // Nothing was previously running, bind a new service 379c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk createAndConnectService(component, userId); 38098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk enableImpliedPermissionsLocked(mCurrentVrService.getComponent(), 38198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk new UserHandle(mCurrentVrService.getUserId())); 382c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk sendUpdatedCaller = true; 383c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk } 38498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 38598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 38698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (calling != null && !Objects.equals(calling, mCurrentVrModeComponent)) { 38798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mCurrentVrModeComponent = calling; 38898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mCurrentVrModeUser = userId; 389c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk sendUpdatedCaller = true; 390e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 39198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 39298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mCurrentVrService != null && sendUpdatedCaller) { 39398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk final ComponentName c = mCurrentVrModeComponent; 39498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mCurrentVrService.sendEvent(new PendingEvent() { 39598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk @Override 39698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk public void runEvent(IInterface service) throws RemoteException { 39798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk IVrListener l = (IVrListener) service; 39898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk l.focusedActivityChanged(c); 39998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 40098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk }); 40198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 40298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 40398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return validUserComponent; 40498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } finally { 40598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Binder.restoreCallingIdentity(identity); 406c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk } 40798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 408c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk 40998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk /** 41098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * Enable the permission given in {@link #IMPLIED_VR_LISTENER_PERMISSIONS} for the given 41198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * component package and user. 41298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * 41398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * @param component the component whose package should be enabled. 41498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * @param userId the user that owns the given component. 41598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk */ 41698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void enableImpliedPermissionsLocked(ComponentName component, UserHandle userId) { 41798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mGuard) { 41898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk // Impossible 41998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk throw new IllegalStateException("Enabling permissions without disabling."); 420c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk } 42198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mGuard = true; 422c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk 42398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk PackageManager pm = mContext.getPackageManager(); 42498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 42598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk String pName = component.getPackageName(); 42698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (pm == null) { 42798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Slog.e(TAG, "Couldn't set implied permissions for " + pName + 42898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ", PackageManager isn't running"); 42998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return; 430e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 431e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 43298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ApplicationInfo info = null; 43398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk try { 43498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk info = pm.getApplicationInfo(pName, PackageManager.GET_META_DATA); 43598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } catch (NameNotFoundException e) { 43698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 43798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 43898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (info == null) { 43998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Slog.e(TAG, "Couldn't set implied permissions for " + pName + ", no such package."); 44098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return; 44198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 44298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 44398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (!(info.isSystemApp() || info.isUpdatedSystemApp())) { 44498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return; // Application is not pre-installed, avoid setting implied permissions 44598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 44698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 44798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mWasDefaultGranted = true; 44898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 44998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk grantOverlayAccess(pName, userId); 45098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk grantNotificationPolicyAccess(pName); 45198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk grantNotificationListenerAccess(pName, userId); 452e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 453e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 45498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk /** 45598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * Disable the permission given in {@link #IMPLIED_VR_LISTENER_PERMISSIONS} for the given 45698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * component package and user. 45798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * 45898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * @param component the component whose package should be disabled. 45998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * @param userId the user that owns the given component. 46098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk */ 46198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void disableImpliedPermissionsLocked(ComponentName component, UserHandle userId) { 46298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (!mGuard) { 46398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk // Impossible 46498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk throw new IllegalStateException("Disabling permissions without enabling."); 46598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 46698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mGuard = false; 46798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 46898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk PackageManager pm = mContext.getPackageManager(); 46998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 47098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (pm == null) { 47198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Slog.e(TAG, "Couldn't remove implied permissions for " + component + 47298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ", PackageManager isn't running"); 47398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return; 47498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 47598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 47698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk String pName = component.getPackageName(); 47798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mWasDefaultGranted) { 47898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk revokeOverlayAccess(userId); 47998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk revokeNotificationPolicyAccess(pName); 48098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk revokeNotificiationListenerAccess(); 48198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mWasDefaultGranted = false; 48298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 48398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 48498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 48598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 48698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void grantOverlayAccess(String pkg, UserHandle userId) { 48798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk PackageManager pm = mContext.getPackageManager(); 48898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk boolean prev = (PackageManager.PERMISSION_GRANTED == 48998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk pm.checkPermission(android.Manifest.permission.SYSTEM_ALERT_WINDOW, pkg)); 49098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousManageOverlayPackage = null; 49198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (!prev) { 49298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk pm.grantRuntimePermission(pkg, android.Manifest.permission.SYSTEM_ALERT_WINDOW, 49398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk userId); 49498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousManageOverlayPackage = pkg; 49598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 49698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 49798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 49898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void revokeOverlayAccess(UserHandle userId) { 49998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk PackageManager pm = mContext.getPackageManager(); 50098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mPreviousManageOverlayPackage != null) { 50198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk pm.revokeRuntimePermission(mPreviousManageOverlayPackage, 50298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk android.Manifest.permission.SYSTEM_ALERT_WINDOW, userId); 50398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousManageOverlayPackage = null; 50498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 50598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 50698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 50798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 50898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void grantNotificationPolicyAccess(String pkg) { 50998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk NotificationManager nm = mContext.getSystemService(NotificationManager.class); 51098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk boolean prev = nm.isNotificationPolicyAccessGrantedForPackage(pkg); 51198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousNotificationPolicyAccessPackage = null; 51298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (!prev) { 51398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousNotificationPolicyAccessPackage = pkg; 51498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk nm.setNotificationPolicyAccessGranted(pkg, true); 51598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 51698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 51798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 51898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void revokeNotificationPolicyAccess(String pkg) { 51998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk NotificationManager nm = mContext.getSystemService(NotificationManager.class); 52098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mPreviousNotificationPolicyAccessPackage != null) { 5210c9ac648190a3f0e850d4fe376002f7a11654a87Ariana Mott if (mPreviousNotificationPolicyAccessPackage.equals(pkg)) { 5220c9ac648190a3f0e850d4fe376002f7a11654a87Ariana Mott // Remove any DND zen rules possibly created by the package. 5230c9ac648190a3f0e850d4fe376002f7a11654a87Ariana Mott nm.removeAutomaticZenRules(mPreviousNotificationPolicyAccessPackage); 5240c9ac648190a3f0e850d4fe376002f7a11654a87Ariana Mott // Remove Notification Policy Access. 5250c9ac648190a3f0e850d4fe376002f7a11654a87Ariana Mott nm.setNotificationPolicyAccessGranted(mPreviousNotificationPolicyAccessPackage, false); 5260c9ac648190a3f0e850d4fe376002f7a11654a87Ariana Mott mPreviousNotificationPolicyAccessPackage = null; 5270c9ac648190a3f0e850d4fe376002f7a11654a87Ariana Mott } else { 5280c9ac648190a3f0e850d4fe376002f7a11654a87Ariana Mott Slog.e(TAG, "Couldn't remove Notification Policy Access for package: " + pkg); 5290c9ac648190a3f0e850d4fe376002f7a11654a87Ariana Mott } 53098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 53198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 53298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 53398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void grantNotificationListenerAccess(String pkg, UserHandle userId) { 53498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk PackageManager pm = mContext.getPackageManager(); 53598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ArraySet<ComponentName> possibleServices = EnabledComponentsObserver.loadComponentNames(pm, 53698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk userId.getIdentifier(), NotificationListenerService.SERVICE_INTERFACE, 53798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE); 53898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ContentResolver resolver = mContext.getContentResolver(); 53998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 54098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ArraySet<String> current = getCurrentNotifListeners(resolver); 54198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 54298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousToggledListenerSettings.clear(); 54398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 54498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk for (ComponentName c : possibleServices) { 54598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk String flatName = c.flattenToString(); 54698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (Objects.equals(c.getPackageName(), pkg) 54798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk && !current.contains(flatName)) { 54898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousToggledListenerSettings.add(flatName); 54998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk current.add(flatName); 55098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 55198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 55298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 55398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (current.size() > 0) { 55498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk String flatSettings = formatSettings(current); 55598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Settings.Secure.putString(resolver, Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, 55698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk flatSettings); 55798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 55898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 55998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 56098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void revokeNotificiationListenerAccess() { 56198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mPreviousToggledListenerSettings.isEmpty()) { 56298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return; 56398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 56498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 56598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ContentResolver resolver = mContext.getContentResolver(); 56698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ArraySet<String> current = getCurrentNotifListeners(resolver); 56798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 56898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk current.removeAll(mPreviousToggledListenerSettings); 56998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousToggledListenerSettings.clear(); 57098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 57198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk String flatSettings = formatSettings(current); 57298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Settings.Secure.putString(resolver, Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, 57398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk flatSettings); 57498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 57598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 57698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private ArraySet<String> getCurrentNotifListeners(ContentResolver resolver) { 57798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk String flat = Settings.Secure.getString(resolver, 57898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Settings.Secure.ENABLED_NOTIFICATION_LISTENERS); 57998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 58098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ArraySet<String> current = new ArraySet<>(); 58198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (flat != null) { 58298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk String[] allowed = flat.split(":"); 58398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk for (String s : allowed) { 58498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk current.add(s); 58598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 58698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 58798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return current; 58898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 58998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 59098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private static String formatSettings(Collection<String> c) { 59198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (c == null || c.isEmpty()) { 59298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return ""; 59398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 59498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 59598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk StringBuilder b = new StringBuilder(); 59698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk boolean start = true; 59798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk for (String s : c) { 59898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if ("".equals(s)) { 59998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk continue; 60098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 60198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (!start) { 60298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk b.append(':'); 60398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 60498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk b.append(s); 60598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk start = false; 60698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 60798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return b.toString(); 60898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 60998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 61098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 61198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 612c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk private void createAndConnectService(@NonNull ComponentName component, int userId) { 613c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk mCurrentVrService = VrManagerService.create(mContext, component, userId); 614c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk mCurrentVrService.connect(); 615c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk Slog.i(TAG, "Connecting " + component + " for user " + userId); 616c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk } 617c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk 618e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /** 619e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Send VR mode change callbacks to HAL and system services if mode has actually changed. 620e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 621e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Note: Must be called while holding {@code mLock}. 622e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * 623e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @param enabled new state of the VR mode. 62429931bc684bde6b430923122777684178ee2681cRuben Brunk * @param exemptedComponent a component to exempt from AppOps restrictions for overlays. 625e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 62629931bc684bde6b430923122777684178ee2681cRuben Brunk private void changeVrModeLocked(boolean enabled, ComponentName exemptedComponent) { 627e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk if (mVrModeEnabled != enabled) { 628e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mVrModeEnabled = enabled; 629e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 630e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk // Log mode change event. 631e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled")); 632e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk setVrModeNative(mVrModeEnabled); 633e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 63429931bc684bde6b430923122777684178ee2681cRuben Brunk updateOverlayStateLocked(exemptedComponent); 635e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk onVrModeChangedLocked(); 636dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 637dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 638dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 639dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk /** 640dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * Notify system services of VR mode change. 641e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 642e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Note: Must be called while holding {@code mLock}. 643dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk */ 644dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk private void onVrModeChangedLocked() { 645c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk mHandler.sendMessage(mHandler.obtainMessage(MSG_VR_STATE_CHANGE, 646c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk (mVrModeEnabled) ? 1 : 0, 0)); 647dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 648e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 649e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /** 650e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Helper function for making ManagedApplicationService instances. 651e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 652e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private static ManagedApplicationService create(@NonNull Context context, 653e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @NonNull ComponentName component, int userId) { 654e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return ManagedApplicationService.build(context, component, userId, 655e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk R.string.vr_listener_binding_label, Settings.ACTION_VR_LISTENER_SETTINGS, 656e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk sBinderChecker); 657e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 658e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 659e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /* 660e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Implementation of VrManagerInternal calls. These are callable from system services. 661e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 662e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 663e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private boolean setVrMode(boolean enabled, @NonNull ComponentName targetPackageName, 664c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk int userId, @NonNull ComponentName callingPackage) { 665e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 666c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk return updateCurrentVrServiceLocked(enabled, targetPackageName, userId, callingPackage); 667e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 668e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 669e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 670c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) { 671e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 672c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk return mComponentObserver.isValid(targetPackageName, userId); 673e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 674e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 675e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 6768f1d5cbabb3bc4ef61b9c2edc70fcfd5d75efec8Ruben Brunk private boolean isCurrentVrListener(String packageName, int userId) { 6778f1d5cbabb3bc4ef61b9c2edc70fcfd5d75efec8Ruben Brunk synchronized (mLock) { 6788f1d5cbabb3bc4ef61b9c2edc70fcfd5d75efec8Ruben Brunk if (mCurrentVrService == null) { 6798f1d5cbabb3bc4ef61b9c2edc70fcfd5d75efec8Ruben Brunk return false; 6808f1d5cbabb3bc4ef61b9c2edc70fcfd5d75efec8Ruben Brunk } 6818f1d5cbabb3bc4ef61b9c2edc70fcfd5d75efec8Ruben Brunk return mCurrentVrService.getComponent().getPackageName().equals(packageName) && 6828f1d5cbabb3bc4ef61b9c2edc70fcfd5d75efec8Ruben Brunk userId == mCurrentVrService.getUserId(); 6838f1d5cbabb3bc4ef61b9c2edc70fcfd5d75efec8Ruben Brunk } 6848f1d5cbabb3bc4ef61b9c2edc70fcfd5d75efec8Ruben Brunk } 6858f1d5cbabb3bc4ef61b9c2edc70fcfd5d75efec8Ruben Brunk 686c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk /* 687c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk * Implementation of IVrManager calls. 688c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk */ 689c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk 690c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk private void addStateCallback(IVrStateCallbacks cb) { 691c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk mRemoteCallbacks.register(cb); 692e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 693e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 694c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk private void removeStateCallback(IVrStateCallbacks cb) { 695c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk mRemoteCallbacks.unregister(cb); 696e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 697e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 698c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk private boolean getVrMode() { 699e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 700c7be3beced4ade05466a4a77c003ea81c2429f74Ruben Brunk return mVrModeEnabled; 701e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 702e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 703dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk} 704