VrManagerService.java revision 8820f943e0254e188861ef4bc73a95cefc648942
1/**
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.server.vr;
17
18import android.Manifest;
19import android.app.ActivityManager;
20import android.app.AppOpsManager;
21import android.app.NotificationManager;
22import android.annotation.NonNull;
23import android.content.BroadcastReceiver;
24import android.content.ComponentName;
25import android.content.ContentResolver;
26import android.content.Context;
27import android.content.Intent;
28import android.content.IntentFilter;
29import android.content.pm.ApplicationInfo;
30import android.content.pm.FeatureInfo;
31import android.content.pm.PackageInfo;
32import android.content.pm.PackageManager;
33import android.content.pm.PackageManager.NameNotFoundException;
34import android.os.Binder;
35import android.os.Handler;
36import android.os.IBinder;
37import android.os.IInterface;
38import android.os.Looper;
39import android.os.Message;
40import android.os.RemoteCallbackList;
41import android.os.RemoteException;
42import android.os.UserHandle;
43import android.provider.Settings;
44import android.service.notification.NotificationListenerService;
45import android.service.vr.IVrListener;
46import android.service.vr.IVrManager;
47import android.service.vr.IVrStateCallbacks;
48import android.service.vr.VrListenerService;
49import android.util.ArraySet;
50import android.util.Slog;
51import android.util.SparseArray;
52
53import com.android.internal.R;
54import com.android.server.SystemConfig;
55import com.android.server.SystemService;
56import com.android.server.utils.ManagedApplicationService.PendingEvent;
57import com.android.server.vr.EnabledComponentsObserver.EnabledComponentChangeListener;
58import com.android.server.utils.ManagedApplicationService;
59import com.android.server.utils.ManagedApplicationService.BinderChecker;
60
61import java.io.FileDescriptor;
62import java.io.PrintWriter;
63import java.lang.StringBuilder;
64import java.text.SimpleDateFormat;
65import java.util.ArrayDeque;
66import java.util.ArrayList;
67import java.util.Collection;
68import java.util.Date;
69import java.util.List;
70import java.util.Objects;
71
72/**
73 * Service tracking whether VR mode is active, and notifying listening services of state changes.
74 * <p/>
75 * Services running in system server may modify the state of VrManagerService via the interface in
76 * VrManagerInternal, and may register to receive callbacks when the system VR mode changes via the
77 * interface given in VrStateListener.
78 * <p/>
79 * Device vendors may choose to receive VR state changes by implementing the VR mode HAL, e.g.:
80 *  hardware/libhardware/modules/vr
81 * <p/>
82 * In general applications may enable or disable VR mode by calling
83 * {@link android.app.Activity#setVrModeEnabled)}.  An application may also implement a service to
84 * be run while in VR mode by implementing {@link android.service.vr.VrListenerService}.
85 *
86 * @see {@link android.service.vr.VrListenerService}
87 * @see {@link com.android.server.vr.VrManagerInternal}
88 * @see {@link com.android.server.vr.VrStateListener}
89 *
90 * @hide
91 */
92public class VrManagerService extends SystemService implements EnabledComponentChangeListener{
93
94    public static final String TAG = "VrManagerService";
95
96    public static final String VR_MANAGER_BINDER_SERVICE = "vrmanager";
97
98    private static final int PENDING_STATE_DELAY_MS = 300;
99    private static final int EVENT_LOG_SIZE = 32;
100    private static final int INVALID_APPOPS_MODE = -1;
101
102    private static native void initializeNative();
103    private static native void setVrModeNative(boolean enabled);
104
105    private final Object mLock = new Object();
106
107    private final IBinder mOverlayToken = new Binder();
108
109    // State protected by mLock
110    private boolean mVrModeEnabled;
111    private EnabledComponentsObserver mComponentObserver;
112    private ManagedApplicationService mCurrentVrService;
113    private Context mContext;
114    private ComponentName mCurrentVrModeComponent;
115    private int mCurrentVrModeUser;
116    private boolean mWasDefaultGranted;
117    private boolean mGuard;
118    private final RemoteCallbackList<IVrStateCallbacks> mRemoteCallbacks =
119            new RemoteCallbackList<>();
120    private int mPreviousCoarseLocationMode = INVALID_APPOPS_MODE;
121    private int mPreviousManageOverlayMode = INVALID_APPOPS_MODE;
122    private VrState mPendingState;
123    private final ArrayDeque<VrState> mLoggingDeque = new ArrayDeque<>(EVENT_LOG_SIZE);
124    private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager();
125
126    private static final int MSG_VR_STATE_CHANGE = 0;
127    private static final int MSG_PENDING_VR_STATE_CHANGE = 1;
128
129    private final Handler mHandler = new Handler() {
130        @Override
131        public void handleMessage(Message msg) {
132            switch(msg.what) {
133                case MSG_VR_STATE_CHANGE : {
134                    boolean state = (msg.arg1 == 1);
135                    int i = mRemoteCallbacks.beginBroadcast();
136                    while (i > 0) {
137                        i--;
138                        try {
139                            mRemoteCallbacks.getBroadcastItem(i).onVrStateChanged(state);
140                        } catch (RemoteException e) {
141                            // Noop
142                        }
143                    }
144                    mRemoteCallbacks.finishBroadcast();
145                } break;
146                case MSG_PENDING_VR_STATE_CHANGE : {
147                    synchronized(mLock) {
148                        VrManagerService.this.consumeAndApplyPendingStateLocked();
149                    }
150                } break;
151                default :
152                    throw new IllegalStateException("Unknown message type: " + msg.what);
153            }
154        }
155    };
156
157    private static class VrState {
158        final boolean enabled;
159        final int userId;
160        final ComponentName targetPackageName;
161        final ComponentName callingPackage;
162        final long timestamp;
163        final boolean defaultPermissionsGranted;
164
165        VrState(boolean enabled, ComponentName targetPackageName, int userId,
166                ComponentName callingPackage) {
167            this.enabled = enabled;
168            this.userId = userId;
169            this.targetPackageName = targetPackageName;
170            this.callingPackage = callingPackage;
171            this.defaultPermissionsGranted = false;
172            this.timestamp = System.currentTimeMillis();
173        }
174
175        VrState(boolean enabled, ComponentName targetPackageName, int userId,
176            ComponentName callingPackage, boolean defaultPermissionsGranted) {
177            this.enabled = enabled;
178            this.userId = userId;
179            this.targetPackageName = targetPackageName;
180            this.callingPackage = callingPackage;
181            this.defaultPermissionsGranted = defaultPermissionsGranted;
182            this.timestamp = System.currentTimeMillis();
183        }
184    }
185
186    private static final BinderChecker sBinderChecker = new BinderChecker() {
187        @Override
188        public IInterface asInterface(IBinder binder) {
189            return IVrListener.Stub.asInterface(binder);
190        }
191
192        @Override
193        public boolean checkType(IInterface service) {
194            return service instanceof IVrListener;
195        }
196    };
197
198    private final class NotificationAccessManager {
199        private final SparseArray<ArraySet<String>> mAllowedPackages = new SparseArray<>();
200
201        public void update(Collection<String> packageNames) {
202            int currentUserId = ActivityManager.getCurrentUser();
203
204            UserHandle currentUserHandle = new UserHandle(currentUserId);
205
206            ArraySet<String> allowed = mAllowedPackages.get(currentUserId);
207            if (allowed == null) {
208                allowed = new ArraySet<>();
209            }
210
211            for (String pkg : allowed) {
212                if (!packageNames.contains(pkg)) {
213                    revokeNotificationListenerAccess(pkg);
214                    revokeNotificationPolicyAccess(pkg);
215                }
216            }
217            for (String pkg : packageNames) {
218                if (!allowed.contains(pkg)) {
219                    grantNotificationPolicyAccess(pkg);
220                    grantNotificationListenerAccess(pkg, currentUserHandle);
221                }
222            }
223
224            allowed.clear();
225            allowed.addAll(packageNames);
226            mAllowedPackages.put(currentUserId, allowed);
227        }
228    }
229
230
231    /**
232     * Called when a user, package, or setting changes that could affect whether or not the
233     * currently bound VrListenerService is changed.
234     */
235    @Override
236    public void onEnabledComponentChanged() {
237        synchronized (mLock) {
238            int currentUser = ActivityManager.getCurrentUser();
239
240            // Update listeners
241            ArraySet<ComponentName> enabledListeners = mComponentObserver.getEnabled(currentUser);
242
243            ArraySet<String> enabledPackages = new ArraySet<>();
244            for (ComponentName n : enabledListeners) {
245                String pkg = n.getPackageName();
246                if (isDefaultAllowed(pkg)) {
247                    enabledPackages.add(n.getPackageName());
248                }
249            }
250            mNotifAccessManager.update(enabledPackages);
251
252            if (mCurrentVrService == null) {
253                return; // No active services
254            }
255
256            // If there is a pending state change, we'd better deal with that first
257            consumeAndApplyPendingStateLocked();
258
259            if (mCurrentVrService == null) {
260                return; // No active services
261            }
262
263            // There is an active service, update it if needed
264            updateCurrentVrServiceLocked(mVrModeEnabled, mCurrentVrService.getComponent(),
265                    mCurrentVrService.getUserId(), null);
266        }
267    }
268
269    private final IVrManager mVrManager = new IVrManager.Stub() {
270
271        @Override
272        public void registerListener(IVrStateCallbacks cb) {
273            enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
274            if (cb == null) {
275                throw new IllegalArgumentException("Callback binder object is null.");
276            }
277
278            VrManagerService.this.addStateCallback(cb);
279        }
280
281        @Override
282        public void unregisterListener(IVrStateCallbacks cb) {
283            enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
284            if (cb == null) {
285                throw new IllegalArgumentException("Callback binder object is null.");
286            }
287
288            VrManagerService.this.removeStateCallback(cb);
289        }
290
291        @Override
292        public boolean getVrModeState() {
293            return VrManagerService.this.getVrMode();
294        }
295
296        @Override
297        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
298            if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
299                    != PackageManager.PERMISSION_GRANTED) {
300                pw.println("permission denied: can't dump VrManagerService from pid="
301                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
302                return;
303            }
304            pw.println("********* Dump of VrManagerService *********");
305            pw.println("Previous state transitions:\n");
306            String tab = "  ";
307            dumpStateTransitions(pw);
308            pw.println("\n\nRemote Callbacks:");
309            int i=mRemoteCallbacks.beginBroadcast(); // create the broadcast item array
310            while(i-->0) {
311                pw.print(tab);
312                pw.print(mRemoteCallbacks.getBroadcastItem(i));
313                if (i>0) pw.println(",");
314            }
315            mRemoteCallbacks.finishBroadcast();
316            pw.println("\n");
317            pw.println("Installed VrListenerService components:");
318            int userId = mCurrentVrModeUser;
319            ArraySet<ComponentName> installed = mComponentObserver.getInstalled(userId);
320            if (installed == null || installed.size() == 0) {
321                pw.println("None");
322            } else {
323                for (ComponentName n : installed) {
324                    pw.print(tab);
325                    pw.println(n.flattenToString());
326                }
327            }
328            pw.println("Enabled VrListenerService components:");
329            ArraySet<ComponentName> enabled = mComponentObserver.getEnabled(userId);
330            if (enabled == null || enabled.size() == 0) {
331                pw.println("None");
332            } else {
333                for (ComponentName n : enabled) {
334                    pw.print(tab);
335                    pw.println(n.flattenToString());
336                }
337            }
338            pw.println("\n");
339            pw.println("********* End of VrManagerService Dump *********");
340        }
341
342    };
343
344    private void enforceCallerPermission(String permission) {
345        if (mContext.checkCallingOrSelfPermission(permission)
346                != PackageManager.PERMISSION_GRANTED) {
347            throw new SecurityException("Caller does not hold the permission " + permission);
348        }
349    }
350
351    /**
352     * Implementation of VrManagerInternal.  Callable only from system services.
353     */
354    private final class LocalService extends VrManagerInternal {
355        @Override
356        public void setVrMode(boolean enabled, ComponentName packageName, int userId,
357                ComponentName callingPackage) {
358            VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage);
359        }
360
361        @Override
362        public boolean isCurrentVrListener(String packageName, int userId) {
363            return VrManagerService.this.isCurrentVrListener(packageName, userId);
364        }
365
366        @Override
367        public int hasVrPackage(ComponentName packageName, int userId) {
368            return VrManagerService.this.hasVrPackage(packageName, userId);
369        }
370    }
371
372    public VrManagerService(Context context) {
373        super(context);
374    }
375
376    @Override
377    public void onStart() {
378        synchronized(mLock) {
379            initializeNative();
380            mContext = getContext();
381        }
382
383        publishLocalService(VrManagerInternal.class, new LocalService());
384        publishBinderService(VR_MANAGER_BINDER_SERVICE, mVrManager.asBinder());
385
386        // If there are no VR packages installed on the device, then disable VR
387        // components, otherwise, enable them.
388        setEnabledStatusOfVrComponents();
389    }
390
391    private void setEnabledStatusOfVrComponents() {
392        ArraySet<ComponentName> vrComponents = SystemConfig.getInstance().getDefaultVrComponents();
393        if (vrComponents == null) {
394           return;
395        }
396
397        // We only want to enable VR components if there is a VR package installed on the device.
398        // The VR components themselves do not quality as a VR package, so exclude them.
399        ArraySet<String> vrComponentPackageNames = new ArraySet<>();
400        for (ComponentName componentName : vrComponents) {
401            vrComponentPackageNames.add(componentName.getPackageName());
402        }
403
404        // Check to see if there are any packages on the device, other than the VR component
405        // packages.
406        PackageManager pm = mContext.getPackageManager();
407        List<PackageInfo> packageInfos = pm.getInstalledPackages(
408                PackageManager.GET_CONFIGURATIONS);
409        boolean vrModeIsUsed = false;
410        for (PackageInfo packageInfo : packageInfos) {
411            if (packageInfo != null && packageInfo.packageName != null &&
412                    pm.getApplicationEnabledSetting(packageInfo.packageName) ==
413                            PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
414                vrModeIsUsed = enableVrComponentsIfVrModeUsed(pm, packageInfo,
415                        vrComponentPackageNames, vrComponents);
416                if (vrModeIsUsed) {
417                    break;
418                }
419            }
420        }
421
422        if (!vrModeIsUsed) {
423            Slog.i(TAG, "No VR packages found, disabling VR components");
424            setVrComponentsEnabledOrDisabled(vrComponents, false);
425
426            // Register to receive an intent when a new package is installed, in case that package
427            // requires VR components.
428            IntentFilter intentFilter = new IntentFilter();
429            intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
430            intentFilter.addDataScheme("package");
431            mContext.registerReceiver(new BroadcastReceiver() {
432                @Override
433                public void onReceive(Context context, Intent intent) {
434                    PackageManager pm = context.getPackageManager();
435                    final String packageName = intent.getData().getSchemeSpecificPart();
436                    if (packageName != null) {
437                        try {
438                            PackageInfo packageInfo = pm.getPackageInfo(packageName,
439                                    PackageManager.GET_CONFIGURATIONS);
440                            enableVrComponentsIfVrModeUsed(pm, packageInfo,
441                                    vrComponentPackageNames, vrComponents);
442                        } catch (NameNotFoundException e) {
443                        }
444                    }
445                };
446            }, intentFilter);
447        }
448    }
449
450    private void setVrComponentsEnabledOrDisabled(ArraySet<ComponentName> vrComponents,
451            boolean enabled) {
452        int state = enabled ?
453                PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
454                PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
455        PackageManager pm = mContext.getPackageManager();
456        for (ComponentName componentName : vrComponents) {
457            try {
458                // Note that we must first check for the existance of the package before trying
459                // to set its enabled state.  This is to prevent PackageManager from throwing
460                // an excepton if the package is not found (not just a NameNotFoundException
461                // exception).
462                PackageInfo packageInfo = pm.getPackageInfo(componentName.getPackageName(),
463                        PackageManager.GET_CONFIGURATIONS);
464                pm.setApplicationEnabledSetting(componentName.getPackageName(), state , 0);
465            } catch (NameNotFoundException e) {
466            }
467        }
468    }
469
470    private boolean enableVrComponentsIfVrModeUsed(PackageManager pm, PackageInfo packageInfo,
471            ArraySet<String> vrComponentPackageNames, ArraySet<ComponentName> vrComponents) {
472        boolean isVrComponent = vrComponents != null &&
473                vrComponentPackageNames.contains(packageInfo.packageName);
474        if (packageInfo != null && packageInfo.reqFeatures != null && !isVrComponent) {
475            for (FeatureInfo featureInfo : packageInfo.reqFeatures) {
476                if (featureInfo.name != null &&
477                    (featureInfo.name.equals(PackageManager.FEATURE_VR_MODE) ||
478                     featureInfo.name.equals(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE))) {
479                    Slog.i(TAG, "VR package found, enabling VR components");
480                    setVrComponentsEnabledOrDisabled(vrComponents, true);
481                    return true;
482                }
483            }
484        }
485        return false;
486    }
487
488    @Override
489    public void onBootPhase(int phase) {
490        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
491            synchronized (mLock) {
492                Looper looper = Looper.getMainLooper();
493                Handler handler = new Handler(looper);
494                ArrayList<EnabledComponentChangeListener> listeners = new ArrayList<>();
495                listeners.add(this);
496                mComponentObserver = EnabledComponentsObserver.build(mContext, handler,
497                        Settings.Secure.ENABLED_VR_LISTENERS, looper,
498                        android.Manifest.permission.BIND_VR_LISTENER_SERVICE,
499                        VrListenerService.SERVICE_INTERFACE, mLock, listeners);
500
501                mComponentObserver.rebuildAll();
502            }
503        }
504    }
505
506    @Override
507    public void onStartUser(int userHandle) {
508        synchronized (mLock) {
509            mComponentObserver.onUsersChanged();
510        }
511    }
512
513    @Override
514    public void onSwitchUser(int userHandle) {
515        synchronized (mLock) {
516            mComponentObserver.onUsersChanged();
517        }
518
519    }
520
521    @Override
522    public void onStopUser(int userHandle) {
523        synchronized (mLock) {
524            mComponentObserver.onUsersChanged();
525        }
526
527    }
528
529    @Override
530    public void onCleanupUser(int userHandle) {
531        synchronized (mLock) {
532            mComponentObserver.onUsersChanged();
533        }
534    }
535
536    private void updateOverlayStateLocked(ComponentName exemptedComponent) {
537        final long identity = Binder.clearCallingIdentity();
538        try {
539            AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
540            if (appOpsManager != null) {
541                String[] exemptions = (exemptedComponent == null) ? new String[0] :
542                        new String[] { exemptedComponent.getPackageName() };
543
544                appOpsManager.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
545                        mVrModeEnabled, mOverlayToken, exemptions);
546            }
547        } finally {
548            Binder.restoreCallingIdentity(identity);
549        }
550    }
551
552    /**
553     * Send VR mode changes (if the mode state has changed), and update the bound/unbound state of
554     * the currently selected VR listener service.  If the component selected for the VR listener
555     * service has changed, unbind the previous listener and bind the new listener (if enabled).
556     * <p/>
557     * Note: Must be called while holding {@code mLock}.
558     *
559     * @param enabled new state for VR mode.
560     * @param component new component to be bound as a VR listener.
561     * @param userId user owning the component to be bound.
562     * @param calling the component currently using VR mode, or null to leave unchanged.
563     *
564     * @return {@code true} if the component/user combination specified is valid.
565     */
566    private boolean updateCurrentVrServiceLocked(boolean enabled, @NonNull ComponentName component,
567            int userId, ComponentName calling) {
568
569        boolean sendUpdatedCaller = false;
570        final long identity = Binder.clearCallingIdentity();
571        try {
572
573            boolean validUserComponent = (mComponentObserver.isValid(component, userId) ==
574                    EnabledComponentsObserver.NO_ERROR);
575            if (!mVrModeEnabled && !enabled) {
576                return validUserComponent; // Disabled -> Disabled transition does nothing.
577            }
578
579            // Always send mode change events.
580            changeVrModeLocked(enabled, (enabled && validUserComponent) ? component : null);
581
582            if (!enabled || !validUserComponent) {
583                // Unbind whatever is running
584                if (mCurrentVrService != null) {
585                    Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + " for user " +
586                            mCurrentVrService.getUserId());
587                    mCurrentVrService.disconnect();
588                    disableImpliedPermissionsLocked(mCurrentVrService.getComponent(),
589                            new UserHandle(mCurrentVrService.getUserId()));
590                    mCurrentVrService = null;
591                }
592            } else {
593                if (mCurrentVrService != null) {
594                    // Unbind any running service that doesn't match the component/user selection
595                    if (mCurrentVrService.disconnectIfNotMatching(component, userId)) {
596                        Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() +
597                                " for user " + mCurrentVrService.getUserId());
598                        disableImpliedPermissionsLocked(mCurrentVrService.getComponent(),
599                                new UserHandle(mCurrentVrService.getUserId()));
600                        createAndConnectService(component, userId);
601                        enableImpliedPermissionsLocked(mCurrentVrService.getComponent(),
602                                new UserHandle(mCurrentVrService.getUserId()));
603                        sendUpdatedCaller = true;
604                    }
605                    // The service with the correct component/user is bound
606                } else {
607                    // Nothing was previously running, bind a new service
608                    createAndConnectService(component, userId);
609                    enableImpliedPermissionsLocked(mCurrentVrService.getComponent(),
610                            new UserHandle(mCurrentVrService.getUserId()));
611                    sendUpdatedCaller = true;
612                }
613            }
614
615            if (calling != null && !Objects.equals(calling, mCurrentVrModeComponent))  {
616                mCurrentVrModeComponent = calling;
617                mCurrentVrModeUser = userId;
618                sendUpdatedCaller = true;
619            }
620
621            if (mCurrentVrService != null && sendUpdatedCaller) {
622                final ComponentName c = mCurrentVrModeComponent;
623                mCurrentVrService.sendEvent(new PendingEvent() {
624                    @Override
625                    public void runEvent(IInterface service) throws RemoteException {
626                        IVrListener l = (IVrListener) service;
627                        l.focusedActivityChanged(c);
628                    }
629                });
630            }
631            logStateLocked();
632
633            return validUserComponent;
634        } finally {
635            Binder.restoreCallingIdentity(identity);
636        }
637    }
638
639    /**
640     * Enable the permission given in {@link #IMPLIED_VR_LISTENER_PERMISSIONS} for the given
641     * component package and user.
642     *
643     * @param component the component whose package should be enabled.
644     * @param userId the user that owns the given component.
645     */
646    private void enableImpliedPermissionsLocked(ComponentName component, UserHandle userId) {
647        if (mGuard) {
648            // Impossible
649            throw new IllegalStateException("Enabling permissions without disabling.");
650        }
651        mGuard = true;
652
653        PackageManager pm = mContext.getPackageManager();
654
655        String pName = component.getPackageName();
656        if (pm == null) {
657            Slog.e(TAG, "Couldn't set implied permissions for " + pName +
658                ", PackageManager isn't running");
659            return;
660        }
661
662        ApplicationInfo info = null;
663        try {
664            info = pm.getApplicationInfo(pName, PackageManager.GET_META_DATA);
665        } catch (NameNotFoundException e) {
666        }
667
668        if (info == null || !(info.isSystemApp() || info.isUpdatedSystemApp())) {
669            return;
670        }
671
672        mWasDefaultGranted = true;
673        AppOpsManager mgr = mContext.getSystemService(AppOpsManager.class);
674        if (mgr == null) {
675            Slog.e(TAG, "No AppOpsManager, failed to set permissions for: " + pName);
676            return;
677        }
678        grantCoarseLocationAccess(mgr, pName, info.uid);
679        grantOverlayAccess(mgr, pName, info.uid);
680    }
681
682    /**
683     * Disable the permission given in {@link #IMPLIED_VR_LISTENER_PERMISSIONS} for the given
684     * component package and user.
685     *
686     * @param component the component whose package should be disabled.
687     * @param userId the user that owns the given component.
688     */
689    private void disableImpliedPermissionsLocked(ComponentName component, UserHandle userId) {
690        if (!mGuard) {
691            // Impossible
692            throw new IllegalStateException("Disabling permissions without enabling.");
693        }
694        mGuard = false;
695
696        PackageManager pm = mContext.getPackageManager();
697
698        if (pm == null) {
699            Slog.e(TAG, "Couldn't remove implied permissions for " + component +
700                ", PackageManager isn't running");
701            return;
702        }
703
704        String pName = component.getPackageName();
705        if (mWasDefaultGranted) {
706            ApplicationInfo info = null;
707            try {
708                info = pm.getApplicationInfo(pName, PackageManager.GET_META_DATA);
709            } catch (NameNotFoundException e) {
710            }
711
712            if (info != null) {
713                AppOpsManager mgr = mContext.getSystemService(AppOpsManager.class);
714                if (mgr == null) {
715                    Slog.e(TAG, "No AppOpsManager, failed to set permissions for: " + pName);
716                    return;
717                }
718                revokeCoarseLocationAccess(mgr, pName, info.uid);
719                revokeOverlayAccess(mgr, pName, info.uid);
720            }
721            mWasDefaultGranted = false;
722        }
723
724    }
725
726    private boolean isDefaultAllowed(String packageName) {
727        PackageManager pm = mContext.getPackageManager();
728
729        ApplicationInfo info = null;
730        try {
731            info = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
732        } catch (NameNotFoundException e) {
733        }
734
735        if (info == null || !(info.isSystemApp() || info.isUpdatedSystemApp())) {
736            return false;
737        }
738        return true;
739    }
740
741    private void grantCoarseLocationAccess(AppOpsManager mgr, String packageName, int uid) {
742        mPreviousCoarseLocationMode = mgr.checkOpNoThrow(AppOpsManager.OP_COARSE_LOCATION, uid,
743                packageName);
744
745        if (mPreviousCoarseLocationMode != AppOpsManager.MODE_ALLOWED) {
746            mgr.setMode(AppOpsManager.OP_COARSE_LOCATION, uid, packageName,
747                    AppOpsManager.MODE_ALLOWED);
748        }
749    }
750
751    private void revokeCoarseLocationAccess(AppOpsManager mgr, String packageName, int uid) {
752        if (mPreviousCoarseLocationMode != AppOpsManager.MODE_ALLOWED) {
753            mgr.setMode(AppOpsManager.OP_COARSE_LOCATION, uid, packageName,
754                    mPreviousCoarseLocationMode);
755            mPreviousCoarseLocationMode = INVALID_APPOPS_MODE;
756        }
757    }
758
759    private void grantOverlayAccess(AppOpsManager mgr, String packageName, int uid) {
760
761        mPreviousManageOverlayMode = mgr.checkOpNoThrow(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid,
762                packageName);
763
764        if (mPreviousManageOverlayMode != AppOpsManager.MODE_ALLOWED) {
765            mgr.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, packageName,
766                    AppOpsManager.MODE_ALLOWED);
767        }
768    }
769
770    private void revokeOverlayAccess(AppOpsManager mgr, String packageName, int uid) {
771        if (mPreviousManageOverlayMode != AppOpsManager.MODE_ALLOWED) {
772            mgr.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, packageName,
773                    mPreviousManageOverlayMode);
774            mPreviousManageOverlayMode = INVALID_APPOPS_MODE;
775        }
776    }
777
778    private void grantNotificationPolicyAccess(String pkg) {
779        NotificationManager nm = mContext.getSystemService(NotificationManager.class);
780        nm.setNotificationPolicyAccessGranted(pkg, true);
781    }
782
783    private void revokeNotificationPolicyAccess(String pkg) {
784        NotificationManager nm = mContext.getSystemService(NotificationManager.class);
785        // Remove any DND zen rules possibly created by the package.
786        nm.removeAutomaticZenRules(pkg);
787        // Remove Notification Policy Access.
788        nm.setNotificationPolicyAccessGranted(pkg, false);
789    }
790
791    private void grantNotificationListenerAccess(String pkg, UserHandle userId) {
792        PackageManager pm = mContext.getPackageManager();
793        ArraySet<ComponentName> possibleServices = EnabledComponentsObserver.loadComponentNames(pm,
794                userId.getIdentifier(), NotificationListenerService.SERVICE_INTERFACE,
795                android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE);
796        ContentResolver resolver = mContext.getContentResolver();
797
798        ArraySet<String> current = getCurrentNotifListeners(resolver);
799
800        for (ComponentName c : possibleServices) {
801            String flatName = c.flattenToString();
802            if (Objects.equals(c.getPackageName(), pkg)
803                    && !current.contains(flatName)) {
804                current.add(flatName);
805            }
806        }
807
808        if (current.size() > 0) {
809            String flatSettings = formatSettings(current);
810            Settings.Secure.putString(resolver, Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
811                    flatSettings);
812        }
813    }
814
815    private void revokeNotificationListenerAccess(String pkg) {
816        ContentResolver resolver = mContext.getContentResolver();
817        ArraySet<String> current = getCurrentNotifListeners(resolver);
818
819        ArrayList<String> toRemove = new ArrayList<>();
820
821        for (String c : current) {
822            ComponentName component = ComponentName.unflattenFromString(c);
823            if (component.getPackageName().equals(pkg)) {
824                toRemove.add(c);
825            }
826        }
827
828        current.removeAll(toRemove);
829
830        String flatSettings = formatSettings(current);
831        Settings.Secure.putString(resolver, Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
832                flatSettings);
833
834    }
835
836    private ArraySet<String> getCurrentNotifListeners(ContentResolver resolver) {
837        String flat = Settings.Secure.getString(resolver,
838                Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
839
840        ArraySet<String> current = new ArraySet<>();
841        if (flat != null) {
842            String[] allowed = flat.split(":");
843            for (String s : allowed) {
844                current.add(s);
845            }
846        }
847        return current;
848    }
849
850    private static String formatSettings(Collection<String> c) {
851        if (c == null || c.isEmpty()) {
852            return "";
853        }
854
855        StringBuilder b = new StringBuilder();
856        boolean start = true;
857        for (String s : c) {
858            if ("".equals(s)) {
859                continue;
860            }
861            if (!start) {
862                b.append(':');
863            }
864            b.append(s);
865            start = false;
866        }
867        return b.toString();
868    }
869
870
871
872    private void createAndConnectService(@NonNull ComponentName component, int userId) {
873        mCurrentVrService = VrManagerService.create(mContext, component, userId);
874        mCurrentVrService.connect();
875        Slog.i(TAG, "Connecting " + component + " for user " + userId);
876    }
877
878    /**
879     * Send VR mode change callbacks to HAL and system services if mode has actually changed.
880     * <p/>
881     * Note: Must be called while holding {@code mLock}.
882     *
883     * @param enabled new state of the VR mode.
884     * @param exemptedComponent a component to exempt from AppOps restrictions for overlays.
885     */
886    private void changeVrModeLocked(boolean enabled, ComponentName exemptedComponent) {
887        if (mVrModeEnabled != enabled) {
888            mVrModeEnabled = enabled;
889
890            // Log mode change event.
891            Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled"));
892            setVrModeNative(mVrModeEnabled);
893
894            updateOverlayStateLocked(exemptedComponent);
895            onVrModeChangedLocked();
896        }
897    }
898
899    /**
900     * Notify system services of VR mode change.
901     * <p/>
902     * Note: Must be called while holding {@code mLock}.
903     */
904    private void onVrModeChangedLocked() {
905        mHandler.sendMessage(mHandler.obtainMessage(MSG_VR_STATE_CHANGE,
906                (mVrModeEnabled) ? 1 : 0, 0));
907    }
908
909    /**
910     * Helper function for making ManagedApplicationService instances.
911     */
912    private static ManagedApplicationService create(@NonNull Context context,
913            @NonNull ComponentName component, int userId) {
914        return ManagedApplicationService.build(context, component, userId,
915                R.string.vr_listener_binding_label, Settings.ACTION_VR_LISTENER_SETTINGS,
916                sBinderChecker);
917    }
918
919    private void consumeAndApplyPendingStateLocked() {
920        if (mPendingState != null) {
921            updateCurrentVrServiceLocked(mPendingState.enabled,
922                    mPendingState.targetPackageName, mPendingState.userId,
923                    mPendingState.callingPackage);
924            mPendingState = null;
925        }
926    }
927
928    private void logStateLocked() {
929        ComponentName currentBoundService = (mCurrentVrService == null) ? null :
930            mCurrentVrService.getComponent();
931        VrState current = new VrState(mVrModeEnabled, currentBoundService, mCurrentVrModeUser,
932            mCurrentVrModeComponent, mWasDefaultGranted);
933        if (mLoggingDeque.size() == EVENT_LOG_SIZE) {
934            mLoggingDeque.removeFirst();
935        }
936        mLoggingDeque.add(current);
937    }
938
939    private void dumpStateTransitions(PrintWriter pw) {
940        SimpleDateFormat d = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
941        String tab = "  ";
942        if (mLoggingDeque.size() == 0) {
943            pw.print(tab);
944            pw.println("None");
945        }
946        for (VrState state : mLoggingDeque) {
947            pw.print(d.format(new Date(state.timestamp)));
948            pw.print(tab);
949            pw.print("State changed to:");
950            pw.print(tab);
951            pw.println((state.enabled) ? "ENABLED" : "DISABLED");
952            if (state.enabled) {
953                pw.print(tab);
954                pw.print("User=");
955                pw.println(state.userId);
956                pw.print(tab);
957                pw.print("Current VR Activity=");
958                pw.println((state.callingPackage == null) ?
959                    "None" : state.callingPackage.flattenToString());
960                pw.print(tab);
961                pw.print("Bound VrListenerService=");
962                pw.println((state.targetPackageName == null) ?
963                    "None" : state.targetPackageName.flattenToString());
964                if (state.defaultPermissionsGranted) {
965                    pw.print(tab);
966                    pw.println("Default permissions granted to the bound VrListenerService.");
967                }
968            }
969        }
970    }
971
972    /*
973     * Implementation of VrManagerInternal calls.  These are callable from system services.
974     */
975
976    private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName,
977            int userId, @NonNull ComponentName callingPackage) {
978
979        synchronized (mLock) {
980
981            if (!enabled && mCurrentVrService != null) {
982                // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls
983                // and service bind/unbind in case we are immediately switching to another VR app.
984                if (mPendingState == null) {
985                    mHandler.sendEmptyMessageDelayed(MSG_PENDING_VR_STATE_CHANGE,
986                            PENDING_STATE_DELAY_MS);
987                }
988
989                mPendingState = new VrState(enabled, targetPackageName, userId, callingPackage);
990                return;
991            } else {
992                mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE);
993                mPendingState = null;
994            }
995
996            updateCurrentVrServiceLocked(enabled, targetPackageName, userId, callingPackage);
997        }
998    }
999
1000    private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) {
1001        synchronized (mLock) {
1002            return mComponentObserver.isValid(targetPackageName, userId);
1003        }
1004    }
1005
1006    private boolean isCurrentVrListener(String packageName, int userId) {
1007        synchronized (mLock) {
1008            if (mCurrentVrService == null) {
1009                return false;
1010            }
1011            return mCurrentVrService.getComponent().getPackageName().equals(packageName) &&
1012                    userId == mCurrentVrService.getUserId();
1013        }
1014    }
1015
1016    /*
1017     * Implementation of IVrManager calls.
1018     */
1019
1020    private void addStateCallback(IVrStateCallbacks cb) {
1021        mRemoteCallbacks.register(cb);
1022    }
1023
1024    private void removeStateCallback(IVrStateCallbacks cb) {
1025        mRemoteCallbacks.unregister(cb);
1026    }
1027
1028    private boolean getVrMode() {
1029        synchronized (mLock) {
1030            return mVrModeEnabled;
1031        }
1032    }
1033}
1034