Add VrManager AIDL interface for use by system apps.

Bug: 27884853
Change-Id: I6de0d291deafe5003070d60866c60d6599312e79
This commit is contained in:
Ruben Brunk
2016-04-01 17:07:51 -07:00
parent ca94f29366
commit c7be3beced
8 changed files with 188 additions and 59 deletions

View File

@@ -244,6 +244,8 @@ LOCAL_SRC_FILES += \
core/java/android/service/notification/IConditionListener.aidl \
core/java/android/service/notification/IConditionProvider.aidl \
core/java/android/service/vr/IVrListener.aidl \
core/java/android/service/vr/IVrManager.aidl \
core/java/android/service/vr/IVrStateCallbacks.aidl \
core/java/android/print/ILayoutResultCallback.aidl \
core/java/android/print/IPrinterDiscoveryObserver.aidl \
core/java/android/print/IPrintDocumentAdapter.aidl \

View File

@@ -0,0 +1,46 @@
/**
* Copyright (c) 2016, 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.service.vr;
import android.service.vr.IVrStateCallbacks;
/** @hide */
interface IVrManager {
/**
* Add a callback to be notified when VR mode state changes.
*
* @param cb the callback instance to add.
*/
void registerListener(in IVrStateCallbacks cb);
/**
* Remove the callack from the current set of registered callbacks.
*
* @param cb the callback to remove.
*/
void unregisterListener(in IVrStateCallbacks cb);
/**
* Return current VR mode state.
*
* @return {@code true} if VR mode is enabled.
*/
boolean getVrModeState();
}

View File

@@ -0,0 +1,24 @@
/**
* Copyright (c) 2016, 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.service.vr;
/** @hide */
oneway interface IVrStateCallbacks {
void onVrStateChanged(in boolean enabled);
}

View File

@@ -2991,6 +2991,11 @@
<permission android:name="android.permission.BIND_VR_LISTENER_SERVICE"
android:protectionLevel="signature" />
<!-- Required to make calls to {@link android.service.vr.IVrManager}.
@hide -->
<permission android:name="android.permission.ACCESS_VR_MANAGER"
android:protectionLevel="signature" />
<!-- 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"

View File

@@ -18,12 +18,17 @@ package com.android.server.lights;
import com.android.server.SystemService;
import com.android.server.vr.VrManagerInternal;
import com.android.server.vr.VrManagerService;
import com.android.server.vr.VrStateListener;
import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.os.Trace;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
import android.util.Slog;
public class LightsService extends SystemService {
@@ -164,13 +169,19 @@ public class LightsService extends SystemService {
@Override
public void onBootPhase(int phase) {
if (phase == PHASE_SYSTEM_SERVICES_READY) {
getLocalService(VrManagerInternal.class).registerListener(mVrStateListener);
IVrManager vrManager =
(IVrManager) getBinderService(VrManagerService.VR_MANAGER_BINDER_SERVICE);
try {
vrManager.registerListener(mVrStateCallbacks);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to register VR mode state listener: " + e);
}
}
}
private final VrStateListener mVrStateListener = new VrStateListener() {
private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
@Override
public void onVrStateChanged(boolean enabled) {
public void onVrStateChanged(boolean enabled) throws RemoteException {
LightImpl l = mLights[LightsManager.LIGHT_ID_BACKLIGHT];
if (enabled) {
if (DEBUG) Slog.v(TAG, "VR mode enabled, setting brightness to low persistence");

View File

@@ -53,6 +53,8 @@ import android.provider.Settings;
import android.provider.Settings.Secure;
import android.provider.Settings.SettingNotFoundException;
import android.service.dreams.DreamManagerInternal;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
import android.util.EventLog;
import android.util.Slog;
import android.util.SparseIntArray;
@@ -72,6 +74,7 @@ import com.android.server.am.BatteryStatsService;
import com.android.server.lights.Light;
import com.android.server.lights.LightsManager;
import com.android.server.vr.VrManagerInternal;
import com.android.server.vr.VrManagerService;
import com.android.server.vr.VrStateListener;
import libcore.util.Objects;
@@ -658,7 +661,13 @@ public final class PowerManagerService extends SystemService
resolver.registerContentObserver(Settings.Secure.getUriFor(
Secure.BRIGHTNESS_USE_TWILIGHT),
false, mSettingsObserver, UserHandle.USER_ALL);
getLocalService(VrManagerInternal.class).registerListener(mVrStateListener);
IVrManager vrManager =
(IVrManager) getBinderService(VrManagerService.VR_MANAGER_BINDER_SERVICE);
try {
vrManager.registerListener(mVrStateCallbacks);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to register VR mode state listener: " + e);
}
// Go.
readConfigurationLocked();
updateSettingsLocked();
@@ -3007,7 +3016,7 @@ public final class PowerManagerService extends SystemService
}
}
private final VrStateListener mVrStateListener = new VrStateListener() {
private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
@Override
public void onVrStateChanged(boolean enabled) {
powerHintInternal(POWER_HINT_VR_MODE, enabled ? 1 : 0);

View File

@@ -30,13 +30,6 @@ public abstract class VrManagerInternal {
*/
public static final int NO_ERROR = 0;
/**
* Return current VR mode state.
*
* @return {@code true} if VR mode is enabled.
*/
public abstract boolean isInVrMode();
/**
* Return {@code true} if the given package is the currently bound VrListenerService for the
* given user.
@@ -59,22 +52,6 @@ public abstract class VrManagerInternal {
public abstract void setVrMode(boolean enabled, @NonNull ComponentName packageName,
int userId, @NonNull ComponentName calling);
/**
* Add a listener for VR mode state changes.
* <p>
* This listener will immediately be called with the current VR mode state.
* </p>
* @param listener the listener instance to add.
*/
public abstract void registerListener(@NonNull VrStateListener listener);
/**
* Remove the listener from the current set of listeners.
*
* @param listener the listener to remove.
*/
public abstract void unregisterListener(@NonNull VrStateListener listener);
/**
* Return NO_ERROR if the given package is installed on the device and enabled as a
* VrListenerService for the given current user, or a negative error code indicating a failure.

View File

@@ -15,6 +15,7 @@
*/
package com.android.server.vr;
import android.Manifest;
import android.app.AppOpsManager;
import android.app.NotificationManager;
import android.annotation.NonNull;
@@ -29,11 +30,15 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.NotificationListenerService;
import android.service.vr.IVrListener;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
import android.service.vr.VrListenerService;
import android.util.ArraySet;
import android.util.Slog;
@@ -46,6 +51,7 @@ import com.android.server.utils.ManagedApplicationService;
import com.android.server.utils.ManagedApplicationService.BinderChecker;
import java.lang.StringBuilder;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;
@@ -75,6 +81,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC
public static final String TAG = "VrManagerService";
public static final String VR_MANAGER_BINDER_SERVICE = "vrmanager";
private static native void initializeNative();
private static native void setVrModeNative(boolean enabled);
@@ -84,7 +92,6 @@ public class VrManagerService extends SystemService implements EnabledComponentC
// State protected by mLock
private boolean mVrModeEnabled;
private final Set<VrStateListener> mListeners = new ArraySet<>();
private EnabledComponentsObserver mComponentObserver;
private ManagedApplicationService mCurrentVrService;
private Context mContext;
@@ -92,10 +99,37 @@ public class VrManagerService extends SystemService implements EnabledComponentC
private int mCurrentVrModeUser;
private boolean mWasDefaultGranted;
private boolean mGuard;
private final RemoteCallbackList<IVrStateCallbacks> mRemoteCallbacks =
new RemoteCallbackList<>();
private final ArraySet<String> mPreviousToggledListenerSettings = new ArraySet<>();
private String mPreviousNotificationPolicyAccessPackage;
private String mPreviousManageOverlayPackage;
private static final int MSG_VR_STATE_CHANGE = 0;
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case MSG_VR_STATE_CHANGE : {
boolean state = (msg.arg1 == 1);
int i = mRemoteCallbacks.beginBroadcast();
while (i > 0) {
i--;
try {
mRemoteCallbacks.getBroadcastItem(i).onVrStateChanged(state);
} catch (RemoteException e) {
// Noop
}
}
mRemoteCallbacks.finishBroadcast();
} break;
default :
throw new IllegalStateException("Unknown message type: " + msg.what);
}
}
};
private static final BinderChecker sBinderChecker = new BinderChecker() {
@Override
public IInterface asInterface(IBinder binder) {
@@ -125,15 +159,46 @@ public class VrManagerService extends SystemService implements EnabledComponentC
}
}
private final IVrManager mVrManager = new IVrManager.Stub() {
@Override
public void registerListener(IVrStateCallbacks cb) {
enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
if (cb == null) {
throw new IllegalArgumentException("Callback binder object is null.");
}
VrManagerService.this.addStateCallback(cb);
}
@Override
public void unregisterListener(IVrStateCallbacks cb) {
enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
if (cb == null) {
throw new IllegalArgumentException("Callback binder object is null.");
}
VrManagerService.this.removeStateCallback(cb);
}
@Override
public boolean getVrModeState() {
return VrManagerService.this.getVrMode();
}
};
private void enforceCallerPermission(String permission) {
if (mContext.checkCallingOrSelfPermission(permission)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Caller does not hold the permission " + permission);
}
}
/**
* Implementation of VrManagerInternal. Callable only from system services.
*/
private final class LocalService extends VrManagerInternal {
@Override
public boolean isInVrMode() {
return VrManagerService.this.getVrMode();
}
@Override
public void setVrMode(boolean enabled, ComponentName packageName, int userId,
ComponentName callingPackage) {
@@ -145,16 +210,6 @@ public class VrManagerService extends SystemService implements EnabledComponentC
return VrManagerService.this.isCurrentVrListener(packageName, userId);
}
@Override
public void registerListener(VrStateListener listener) {
VrManagerService.this.addListener(listener);
}
@Override
public void unregisterListener(VrStateListener listener) {
VrManagerService.this.removeListener(listener);
}
@Override
public int hasVrPackage(ComponentName packageName, int userId) {
return VrManagerService.this.hasVrPackage(packageName, userId);
@@ -173,6 +228,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC
}
publishLocalService(VrManagerInternal.class, new LocalService());
publishBinderService(VR_MANAGER_BINDER_SERVICE, mVrManager.asBinder());
}
@Override
@@ -551,9 +607,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC
* Note: Must be called while holding {@code mLock}.
*/
private void onVrModeChangedLocked() {
for (VrStateListener l : mListeners) {
l.onVrStateChanged(mVrModeEnabled);
}
mHandler.sendMessage(mHandler.obtainMessage(MSG_VR_STATE_CHANGE,
(mVrModeEnabled) ? 1 : 0, 0));
}
/**
@@ -577,9 +632,9 @@ public class VrManagerService extends SystemService implements EnabledComponentC
}
}
private boolean getVrMode() {
private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) {
synchronized (mLock) {
return mVrModeEnabled;
return mComponentObserver.isValid(targetPackageName, userId);
}
}
@@ -593,21 +648,21 @@ public class VrManagerService extends SystemService implements EnabledComponentC
}
}
private void addListener(VrStateListener listener) {
synchronized (mLock) {
mListeners.add(listener);
}
/*
* Implementation of IVrManager calls.
*/
private void addStateCallback(IVrStateCallbacks cb) {
mRemoteCallbacks.register(cb);
}
private void removeListener(VrStateListener listener) {
synchronized (mLock) {
mListeners.remove(listener);
}
private void removeStateCallback(IVrStateCallbacks cb) {
mRemoteCallbacks.unregister(cb);
}
private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) {
private boolean getVrMode() {
synchronized (mLock) {
return mComponentObserver.isValid(targetPackageName, userId);
return mVrModeEnabled;
}
}
}