VrManagerService.java revision 98576cf949a1ffbece3722451713aac01ed27968
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; 1998576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.app.NotificationManager; 20e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.annotation.NonNull; 21e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.content.ComponentName; 2298576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.content.ContentResolver; 2398576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.content.Context; 2498576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.content.pm.ApplicationInfo; 2598576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.content.pm.PackageManager; 2698576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.content.pm.PackageManager.NameNotFoundException; 2747d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganovimport android.os.Binder; 28e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.os.Handler; 2947d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganovimport android.os.IBinder; 30e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.os.IInterface; 31e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.os.Looper; 32c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunkimport android.os.RemoteException; 3398576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.os.UserHandle; 34e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.provider.Settings; 3598576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport android.service.notification.NotificationListenerService; 36e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.service.vr.IVrListener; 37e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport android.service.vr.VrListenerService; 38dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport android.util.ArraySet; 39dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport android.util.Slog; 40dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 41e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport com.android.internal.R; 42dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport com.android.server.SystemService; 43c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunkimport com.android.server.utils.ManagedApplicationService.PendingEvent; 44e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport com.android.server.vr.EnabledComponentsObserver.EnabledComponentChangeListener; 45e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport com.android.server.utils.ManagedApplicationService; 46e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport com.android.server.utils.ManagedApplicationService.BinderChecker; 47dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 4898576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport java.lang.StringBuilder; 49dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunkimport java.util.ArrayList; 5098576cf949a1ffbece3722451713aac01ed27968Ruben Brunkimport java.util.Collection; 51c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunkimport java.util.Objects; 52e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkimport java.util.Set; 53dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 54dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk/** 55e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Service tracking whether VR mode is active, and notifying listening services of state changes. 56e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 57e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Services running in system server may modify the state of VrManagerService via the interface in 58e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * VrManagerInternal, and may register to receive callbacks when the system VR mode changes via the 59e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * interface given in VrStateListener. 60e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 61e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Device vendors may choose to receive VR state changes by implementing the VR mode HAL, e.g.: 62e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * hardware/libhardware/modules/vr 63e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 64e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * In general applications may enable or disable VR mode by calling 6598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * {@link android.app.Activity#setVrModeEnabled)}. An application may also implement a service to 6698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * be run while in VR mode by implementing {@link android.service.vr.VrListenerService}. 67e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * 68e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @see {@link android.service.vr.VrListenerService} 69e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @see {@link com.android.server.vr.VrManagerInternal} 70e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @see {@link com.android.server.vr.VrStateListener} 71dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * 72e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @hide 73dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk */ 74e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunkpublic class VrManagerService extends SystemService implements EnabledComponentChangeListener{ 75dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 76dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk public static final String TAG = "VrManagerService"; 77dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 78baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk private static native void initializeNative(); 79baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk private static native void setVrModeNative(boolean enabled); 80baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk 81dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk private final Object mLock = new Object(); 8247d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov 8347d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov private final IBinder mOverlayToken = new Binder(); 8447d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov 85e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk // State protected by mLock 8698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private boolean mVrModeEnabled; 87e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private final Set<VrStateListener> mListeners = new ArraySet<>(); 88e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private EnabledComponentsObserver mComponentObserver; 89e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private ManagedApplicationService mCurrentVrService; 90e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private Context mContext; 91c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk private ComponentName mCurrentVrModeComponent; 92c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk private int mCurrentVrModeUser; 9398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private boolean mWasDefaultGranted; 9498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private boolean mGuard; 9598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private final ArraySet<String> mPreviousToggledListenerSettings = new ArraySet<>(); 9698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private String mPreviousNotificationPolicyAccessPackage; 9798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private String mPreviousManageOverlayPackage; 98e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 99e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private static final BinderChecker sBinderChecker = new BinderChecker() { 100e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 101e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public IInterface asInterface(IBinder binder) { 102e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return IVrListener.Stub.asInterface(binder); 103e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 104e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 105e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 106e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public boolean checkType(IInterface service) { 107e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return service instanceof IVrListener; 108e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 109e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk }; 110e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 111e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /** 112e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Called when a user, package, or setting changes that could affect whether or not the 113e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * currently bound VrListenerService is changed. 114e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 115e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 116e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onEnabledComponentChanged() { 117e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 118e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk if (mCurrentVrService == null) { 119e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return; // No active services 120e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 121e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 122e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk // There is an active service, update it if needed 123e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk updateCurrentVrServiceLocked(mVrModeEnabled, mCurrentVrService.getComponent(), 124c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk mCurrentVrService.getUserId(), null); 125e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 126e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 127dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 128e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /** 129e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Implementation of VrManagerInternal. Callable only from system services. 130e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 131dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk private final class LocalService extends VrManagerInternal { 132dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk @Override 133dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk public boolean isInVrMode() { 134dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk return VrManagerService.this.getVrMode(); 135dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 136dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 137dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk @Override 138c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk public void setVrMode(boolean enabled, ComponentName packageName, int userId, 139c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk ComponentName callingPackage) { 140c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage); 141dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 142dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 143dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk @Override 144dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk public void registerListener(VrStateListener listener) { 145dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk VrManagerService.this.addListener(listener); 146dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 147dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 148dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk @Override 149dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk public void unregisterListener(VrStateListener listener) { 150dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk VrManagerService.this.removeListener(listener); 151dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 152e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 153e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 154e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public int hasVrPackage(ComponentName packageName, int userId) { 155e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return VrManagerService.this.hasVrPackage(packageName, userId); 156e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 157dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 158dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 159dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk public VrManagerService(Context context) { 160dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk super(context); 161dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 162dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 163dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk @Override 164dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk public void onStart() { 165baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk synchronized(mLock) { 166baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk initializeNative(); 167e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mContext = getContext(); 168baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk } 169baa4b55b892041fc33f3acdf29de0676ab63c2f9Ruben Brunk 170dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk publishLocalService(VrManagerInternal.class, new LocalService()); 171dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 172dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 173e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 174e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onBootPhase(int phase) { 1758507004a35a94e9bb4653dc049505aa54d1e6175Ruben Brunk if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { 176e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 177e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Looper looper = Looper.getMainLooper(); 178e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Handler handler = new Handler(looper); 179e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk ArrayList<EnabledComponentChangeListener> listeners = new ArrayList<>(); 180e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk listeners.add(this); 181e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver = EnabledComponentsObserver.build(mContext, handler, 182e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Settings.Secure.ENABLED_VR_LISTENERS, looper, 183e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk android.Manifest.permission.BIND_VR_LISTENER_SERVICE, 184e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk VrListenerService.SERVICE_INTERFACE, mLock, listeners); 185e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 186e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver.rebuildAll(); 187e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 188e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 189e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 190e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 191e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 192e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onStartUser(int userHandle) { 193dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk synchronized (mLock) { 194e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver.onUsersChanged(); 195dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 196dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 197dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 198e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 199e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onSwitchUser(int userHandle) { 200dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk synchronized (mLock) { 201e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver.onUsersChanged(); 202e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 203e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 204e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 205e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 206e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 207e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onStopUser(int userHandle) { 208e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 209e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver.onUsersChanged(); 210dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 211e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 212dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 213dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 214e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @Override 215e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk public void onCleanupUser(int userHandle) { 216dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk synchronized (mLock) { 217e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mComponentObserver.onUsersChanged(); 218dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 219dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 220dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 22129931bc684bde6b430923122777684178ee2681cRuben Brunk private void updateOverlayStateLocked(ComponentName exemptedComponent) { 22247d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 22347d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov try { 22447d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class); 22547d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov if (appOpsManager != null) { 22629931bc684bde6b430923122777684178ee2681cRuben Brunk String[] exemptions = (exemptedComponent == null) ? new String[0] : 22729931bc684bde6b430923122777684178ee2681cRuben Brunk new String[] { exemptedComponent.getPackageName() }; 22829931bc684bde6b430923122777684178ee2681cRuben Brunk 22947d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov appOpsManager.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, 23029931bc684bde6b430923122777684178ee2681cRuben Brunk mVrModeEnabled, mOverlayToken, exemptions); 23147d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov } 23247d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov } finally { 23347d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov Binder.restoreCallingIdentity(identity); 23447d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov } 23547d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov } 23647d98de60bc5504271e027aef0b7ea218f0aaf59Svetoslav Ganov 237e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /** 238e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Send VR mode changes (if the mode state has changed), and update the bound/unbound state of 239e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * the currently selected VR listener service. If the component selected for the VR listener 240e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * service has changed, unbind the previous listener and bind the new listener (if enabled). 241e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 242e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Note: Must be called while holding {@code mLock}. 243e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * 244e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @param enabled new state for VR mode. 245e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @param component new component to be bound as a VR listener. 246e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @param userId user owning the component to be bound. 247c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk * @param calling the component currently using VR mode, or null to leave unchanged. 248e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * 249e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @return {@code true} if the component/user combination specified is valid. 250e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 25198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private boolean updateCurrentVrServiceLocked(boolean enabled, @NonNull ComponentName component, 25298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk int userId, ComponentName calling) { 253c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk 254c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk boolean sendUpdatedCaller = false; 25598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk final long identity = Binder.clearCallingIdentity(); 25698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk try { 257e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 25898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk boolean validUserComponent = (mComponentObserver.isValid(component, userId) == 25998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk EnabledComponentsObserver.NO_ERROR); 260e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 26198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk // Always send mode change events. 26298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk changeVrModeLocked(enabled, (enabled && validUserComponent) ? component : null); 26329931bc684bde6b430923122777684178ee2681cRuben Brunk 26498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (!enabled || !validUserComponent) { 26598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk // Unbind whatever is running 26698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mCurrentVrService != null) { 267c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + " for user " + 26898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mCurrentVrService.getUserId()); 26998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mCurrentVrService.disconnect(); 27098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk disableImpliedPermissionsLocked(mCurrentVrService.getComponent(), 27198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk new UserHandle(mCurrentVrService.getUserId())); 27298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mCurrentVrService = null; 27398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 27498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } else { 27598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mCurrentVrService != null) { 27698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk // Unbind any running service that doesn't match the component/user selection 27798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mCurrentVrService.disconnectIfNotMatching(component, userId)) { 27898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + 27998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk " for user " + mCurrentVrService.getUserId()); 28098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk disableImpliedPermissionsLocked(mCurrentVrService.getComponent(), 28198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk new UserHandle(mCurrentVrService.getUserId())); 28298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk createAndConnectService(component, userId); 28398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk enableImpliedPermissionsLocked(mCurrentVrService.getComponent(), 28498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk new UserHandle(mCurrentVrService.getUserId())); 28598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk sendUpdatedCaller = true; 28698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 28798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk // The service with the correct component/user is bound 28898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } else { 28998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk // Nothing was previously running, bind a new service 290c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk createAndConnectService(component, userId); 29198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk enableImpliedPermissionsLocked(mCurrentVrService.getComponent(), 29298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk new UserHandle(mCurrentVrService.getUserId())); 293c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk sendUpdatedCaller = true; 294c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk } 29598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 29698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 29798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (calling != null && !Objects.equals(calling, mCurrentVrModeComponent)) { 29898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mCurrentVrModeComponent = calling; 29998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mCurrentVrModeUser = userId; 300c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk sendUpdatedCaller = true; 301e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 30298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 30398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mCurrentVrService != null && sendUpdatedCaller) { 30498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk final ComponentName c = mCurrentVrModeComponent; 30598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mCurrentVrService.sendEvent(new PendingEvent() { 30698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk @Override 30798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk public void runEvent(IInterface service) throws RemoteException { 30898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk IVrListener l = (IVrListener) service; 30998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk l.focusedActivityChanged(c); 31098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 31198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk }); 31298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 31398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 31498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return validUserComponent; 31598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } finally { 31698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Binder.restoreCallingIdentity(identity); 317c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk } 31898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 319c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk 32098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk /** 32198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * Enable the permission given in {@link #IMPLIED_VR_LISTENER_PERMISSIONS} for the given 32298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * component package and user. 32398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * 32498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * @param component the component whose package should be enabled. 32598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * @param userId the user that owns the given component. 32698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk */ 32798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void enableImpliedPermissionsLocked(ComponentName component, UserHandle userId) { 32898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mGuard) { 32998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk // Impossible 33098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk throw new IllegalStateException("Enabling permissions without disabling."); 331c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk } 33298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mGuard = true; 333c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk 33498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk PackageManager pm = mContext.getPackageManager(); 33598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 33698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk String pName = component.getPackageName(); 33798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (pm == null) { 33898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Slog.e(TAG, "Couldn't set implied permissions for " + pName + 33998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ", PackageManager isn't running"); 34098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return; 341e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 342e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 34398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ApplicationInfo info = null; 34498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk try { 34598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk info = pm.getApplicationInfo(pName, PackageManager.GET_META_DATA); 34698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } catch (NameNotFoundException e) { 34798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 34898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 34998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (info == null) { 35098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Slog.e(TAG, "Couldn't set implied permissions for " + pName + ", no such package."); 35198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return; 35298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 35398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 35498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (!(info.isSystemApp() || info.isUpdatedSystemApp())) { 35598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return; // Application is not pre-installed, avoid setting implied permissions 35698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 35798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 35898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mWasDefaultGranted = true; 35998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 36098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk grantOverlayAccess(pName, userId); 36198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk grantNotificationPolicyAccess(pName); 36298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk grantNotificationListenerAccess(pName, userId); 363e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 364e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 36598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk /** 36698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * Disable the permission given in {@link #IMPLIED_VR_LISTENER_PERMISSIONS} for the given 36798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * component package and user. 36898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * 36998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * @param component the component whose package should be disabled. 37098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk * @param userId the user that owns the given component. 37198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk */ 37298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void disableImpliedPermissionsLocked(ComponentName component, UserHandle userId) { 37398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (!mGuard) { 37498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk // Impossible 37598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk throw new IllegalStateException("Disabling permissions without enabling."); 37698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 37798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mGuard = false; 37898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 37998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk PackageManager pm = mContext.getPackageManager(); 38098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 38198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (pm == null) { 38298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Slog.e(TAG, "Couldn't remove implied permissions for " + component + 38398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ", PackageManager isn't running"); 38498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return; 38598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 38698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 38798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk String pName = component.getPackageName(); 38898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mWasDefaultGranted) { 38998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk revokeOverlayAccess(userId); 39098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk revokeNotificationPolicyAccess(pName); 39198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk revokeNotificiationListenerAccess(); 39298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mWasDefaultGranted = false; 39398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 39498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 39598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 39698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 39798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void grantOverlayAccess(String pkg, UserHandle userId) { 39898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk PackageManager pm = mContext.getPackageManager(); 39998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk boolean prev = (PackageManager.PERMISSION_GRANTED == 40098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk pm.checkPermission(android.Manifest.permission.SYSTEM_ALERT_WINDOW, pkg)); 40198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousManageOverlayPackage = null; 40298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (!prev) { 40398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk pm.grantRuntimePermission(pkg, android.Manifest.permission.SYSTEM_ALERT_WINDOW, 40498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk userId); 40598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousManageOverlayPackage = pkg; 40698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 40798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 40898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 40998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void revokeOverlayAccess(UserHandle userId) { 41098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk PackageManager pm = mContext.getPackageManager(); 41198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mPreviousManageOverlayPackage != null) { 41298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk pm.revokeRuntimePermission(mPreviousManageOverlayPackage, 41398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk android.Manifest.permission.SYSTEM_ALERT_WINDOW, userId); 41498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousManageOverlayPackage = null; 41598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 41698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 41798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 41898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 41998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void grantNotificationPolicyAccess(String pkg) { 42098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk NotificationManager nm = mContext.getSystemService(NotificationManager.class); 42198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk boolean prev = nm.isNotificationPolicyAccessGrantedForPackage(pkg); 42298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousNotificationPolicyAccessPackage = null; 42398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (!prev) { 42498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousNotificationPolicyAccessPackage = pkg; 42598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk nm.setNotificationPolicyAccessGranted(pkg, true); 42698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 42798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 42898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 42998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void revokeNotificationPolicyAccess(String pkg) { 43098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk NotificationManager nm = mContext.getSystemService(NotificationManager.class); 43198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mPreviousNotificationPolicyAccessPackage != null) { 43298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk nm.setNotificationPolicyAccessGranted(mPreviousNotificationPolicyAccessPackage, false); 43398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousNotificationPolicyAccessPackage = null; 43498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 43598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 43698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 43798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void grantNotificationListenerAccess(String pkg, UserHandle userId) { 43898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk PackageManager pm = mContext.getPackageManager(); 43998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ArraySet<ComponentName> possibleServices = EnabledComponentsObserver.loadComponentNames(pm, 44098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk userId.getIdentifier(), NotificationListenerService.SERVICE_INTERFACE, 44198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE); 44298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ContentResolver resolver = mContext.getContentResolver(); 44398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 44498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ArraySet<String> current = getCurrentNotifListeners(resolver); 44598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 44698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousToggledListenerSettings.clear(); 44798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 44898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk for (ComponentName c : possibleServices) { 44998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk String flatName = c.flattenToString(); 45098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (Objects.equals(c.getPackageName(), pkg) 45198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk && !current.contains(flatName)) { 45298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousToggledListenerSettings.add(flatName); 45398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk current.add(flatName); 45498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 45598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 45698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 45798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (current.size() > 0) { 45898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk String flatSettings = formatSettings(current); 45998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Settings.Secure.putString(resolver, Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, 46098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk flatSettings); 46198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 46298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 46398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 46498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private void revokeNotificiationListenerAccess() { 46598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (mPreviousToggledListenerSettings.isEmpty()) { 46698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return; 46798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 46898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 46998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ContentResolver resolver = mContext.getContentResolver(); 47098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ArraySet<String> current = getCurrentNotifListeners(resolver); 47198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 47298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk current.removeAll(mPreviousToggledListenerSettings); 47398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk mPreviousToggledListenerSettings.clear(); 47498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 47598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk String flatSettings = formatSettings(current); 47698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Settings.Secure.putString(resolver, Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, 47798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk flatSettings); 47898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 47998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 48098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private ArraySet<String> getCurrentNotifListeners(ContentResolver resolver) { 48198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk String flat = Settings.Secure.getString(resolver, 48298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk Settings.Secure.ENABLED_NOTIFICATION_LISTENERS); 48398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 48498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk ArraySet<String> current = new ArraySet<>(); 48598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (flat != null) { 48698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk String[] allowed = flat.split(":"); 48798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk for (String s : allowed) { 48898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk current.add(s); 48998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 49098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 49198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return current; 49298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 49398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 49498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk private static String formatSettings(Collection<String> c) { 49598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (c == null || c.isEmpty()) { 49698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return ""; 49798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 49898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 49998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk StringBuilder b = new StringBuilder(); 50098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk boolean start = true; 50198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk for (String s : c) { 50298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if ("".equals(s)) { 50398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk continue; 50498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 50598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk if (!start) { 50698576cf949a1ffbece3722451713aac01ed27968Ruben Brunk b.append(':'); 50798576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 50898576cf949a1ffbece3722451713aac01ed27968Ruben Brunk b.append(s); 50998576cf949a1ffbece3722451713aac01ed27968Ruben Brunk start = false; 51098576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 51198576cf949a1ffbece3722451713aac01ed27968Ruben Brunk return b.toString(); 51298576cf949a1ffbece3722451713aac01ed27968Ruben Brunk } 51398576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 51498576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 51598576cf949a1ffbece3722451713aac01ed27968Ruben Brunk 516c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk private void createAndConnectService(@NonNull ComponentName component, int userId) { 517c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk mCurrentVrService = VrManagerService.create(mContext, component, userId); 518c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk mCurrentVrService.connect(); 519c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk Slog.i(TAG, "Connecting " + component + " for user " + userId); 520c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk } 521c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk 522e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /** 523e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Send VR mode change callbacks to HAL and system services if mode has actually changed. 524e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 525e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Note: Must be called while holding {@code mLock}. 526e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * 527e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * @param enabled new state of the VR mode. 52829931bc684bde6b430923122777684178ee2681cRuben Brunk * @param exemptedComponent a component to exempt from AppOps restrictions for overlays. 529e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 53029931bc684bde6b430923122777684178ee2681cRuben Brunk private void changeVrModeLocked(boolean enabled, ComponentName exemptedComponent) { 531e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk if (mVrModeEnabled != enabled) { 532e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mVrModeEnabled = enabled; 533e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 534e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk // Log mode change event. 535e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled")); 536e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk setVrModeNative(mVrModeEnabled); 537e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 53829931bc684bde6b430923122777684178ee2681cRuben Brunk updateOverlayStateLocked(exemptedComponent); 539e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk onVrModeChangedLocked(); 540dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 541dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 542dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk 543dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk /** 544dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk * Notify system services of VR mode change. 545e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * <p/> 546e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Note: Must be called while holding {@code mLock}. 547dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk */ 548dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk private void onVrModeChangedLocked() { 549dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk for (VrStateListener l : mListeners) { 550dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk l.onVrStateChanged(mVrModeEnabled); 551dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 552dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk } 553e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 554e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /** 555e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Helper function for making ManagedApplicationService instances. 556e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 557e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private static ManagedApplicationService create(@NonNull Context context, 558e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk @NonNull ComponentName component, int userId) { 559e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return ManagedApplicationService.build(context, component, userId, 560e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk R.string.vr_listener_binding_label, Settings.ACTION_VR_LISTENER_SETTINGS, 561e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk sBinderChecker); 562e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 563e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 564e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk /* 565e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk * Implementation of VrManagerInternal calls. These are callable from system services. 566e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk */ 567e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 568e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private boolean setVrMode(boolean enabled, @NonNull ComponentName targetPackageName, 569c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk int userId, @NonNull ComponentName callingPackage) { 570e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 571c7354fe2d4d73808929d2087f2d18ee3d8fa47fcRuben Brunk return updateCurrentVrServiceLocked(enabled, targetPackageName, userId, callingPackage); 572e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 573e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 574e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 575e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private boolean getVrMode() { 576e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 577e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return mVrModeEnabled; 578e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 579e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 580e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 581e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private void addListener(VrStateListener listener) { 582e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 583e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mListeners.add(listener); 584e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 585e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 586e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 587e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private void removeListener(VrStateListener listener) { 588e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 589e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk mListeners.remove(listener); 590e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 591e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 592e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk 593e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) { 594e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk synchronized (mLock) { 595e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk return mComponentObserver.isValid(targetPackageName, userId); 596e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 597e24b9a6cfa4d565d7f49c9ae8f3aeca737d93312Ruben Brunk } 598dd18a0b69537954d1cc34929a1386deb54f12b14Ruben Brunk} 599