VrManagerService.java revision dc34df5d310245a268ee9ea3872a612c6f7950b5
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.AppOpsManager;
20import android.app.NotificationManager;
21import android.annotation.NonNull;
22import android.content.ComponentName;
23import android.content.ContentResolver;
24import android.content.Context;
25import android.content.pm.ApplicationInfo;
26import android.content.pm.PackageManager;
27import android.content.pm.PackageManager.NameNotFoundException;
28import android.os.Binder;
29import android.os.Handler;
30import android.os.IBinder;
31import android.os.IInterface;
32import android.os.Looper;
33import android.os.Message;
34import android.os.RemoteCallbackList;
35import android.os.RemoteException;
36import android.os.UserHandle;
37import android.provider.Settings;
38import android.service.notification.NotificationListenerService;
39import android.service.vr.IVrListener;
40import android.service.vr.IVrManager;
41import android.service.vr.IVrStateCallbacks;
42import android.service.vr.VrListenerService;
43import android.util.ArraySet;
44import android.util.Slog;
45
46import com.android.internal.R;
47import com.android.server.SystemService;
48import com.android.server.utils.ManagedApplicationService.PendingEvent;
49import com.android.server.vr.EnabledComponentsObserver.EnabledComponentChangeListener;
50import com.android.server.utils.ManagedApplicationService;
51import com.android.server.utils.ManagedApplicationService.BinderChecker;
52
53import java.io.FileDescriptor;
54import java.io.PrintWriter;
55import java.lang.StringBuilder;
56import java.lang.ref.WeakReference;
57import java.util.ArrayList;
58import java.util.Collection;
59import java.util.Objects;
60import java.util.Set;
61
62/**
63 * Service tracking whether VR mode is active, and notifying listening services of state changes.
64 * <p/>
65 * Services running in system server may modify the state of VrManagerService via the interface in
66 * VrManagerInternal, and may register to receive callbacks when the system VR mode changes via the
67 * interface given in VrStateListener.
68 * <p/>
69 * Device vendors may choose to receive VR state changes by implementing the VR mode HAL, e.g.:
70 *  hardware/libhardware/modules/vr
71 * <p/>
72 * In general applications may enable or disable VR mode by calling
73 * {@link android.app.Activity#setVrModeEnabled)}.  An application may also implement a service to
74 * be run while in VR mode by implementing {@link android.service.vr.VrListenerService}.
75 *
76 * @see {@link android.service.vr.VrListenerService}
77 * @see {@link com.android.server.vr.VrManagerInternal}
78 * @see {@link com.android.server.vr.VrStateListener}
79 *
80 * @hide
81 */
82public class VrManagerService extends SystemService implements EnabledComponentChangeListener{
83
84    public static final String TAG = "VrManagerService";
85
86    public static final String VR_MANAGER_BINDER_SERVICE = "vrmanager";
87
88    private static native void initializeNative();
89    private static native void setVrModeNative(boolean enabled);
90
91    private final Object mLock = new Object();
92
93    private final IBinder mOverlayToken = new Binder();
94
95    // State protected by mLock
96    private boolean mVrModeEnabled;
97    private EnabledComponentsObserver mComponentObserver;
98    private ManagedApplicationService mCurrentVrService;
99    private Context mContext;
100    private ComponentName mCurrentVrModeComponent;
101    private int mCurrentVrModeUser;
102    private boolean mWasDefaultGranted;
103    private boolean mGuard;
104    private final RemoteCallbackList<IVrStateCallbacks> mRemoteCallbacks =
105            new RemoteCallbackList<>();
106    private final ArraySet<String> mPreviousToggledListenerSettings = new ArraySet<>();
107    private String mPreviousNotificationPolicyAccessPackage;
108    private String mPreviousManageOverlayPackage;
109
110    private static final int MSG_VR_STATE_CHANGE = 0;
111
112    private final Handler mHandler = new Handler() {
113        @Override
114        public void handleMessage(Message msg) {
115            switch(msg.what) {
116                case MSG_VR_STATE_CHANGE : {
117                    boolean state = (msg.arg1 == 1);
118                    int i = mRemoteCallbacks.beginBroadcast();
119                    while (i > 0) {
120                        i--;
121                        try {
122                            mRemoteCallbacks.getBroadcastItem(i).onVrStateChanged(state);
123                        } catch (RemoteException e) {
124                            // Noop
125                        }
126                    }
127                    mRemoteCallbacks.finishBroadcast();
128                } break;
129                default :
130                    throw new IllegalStateException("Unknown message type: " + msg.what);
131            }
132        }
133    };
134
135    private static final BinderChecker sBinderChecker = new BinderChecker() {
136        @Override
137        public IInterface asInterface(IBinder binder) {
138            return IVrListener.Stub.asInterface(binder);
139        }
140
141        @Override
142        public boolean checkType(IInterface service) {
143            return service instanceof IVrListener;
144        }
145    };
146
147    /**
148     * Called when a user, package, or setting changes that could affect whether or not the
149     * currently bound VrListenerService is changed.
150     */
151    @Override
152    public void onEnabledComponentChanged() {
153        synchronized (mLock) {
154            if (mCurrentVrService == null) {
155                return; // No active services
156            }
157
158            // There is an active service, update it if needed
159            updateCurrentVrServiceLocked(mVrModeEnabled, mCurrentVrService.getComponent(),
160                    mCurrentVrService.getUserId(), null);
161        }
162    }
163
164    private final IVrManager mVrManager = new IVrManager.Stub() {
165
166        @Override
167        public void registerListener(IVrStateCallbacks cb) {
168            enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
169            if (cb == null) {
170                throw new IllegalArgumentException("Callback binder object is null.");
171            }
172
173            VrManagerService.this.addStateCallback(cb);
174        }
175
176        @Override
177        public void unregisterListener(IVrStateCallbacks cb) {
178            enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
179            if (cb == null) {
180                throw new IllegalArgumentException("Callback binder object is null.");
181            }
182
183            VrManagerService.this.removeStateCallback(cb);
184        }
185
186        @Override
187        public boolean getVrModeState() {
188            return VrManagerService.this.getVrMode();
189        }
190
191        @Override
192        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
193            if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
194                    != PackageManager.PERMISSION_GRANTED) {
195                pw.println("permission denied: can't dump VrManagerService from pid="
196                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
197                return;
198            }
199            pw.print("mVrModeEnabled=");
200            pw.println(mVrModeEnabled);
201            pw.print("mCurrentVrModeUser=");
202            pw.println(mCurrentVrModeUser);
203            pw.print("mRemoteCallbacks=");
204            int i=mRemoteCallbacks.beginBroadcast(); // create the broadcast item array
205            while(i-->0) {
206                pw.print(mRemoteCallbacks.getBroadcastItem(i));
207                if (i>0) pw.print(", ");
208            }
209            mRemoteCallbacks.finishBroadcast();
210            pw.println();
211            pw.print("mCurrentVrService=");
212            pw.println(mCurrentVrService != null ? mCurrentVrService.getComponent() : "(none)");
213            pw.print("mCurrentVrModeComponent=");
214            pw.println(mCurrentVrModeComponent);
215        }
216
217    };
218
219    private void enforceCallerPermission(String permission) {
220        if (mContext.checkCallingOrSelfPermission(permission)
221                != PackageManager.PERMISSION_GRANTED) {
222            throw new SecurityException("Caller does not hold the permission " + permission);
223        }
224    }
225
226    /**
227     * Implementation of VrManagerInternal.  Callable only from system services.
228     */
229    private final class LocalService extends VrManagerInternal {
230        @Override
231        public void setVrMode(boolean enabled, ComponentName packageName, int userId,
232                ComponentName callingPackage) {
233            VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage);
234        }
235
236        @Override
237        public boolean isCurrentVrListener(String packageName, int userId) {
238            return VrManagerService.this.isCurrentVrListener(packageName, userId);
239        }
240
241        @Override
242        public int hasVrPackage(ComponentName packageName, int userId) {
243            return VrManagerService.this.hasVrPackage(packageName, userId);
244        }
245    }
246
247    public VrManagerService(Context context) {
248        super(context);
249    }
250
251    @Override
252    public void onStart() {
253        synchronized(mLock) {
254            initializeNative();
255            mContext = getContext();
256        }
257
258        publishLocalService(VrManagerInternal.class, new LocalService());
259        publishBinderService(VR_MANAGER_BINDER_SERVICE, mVrManager.asBinder());
260    }
261
262    @Override
263    public void onBootPhase(int phase) {
264        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
265            synchronized (mLock) {
266                Looper looper = Looper.getMainLooper();
267                Handler handler = new Handler(looper);
268                ArrayList<EnabledComponentChangeListener> listeners = new ArrayList<>();
269                listeners.add(this);
270                mComponentObserver = EnabledComponentsObserver.build(mContext, handler,
271                        Settings.Secure.ENABLED_VR_LISTENERS, looper,
272                        android.Manifest.permission.BIND_VR_LISTENER_SERVICE,
273                        VrListenerService.SERVICE_INTERFACE, mLock, listeners);
274
275                mComponentObserver.rebuildAll();
276            }
277        }
278    }
279
280    @Override
281    public void onStartUser(int userHandle) {
282        synchronized (mLock) {
283            mComponentObserver.onUsersChanged();
284        }
285    }
286
287    @Override
288    public void onSwitchUser(int userHandle) {
289        synchronized (mLock) {
290            mComponentObserver.onUsersChanged();
291        }
292
293    }
294
295    @Override
296    public void onStopUser(int userHandle) {
297        synchronized (mLock) {
298            mComponentObserver.onUsersChanged();
299        }
300
301    }
302
303    @Override
304    public void onCleanupUser(int userHandle) {
305        synchronized (mLock) {
306            mComponentObserver.onUsersChanged();
307        }
308    }
309
310    private void updateOverlayStateLocked(ComponentName exemptedComponent) {
311        final long identity = Binder.clearCallingIdentity();
312        try {
313            AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
314            if (appOpsManager != null) {
315                String[] exemptions = (exemptedComponent == null) ? new String[0] :
316                        new String[] { exemptedComponent.getPackageName() };
317
318                appOpsManager.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
319                        mVrModeEnabled, mOverlayToken, exemptions);
320            }
321        } finally {
322            Binder.restoreCallingIdentity(identity);
323        }
324    }
325
326    /**
327     * Send VR mode changes (if the mode state has changed), and update the bound/unbound state of
328     * the currently selected VR listener service.  If the component selected for the VR listener
329     * service has changed, unbind the previous listener and bind the new listener (if enabled).
330     * <p/>
331     * Note: Must be called while holding {@code mLock}.
332     *
333     * @param enabled new state for VR mode.
334     * @param component new component to be bound as a VR listener.
335     * @param userId user owning the component to be bound.
336     * @param calling the component currently using VR mode, or null to leave unchanged.
337     *
338     * @return {@code true} if the component/user combination specified is valid.
339     */
340    private boolean updateCurrentVrServiceLocked(boolean enabled, @NonNull ComponentName component,
341            int userId, ComponentName calling) {
342
343        boolean sendUpdatedCaller = false;
344        final long identity = Binder.clearCallingIdentity();
345        try {
346
347            boolean validUserComponent = (mComponentObserver.isValid(component, userId) ==
348                    EnabledComponentsObserver.NO_ERROR);
349
350            // Always send mode change events.
351            changeVrModeLocked(enabled, (enabled && validUserComponent) ? component : null);
352
353            if (!enabled || !validUserComponent) {
354                // Unbind whatever is running
355                if (mCurrentVrService != null) {
356                    Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + " for user " +
357                            mCurrentVrService.getUserId());
358                    mCurrentVrService.disconnect();
359                    disableImpliedPermissionsLocked(mCurrentVrService.getComponent(),
360                            new UserHandle(mCurrentVrService.getUserId()));
361                    mCurrentVrService = null;
362                }
363            } else {
364                if (mCurrentVrService != null) {
365                    // Unbind any running service that doesn't match the component/user selection
366                    if (mCurrentVrService.disconnectIfNotMatching(component, userId)) {
367                        Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() +
368                                " for user " + mCurrentVrService.getUserId());
369                        disableImpliedPermissionsLocked(mCurrentVrService.getComponent(),
370                                new UserHandle(mCurrentVrService.getUserId()));
371                        createAndConnectService(component, userId);
372                        enableImpliedPermissionsLocked(mCurrentVrService.getComponent(),
373                                new UserHandle(mCurrentVrService.getUserId()));
374                        sendUpdatedCaller = true;
375                    }
376                    // The service with the correct component/user is bound
377                } else {
378                    // Nothing was previously running, bind a new service
379                    createAndConnectService(component, userId);
380                    enableImpliedPermissionsLocked(mCurrentVrService.getComponent(),
381                            new UserHandle(mCurrentVrService.getUserId()));
382                    sendUpdatedCaller = true;
383                }
384            }
385
386            if (calling != null && !Objects.equals(calling, mCurrentVrModeComponent))  {
387                mCurrentVrModeComponent = calling;
388                mCurrentVrModeUser = userId;
389                sendUpdatedCaller = true;
390            }
391
392            if (mCurrentVrService != null && sendUpdatedCaller) {
393                final ComponentName c = mCurrentVrModeComponent;
394                mCurrentVrService.sendEvent(new PendingEvent() {
395                    @Override
396                    public void runEvent(IInterface service) throws RemoteException {
397                        IVrListener l = (IVrListener) service;
398                        l.focusedActivityChanged(c);
399                    }
400                });
401            }
402
403            return validUserComponent;
404        } finally {
405            Binder.restoreCallingIdentity(identity);
406        }
407    }
408
409    /**
410     * Enable the permission given in {@link #IMPLIED_VR_LISTENER_PERMISSIONS} for the given
411     * component package and user.
412     *
413     * @param component the component whose package should be enabled.
414     * @param userId the user that owns the given component.
415     */
416    private void enableImpliedPermissionsLocked(ComponentName component, UserHandle userId) {
417        if (mGuard) {
418            // Impossible
419            throw new IllegalStateException("Enabling permissions without disabling.");
420        }
421        mGuard = true;
422
423        PackageManager pm = mContext.getPackageManager();
424
425        String pName = component.getPackageName();
426        if (pm == null) {
427            Slog.e(TAG, "Couldn't set implied permissions for " + pName +
428                ", PackageManager isn't running");
429            return;
430        }
431
432        ApplicationInfo info = null;
433        try {
434            info = pm.getApplicationInfo(pName, PackageManager.GET_META_DATA);
435        } catch (NameNotFoundException e) {
436        }
437
438        if (info == null) {
439            Slog.e(TAG, "Couldn't set implied permissions for " + pName + ", no such package.");
440            return;
441        }
442
443        if (!(info.isSystemApp() || info.isUpdatedSystemApp())) {
444            return; // Application is not pre-installed, avoid setting implied permissions
445        }
446
447        mWasDefaultGranted = true;
448
449        grantOverlayAccess(pName, userId);
450        grantNotificationPolicyAccess(pName);
451        grantNotificationListenerAccess(pName, userId);
452    }
453
454    /**
455     * Disable the permission given in {@link #IMPLIED_VR_LISTENER_PERMISSIONS} for the given
456     * component package and user.
457     *
458     * @param component the component whose package should be disabled.
459     * @param userId the user that owns the given component.
460     */
461    private void disableImpliedPermissionsLocked(ComponentName component, UserHandle userId) {
462        if (!mGuard) {
463            // Impossible
464            throw new IllegalStateException("Disabling permissions without enabling.");
465        }
466        mGuard = false;
467
468        PackageManager pm = mContext.getPackageManager();
469
470        if (pm == null) {
471            Slog.e(TAG, "Couldn't remove implied permissions for " + component +
472                ", PackageManager isn't running");
473            return;
474        }
475
476        String pName = component.getPackageName();
477        if (mWasDefaultGranted) {
478            revokeOverlayAccess(userId);
479            revokeNotificationPolicyAccess(pName);
480            revokeNotificiationListenerAccess();
481            mWasDefaultGranted = false;
482        }
483
484    }
485
486    private void grantOverlayAccess(String pkg, UserHandle userId) {
487        PackageManager pm = mContext.getPackageManager();
488        boolean prev = (PackageManager.PERMISSION_GRANTED ==
489                pm.checkPermission(android.Manifest.permission.SYSTEM_ALERT_WINDOW, pkg));
490        mPreviousManageOverlayPackage = null;
491        if (!prev) {
492            pm.grantRuntimePermission(pkg, android.Manifest.permission.SYSTEM_ALERT_WINDOW,
493                    userId);
494            mPreviousManageOverlayPackage = pkg;
495        }
496    }
497
498    private void revokeOverlayAccess(UserHandle userId) {
499        PackageManager pm = mContext.getPackageManager();
500        if (mPreviousManageOverlayPackage != null) {
501            pm.revokeRuntimePermission(mPreviousManageOverlayPackage,
502                    android.Manifest.permission.SYSTEM_ALERT_WINDOW, userId);
503            mPreviousManageOverlayPackage = null;
504        }
505    }
506
507
508    private void grantNotificationPolicyAccess(String pkg) {
509        NotificationManager nm = mContext.getSystemService(NotificationManager.class);
510        boolean prev = nm.isNotificationPolicyAccessGrantedForPackage(pkg);
511        mPreviousNotificationPolicyAccessPackage = null;
512        if (!prev) {
513            mPreviousNotificationPolicyAccessPackage = pkg;
514            nm.setNotificationPolicyAccessGranted(pkg, true);
515        }
516    }
517
518    private void revokeNotificationPolicyAccess(String pkg) {
519        NotificationManager nm = mContext.getSystemService(NotificationManager.class);
520        if (mPreviousNotificationPolicyAccessPackage != null) {
521            if (mPreviousNotificationPolicyAccessPackage.equals(pkg)) {
522                // Remove any DND zen rules possibly created by the package.
523                nm.removeAutomaticZenRules(mPreviousNotificationPolicyAccessPackage);
524                // Remove Notification Policy Access.
525                nm.setNotificationPolicyAccessGranted(mPreviousNotificationPolicyAccessPackage, false);
526                mPreviousNotificationPolicyAccessPackage = null;
527            } else {
528                Slog.e(TAG, "Couldn't remove Notification Policy Access for package: " + pkg);
529            }
530        }
531    }
532
533    private void grantNotificationListenerAccess(String pkg, UserHandle userId) {
534        PackageManager pm = mContext.getPackageManager();
535        ArraySet<ComponentName> possibleServices = EnabledComponentsObserver.loadComponentNames(pm,
536                userId.getIdentifier(), NotificationListenerService.SERVICE_INTERFACE,
537                android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE);
538        ContentResolver resolver = mContext.getContentResolver();
539
540        ArraySet<String> current = getCurrentNotifListeners(resolver);
541
542        mPreviousToggledListenerSettings.clear();
543
544        for (ComponentName c : possibleServices) {
545            String flatName = c.flattenToString();
546            if (Objects.equals(c.getPackageName(), pkg)
547                    && !current.contains(flatName)) {
548                mPreviousToggledListenerSettings.add(flatName);
549                current.add(flatName);
550            }
551        }
552
553        if (current.size() > 0) {
554            String flatSettings = formatSettings(current);
555            Settings.Secure.putString(resolver, Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
556                    flatSettings);
557        }
558    }
559
560    private void revokeNotificiationListenerAccess() {
561        if (mPreviousToggledListenerSettings.isEmpty()) {
562            return;
563        }
564
565        ContentResolver resolver = mContext.getContentResolver();
566        ArraySet<String> current = getCurrentNotifListeners(resolver);
567
568        current.removeAll(mPreviousToggledListenerSettings);
569        mPreviousToggledListenerSettings.clear();
570
571        String flatSettings = formatSettings(current);
572        Settings.Secure.putString(resolver, Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
573                flatSettings);
574    }
575
576    private ArraySet<String> getCurrentNotifListeners(ContentResolver resolver) {
577        String flat = Settings.Secure.getString(resolver,
578                Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
579
580        ArraySet<String> current = new ArraySet<>();
581        if (flat != null) {
582            String[] allowed = flat.split(":");
583            for (String s : allowed) {
584                current.add(s);
585            }
586        }
587        return current;
588    }
589
590    private static String formatSettings(Collection<String> c) {
591        if (c == null || c.isEmpty()) {
592            return "";
593        }
594
595        StringBuilder b = new StringBuilder();
596        boolean start = true;
597        for (String s : c) {
598            if ("".equals(s)) {
599                continue;
600            }
601            if (!start) {
602                b.append(':');
603            }
604            b.append(s);
605            start = false;
606        }
607        return b.toString();
608    }
609
610
611
612    private void createAndConnectService(@NonNull ComponentName component, int userId) {
613        mCurrentVrService = VrManagerService.create(mContext, component, userId);
614        mCurrentVrService.connect();
615        Slog.i(TAG, "Connecting " + component + " for user " + userId);
616    }
617
618    /**
619     * Send VR mode change callbacks to HAL and system services if mode has actually changed.
620     * <p/>
621     * Note: Must be called while holding {@code mLock}.
622     *
623     * @param enabled new state of the VR mode.
624     * @param exemptedComponent a component to exempt from AppOps restrictions for overlays.
625     */
626    private void changeVrModeLocked(boolean enabled, ComponentName exemptedComponent) {
627        if (mVrModeEnabled != enabled) {
628            mVrModeEnabled = enabled;
629
630            // Log mode change event.
631            Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled"));
632            setVrModeNative(mVrModeEnabled);
633
634            updateOverlayStateLocked(exemptedComponent);
635            onVrModeChangedLocked();
636        }
637    }
638
639    /**
640     * Notify system services of VR mode change.
641     * <p/>
642     * Note: Must be called while holding {@code mLock}.
643     */
644    private void onVrModeChangedLocked() {
645        mHandler.sendMessage(mHandler.obtainMessage(MSG_VR_STATE_CHANGE,
646                (mVrModeEnabled) ? 1 : 0, 0));
647    }
648
649    /**
650     * Helper function for making ManagedApplicationService instances.
651     */
652    private static ManagedApplicationService create(@NonNull Context context,
653            @NonNull ComponentName component, int userId) {
654        return ManagedApplicationService.build(context, component, userId,
655                R.string.vr_listener_binding_label, Settings.ACTION_VR_LISTENER_SETTINGS,
656                sBinderChecker);
657    }
658
659    /*
660     * Implementation of VrManagerInternal calls.  These are callable from system services.
661     */
662
663    private boolean setVrMode(boolean enabled, @NonNull ComponentName targetPackageName,
664            int userId, @NonNull ComponentName callingPackage) {
665        synchronized (mLock) {
666            return updateCurrentVrServiceLocked(enabled, targetPackageName, userId, callingPackage);
667        }
668    }
669
670    private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) {
671        synchronized (mLock) {
672            return mComponentObserver.isValid(targetPackageName, userId);
673        }
674    }
675
676    private boolean isCurrentVrListener(String packageName, int userId) {
677        synchronized (mLock) {
678            if (mCurrentVrService == null) {
679                return false;
680            }
681            return mCurrentVrService.getComponent().getPackageName().equals(packageName) &&
682                    userId == mCurrentVrService.getUserId();
683        }
684    }
685
686    /*
687     * Implementation of IVrManager calls.
688     */
689
690    private void addStateCallback(IVrStateCallbacks cb) {
691        mRemoteCallbacks.register(cb);
692    }
693
694    private void removeStateCallback(IVrStateCallbacks cb) {
695        mRemoteCallbacks.unregister(cb);
696    }
697
698    private boolean getVrMode() {
699        synchronized (mLock) {
700            return mVrModeEnabled;
701        }
702    }
703}
704