Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 49ef0ee2 authored by Santos Cordon's avatar Santos Cordon Committed by android-build-merger
Browse files

Merge "Allow VR State Listeners with RESTRICTED_VR_ACCESS permission." into oc-mr1-dev

am: 0405d12a

Change-Id: I8a9c7b921489d12f8b9822d4d2b3b53d17368802
parents 59fabad0 0405d12a
Loading
Loading
Loading
Loading
+111 −2
Original line number Diff line number Diff line
package android.app;


import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.ComponentName;
import android.content.Context;
import android.os.Handler;
import android.os.RemoteException;
import android.service.vr.IPersistentVrStateCallbacks;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
import android.util.ArrayMap;

import java.util.Map;

/**
 * Used to control aspects of a devices Virtual Reality (VR) capabilities.
@@ -16,7 +21,33 @@ import android.service.vr.IVrManager;
@SystemApi
@SystemService(Context.VR_SERVICE)
public class VrManager {

    private static class CallbackEntry {
        final IVrStateCallbacks mStateCallback = new IVrStateCallbacks.Stub() {
            @Override
            public void onVrStateChanged(boolean enabled) {
                mHandler.post(() -> mCallback.onVrStateChanged(enabled));
            }

        };
        final IPersistentVrStateCallbacks mPersistentStateCallback =
                new IPersistentVrStateCallbacks.Stub() {
            @Override
            public void onPersistentVrStateChanged(boolean enabled) {
                mHandler.post(() -> mCallback.onPersistentVrStateChanged(enabled));
            }
        };
        final VrStateCallback mCallback;
        final Handler mHandler;

        CallbackEntry(VrStateCallback callback, Handler handler) {
            mCallback = callback;
            mHandler = handler;
        }
    }

    private final IVrManager mService;
    private Map<VrStateCallback, CallbackEntry> mCallbackMap = new ArrayMap<>();

    /**
     * {@hide}
@@ -25,6 +56,84 @@ public class VrManager {
        mService = service;
    }

    /**
     * Registers a callback to be notified of changes to the VR Mode state.
     *
     * @param callback The callback to register.
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
    public void registerVrStateCallback(VrStateCallback callback, @NonNull Handler handler) {
        if (callback == null || mCallbackMap.containsKey(callback)) {
            return;
        }

        CallbackEntry entry = new CallbackEntry(callback, handler);
        mCallbackMap.put(callback, entry);
        try {
            mService.registerListener(entry.mStateCallback);
            mService.registerPersistentVrStateListener(entry.mPersistentStateCallback);
        } catch (RemoteException e) {
            try {
                unregisterVrStateCallback(callback);
            } catch (Exception ignore) {
                e.rethrowFromSystemServer();
            }
        }
    }

    /**
     * Deregisters VR State callbacks.
     *
     * @param callback The callback to deregister.
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
    public void unregisterVrStateCallback(VrStateCallback callback) {
        CallbackEntry entry = mCallbackMap.remove(callback);
        if (entry != null) {
            try {
                mService.unregisterListener(entry.mStateCallback);
            } catch (RemoteException ignore) {
                // Dont rethrow exceptions from requests to unregister.
            }

            try {
                mService.unregisterPersistentVrStateListener(entry.mPersistentStateCallback);
            } catch (RemoteException ignore) {
                // Dont rethrow exceptions from requests to unregister.
            }
        }
    }

    /**
     * Returns the current VrMode state.
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.ACCESS_VR_STATE)
    public boolean getVrModeEnabled() {
        try {
            return mService.getVrModeState();
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        return false;
    }

    /**
     * Returns the current VrMode state.
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.ACCESS_VR_STATE)
    public boolean getPersistentVrModeEnabled() {
        try {
            return mService.getPersistentVrModeEnabled();
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        return false;
    }

    /**
     * Sets the persistent VR mode state of a device. When a device is in persistent VR mode it will
     * remain in VR mode even if the foreground does not specify Vr mode being enabled. Mainly used
+38 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.app;

/**
 * Listens to VR Mode state changes. Use with methods in {@link VrManager}.
 *
 * @hide
 */
public abstract class VrStateCallback {

    /**
     * Callback triggered when there is a change to Persistent VR State.
     *
     * @param enabled True when VR State is in persistent mode, false otherwise.
     */
    public void onPersistentVrStateChanged(boolean enabled) {}

    /**
     * Callback triggered when there is a change to Vr State.
     *
     * @param enabled True when VR State is in VR mode, false otherwise.
     */
    public void onVrStateChanged(boolean enabled) {}
}
+7 −0
Original line number Diff line number Diff line
@@ -58,6 +58,13 @@ interface IVrManager {
     */
    boolean getVrModeState();

    /**
     * Returns the current Persistent VR mode state.
     *
     * @return {@code true} if Persistent VR mode is enabled.
     */
    boolean getPersistentVrModeEnabled();

    /**
     * Sets the persistent VR mode state of a device. When a device is in persistent VR mode it will
     * remain in VR mode even if the foreground does not specify VR mode being enabled. Mainly used
+5 −0
Original line number Diff line number Diff line
@@ -3512,6 +3512,11 @@
    <permission android:name="android.permission.ACCESS_VR_MANAGER"
            android:protectionLevel="signature" />

    <!-- Required to access VR-Mode state and state change events via {android.app.VrStateCallback}
         @hide -->
    <permission android:name="android.permission.ACCESS_VR_STATE"
        android:protectionLevel="signature|preinstalled" />

    <!-- Allows an application to whitelist tasks during lock task mode
         @hide <p>Not for use by third-party applications.</p> -->
    <permission android:name="android.permission.UPDATE_LOCK_TASK_PACKAGES"
+40 −10
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.StringBuilder;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
@@ -414,7 +415,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC

        @Override
        public void registerListener(IVrStateCallbacks cb) {
            enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
            enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
                    Manifest.permission.ACCESS_VR_STATE);
            if (cb == null) {
                throw new IllegalArgumentException("Callback binder object is null.");
            }
@@ -424,7 +426,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC

        @Override
        public void unregisterListener(IVrStateCallbacks cb) {
            enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
            enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
                    Manifest.permission.ACCESS_VR_STATE);
            if (cb == null) {
                throw new IllegalArgumentException("Callback binder object is null.");
            }
@@ -434,7 +437,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC

        @Override
        public void registerPersistentVrStateListener(IPersistentVrStateCallbacks cb) {
            enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
            enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
                    Manifest.permission.ACCESS_VR_STATE);
            if (cb == null) {
                throw new IllegalArgumentException("Callback binder object is null.");
            }
@@ -444,7 +448,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC

        @Override
        public void unregisterPersistentVrStateListener(IPersistentVrStateCallbacks cb) {
            enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
            enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
                    Manifest.permission.ACCESS_VR_STATE);
            if (cb == null) {
                throw new IllegalArgumentException("Callback binder object is null.");
            }
@@ -454,19 +459,28 @@ public class VrManagerService extends SystemService implements EnabledComponentC

        @Override
        public boolean getVrModeState() {
            enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
                    Manifest.permission.ACCESS_VR_STATE);
            return VrManagerService.this.getVrMode();
        }

        @Override
        public boolean getPersistentVrModeEnabled() {
            enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
                    Manifest.permission.ACCESS_VR_STATE);
            return VrManagerService.this.getPersistentVrMode();
        }

        @Override
        public void setPersistentVrModeEnabled(boolean enabled) {
            enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS);
            enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
            VrManagerService.this.setPersistentVrModeEnabled(enabled);
        }

        @Override
        public void setVr2dDisplayProperties(
                Vr2dDisplayProperties vr2dDisplayProp) {
            enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS);
            enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
            VrManagerService.this.setVr2dDisplayProperties(vr2dDisplayProp);
        }

@@ -530,11 +544,21 @@ public class VrManagerService extends SystemService implements EnabledComponentC

    };

    private void enforceCallerPermission(String permission) {
    /**
     * Enforces that at lease one of the specified permissions is held by the caller.
     * Throws SecurityException if none of the specified permissions are held.
     *
     * @param permissions One or more permissions to check against.
     */
    private void enforceCallerPermissionAnyOf(String... permissions) {
        for (String permission : permissions) {
            if (mContext.checkCallingOrSelfPermission(permission)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Caller does not hold the permission " + permission);
                    == PackageManager.PERMISSION_GRANTED) {
                return;
            }
        }
        throw new SecurityException("Caller does not hold at least one of the permissions: "
                + Arrays.toString(permissions));
    }

    /**
@@ -1204,4 +1228,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC
            return mVrModeEnabled;
        }
    }

    private boolean getPersistentVrMode() {
        synchronized (mLock) {
            return mPersistentVrModeEnabled;
        }
    }
}