Introduces VrManager as a system service.
Provides access to persistent VR mode as used by VR viewer when a device is believed to be inside a viewer. Bug: 34736524 Test: Built, run using build of vr services that enables mode. Change-Id: I6ff392f09adb8e4bd522dacbd064777bba836282
This commit is contained in:
@@ -6204,6 +6204,10 @@ package android.app {
|
||||
method public void onDetached();
|
||||
}
|
||||
|
||||
public class VrManager {
|
||||
method public void setPersistentVrModeEnabled(boolean);
|
||||
}
|
||||
|
||||
public final class WallpaperInfo implements android.os.Parcelable {
|
||||
ctor public WallpaperInfo(android.content.Context, android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
|
||||
method public int describeContents();
|
||||
@@ -9006,6 +9010,7 @@ package android.content {
|
||||
field public static final java.lang.String USB_SERVICE = "usb";
|
||||
field public static final java.lang.String USER_SERVICE = "user";
|
||||
field public static final java.lang.String VIBRATOR_SERVICE = "vibrator";
|
||||
field public static final java.lang.String VR_SERVICE = "vrmanager";
|
||||
field public static final java.lang.String WALLPAPER_SERVICE = "wallpaper";
|
||||
field public static final java.lang.String WIFI_AWARE_SERVICE = "wifiaware";
|
||||
field public static final java.lang.String WIFI_P2P_SERVICE = "wifip2p";
|
||||
|
||||
@@ -115,6 +115,7 @@ import android.print.PrintManager;
|
||||
import android.service.autofill.IAutoFillManagerService;
|
||||
import android.service.persistentdata.IPersistentDataBlockService;
|
||||
import android.service.persistentdata.PersistentDataBlockManager;
|
||||
import android.service.vr.IVrManager;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
@@ -814,6 +815,14 @@ final class SystemServiceRegistry {
|
||||
IAutoFillManagerService service = IAutoFillManagerService.Stub.asInterface(b);
|
||||
return new AutoFillManager(ctx, service);
|
||||
}});
|
||||
|
||||
registerService(Context.VR_SERVICE, VrManager.class, new CachedServiceFetcher<VrManager>() {
|
||||
@Override
|
||||
public VrManager createService(ContextImpl ctx) throws ServiceNotFoundException {
|
||||
IBinder b = ServiceManager.getServiceOrThrow(Context.VR_SERVICE);
|
||||
return new VrManager(IVrManager.Stub.asInterface(b));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
44
core/java/android/app/VrManager.java
Normal file
44
core/java/android/app/VrManager.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package android.app;
|
||||
|
||||
|
||||
import android.annotation.SystemApi;
|
||||
import android.content.ComponentName;
|
||||
import android.os.RemoteException;
|
||||
import android.service.vr.IVrManager;
|
||||
|
||||
/**
|
||||
* Used to control aspects of a devices Virtual Reality (VR) capabilities.
|
||||
* <p>
|
||||
* You do not instantiate this class directly; instead, retrieve it through
|
||||
* {@link android.content.Context#getSystemService}.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public class VrManager {
|
||||
private final IVrManager mService;
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
public VrManager(IVrManager service) {
|
||||
mService = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* by VR viewers to indicate that a device is placed in a VR viewer.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
|
||||
*
|
||||
* @see Activity#setVrModeEnabled(boolean, ComponentName)
|
||||
* @param enabled true if the device should be placed in persistent VR mode.
|
||||
*/
|
||||
public void setPersistentVrModeEnabled(boolean enabled) {
|
||||
try {
|
||||
mService.setPersistentVrModeEnabled(enabled);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import android.annotation.UserIdInt;
|
||||
import android.app.IApplicationThread;
|
||||
import android.app.IServiceConnection;
|
||||
import android.app.Notification;
|
||||
import android.app.VrManager;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.AssetManager;
|
||||
@@ -3763,6 +3764,16 @@ public abstract class Context {
|
||||
*/
|
||||
public static final String OVERLAY_SERVICE = "overlay";
|
||||
|
||||
/**
|
||||
* Use with {@link #getSystemService} to retrieve a
|
||||
* {@link VrManager} for accessing the VR service.
|
||||
*
|
||||
* @see #getSystemService
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final String VR_SERVICE = "vrmanager";
|
||||
|
||||
/**
|
||||
* Determine whether the given permission is allowed for a particular
|
||||
* process and user ID running in the system.
|
||||
|
||||
@@ -42,5 +42,13 @@ interface IVrManager {
|
||||
*/
|
||||
boolean getVrModeState();
|
||||
|
||||
/**
|
||||
* 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
|
||||
* by VR viewers to indicate that a device is placed in a VR viewer.
|
||||
*
|
||||
* @param enabled true if the device should be placed in persistent VR mode.
|
||||
*/
|
||||
void setPersistentVrModeEnabled(in boolean enabled);
|
||||
}
|
||||
|
||||
|
||||
@@ -79,4 +79,13 @@ public abstract class VrManagerInternal {
|
||||
* given in {@link android.service.vr.VrModeException} on failure.
|
||||
*/
|
||||
public abstract int hasVrPackage(@NonNull ComponentName packageName, int userId);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* by VR viewers to indicate that a device is placed in a VR viewer.
|
||||
*
|
||||
* @param enabled true if the device should be placed in persistent VR mode.
|
||||
*/
|
||||
public abstract void setPersistentVrModeEnabled(boolean enabled);
|
||||
}
|
||||
|
||||
@@ -20,15 +20,10 @@ import android.app.ActivityManager;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.NotificationManager;
|
||||
import android.annotation.NonNull;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.FeatureInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.Binder;
|
||||
@@ -53,7 +48,6 @@ import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemConfig;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.utils.ManagedApplicationService.PendingEvent;
|
||||
@@ -69,8 +63,6 @@ import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -121,8 +113,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC
|
||||
// State protected by mLock
|
||||
private boolean mVrModeAllowed;
|
||||
private boolean mVrModeEnabled;
|
||||
private boolean mPersistentVrModeEnabled;
|
||||
private EnabledComponentsObserver mComponentObserver;
|
||||
private ManagedApplicationService mCurrentVrService;
|
||||
private ComponentName mDefaultVrService;
|
||||
private Context mContext;
|
||||
private ComponentName mCurrentVrModeComponent;
|
||||
private int mCurrentVrModeUser;
|
||||
@@ -157,6 +151,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC
|
||||
if (mVrModeAllowed) {
|
||||
consumeAndApplyPendingStateLocked();
|
||||
} else {
|
||||
// Disable persistent mode when VR mode isn't allowed, allows an escape hatch to
|
||||
// exit persistent VR mode when screen is turned off.
|
||||
mPersistentVrModeEnabled = false;
|
||||
|
||||
// Set pending state to current state.
|
||||
mPendingState = (mVrModeEnabled && mCurrentVrService != null)
|
||||
? new VrState(mVrModeEnabled, mCurrentVrService.getComponent(),
|
||||
@@ -377,6 +375,12 @@ public class VrManagerService extends SystemService implements EnabledComponentC
|
||||
return VrManagerService.this.getVrMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPersistentVrModeEnabled(boolean enabled) {
|
||||
enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
|
||||
VrManagerService.this.setPersistentVrModeEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
|
||||
@@ -387,6 +391,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC
|
||||
}
|
||||
pw.println("********* Dump of VrManagerService *********");
|
||||
pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed"));
|
||||
pw.println("Persistent VR mode is currently: " +
|
||||
((mPersistentVrModeEnabled) ? "enabled" : "disabled"));
|
||||
pw.println("Previous state transitions:\n");
|
||||
String tab = " ";
|
||||
dumpStateTransitions(pw);
|
||||
@@ -462,6 +468,11 @@ public class VrManagerService extends SystemService implements EnabledComponentC
|
||||
public int hasVrPackage(ComponentName packageName, int userId) {
|
||||
return VrManagerService.this.hasVrPackage(packageName, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPersistentVrModeEnabled(boolean enabled) {
|
||||
VrManagerService.this.setPersistentVrModeEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
public VrManagerService(Context context) {
|
||||
@@ -494,6 +505,15 @@ public class VrManagerService extends SystemService implements EnabledComponentC
|
||||
|
||||
mComponentObserver.rebuildAll();
|
||||
}
|
||||
|
||||
//TODO: something more robust than picking the first one
|
||||
ArraySet<ComponentName> defaultVrComponents =
|
||||
SystemConfig.getInstance().getDefaultVrComponents();
|
||||
if (defaultVrComponents.size() > 0) {
|
||||
mDefaultVrService = defaultVrComponents.valueAt(0);
|
||||
} else {
|
||||
Slog.i(TAG, "No default vr listener service found.");
|
||||
}
|
||||
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
|
||||
synchronized (mLock) {
|
||||
mVrModeAllowed = true;
|
||||
@@ -637,8 +657,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentVrModeComponent = calling;
|
||||
if (calling != null && !Objects.equals(calling, mCurrentVrModeComponent)) {
|
||||
mCurrentVrModeComponent = calling;
|
||||
sendUpdatedCaller = true;
|
||||
}
|
||||
|
||||
@@ -947,7 +967,25 @@ public class VrManagerService extends SystemService implements EnabledComponentC
|
||||
int userId, @NonNull ComponentName callingPackage) {
|
||||
|
||||
synchronized (mLock) {
|
||||
VrState pending = new VrState(enabled, targetPackageName, userId, callingPackage);
|
||||
VrState pending;
|
||||
ComponentName targetListener;
|
||||
ComponentName foregroundVrComponent;
|
||||
|
||||
// If the device is in persistent VR mode, then calls to disable VR mode are ignored,
|
||||
// and the system default VR listener is used.
|
||||
boolean targetEnabledState = enabled || mPersistentVrModeEnabled;
|
||||
if (!enabled && mPersistentVrModeEnabled) {
|
||||
targetListener = mDefaultVrService;
|
||||
|
||||
// Current foreground component isn't a VR one (in 2D app case)
|
||||
foregroundVrComponent = null;
|
||||
} else {
|
||||
targetListener = targetPackageName;
|
||||
foregroundVrComponent = callingPackage;
|
||||
}
|
||||
pending = new VrState(
|
||||
targetEnabledState, targetListener, userId, foregroundVrComponent);
|
||||
|
||||
if (!mVrModeAllowed) {
|
||||
// We're not allowed to be in VR mode. Make this state pending. This will be
|
||||
// applied the next time we are allowed to enter VR mode unless it is superseded by
|
||||
@@ -956,7 +994,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC
|
||||
return;
|
||||
}
|
||||
|
||||
if (!enabled && mCurrentVrService != null) {
|
||||
if (!targetEnabledState && mCurrentVrService != null) {
|
||||
// If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls
|
||||
// and service bind/unbind in case we are immediately switching to another VR app.
|
||||
if (mPendingState == null) {
|
||||
@@ -971,7 +1009,19 @@ public class VrManagerService extends SystemService implements EnabledComponentC
|
||||
mPendingState = null;
|
||||
}
|
||||
|
||||
updateCurrentVrServiceLocked(enabled, targetPackageName, userId, callingPackage);
|
||||
updateCurrentVrServiceLocked(
|
||||
targetEnabledState, targetListener, userId, foregroundVrComponent);
|
||||
}
|
||||
}
|
||||
|
||||
private void setPersistentVrModeEnabled(boolean enabled) {
|
||||
synchronized (mLock) {
|
||||
mPersistentVrModeEnabled = enabled;
|
||||
|
||||
// Disabling persistent mode when not showing a VR should disable the overall vr mode.
|
||||
if (!enabled && mCurrentVrModeComponent == null) {
|
||||
setVrMode(false, null, 0, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user