Merge changes from topic 'virtual-display-api' into oc-dev
* changes:
Add command line option to set compatibility display properties
Make VR mode virtual display properties customizable
diff --git a/cmds/vr/src/com/android/commands/vr/Vr.java b/cmds/vr/src/com/android/commands/vr/Vr.java
index 3fb40fb..bf97bba 100644
--- a/cmds/vr/src/com/android/commands/vr/Vr.java
+++ b/cmds/vr/src/com/android/commands/vr/Vr.java
@@ -16,6 +16,7 @@
package com.android.commands.vr;
+import android.app.CompatibilityDisplayProperties;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -36,7 +37,10 @@
(new Vr()).run(args);
}
- private static final String COMMAND_SET_PERSISTENT_VR_MODE_ENABLED = "set-persistent-vr-mode-enabled";
+ private static final String COMMAND_SET_PERSISTENT_VR_MODE_ENABLED =
+ "set-persistent-vr-mode-enabled";
+ private static final String COMMAND_SET_COMPATIBILITY_DISPLAY_PROPERTIES =
+ "set-display-props";
private IVrManager mVrService;
@@ -44,7 +48,8 @@
public void onShowUsage(PrintStream out) {
out.println(
"usage: vr [subcommand]\n" +
- "usage: vr set-persistent-vr-mode-enabled [true|false]\n"
+ "usage: vr set-persistent-vr-mode-enabled [true|false]\n" +
+ "usage: vr set-display-props [width] [height] [dpi]\n"
);
}
@@ -58,6 +63,9 @@
String command = nextArgRequired();
switch (command) {
+ case COMMAND_SET_COMPATIBILITY_DISPLAY_PROPERTIES:
+ runSetCompatibilityDisplayProperties();
+ break;
case COMMAND_SET_PERSISTENT_VR_MODE_ENABLED:
runSetPersistentVrModeEnabled();
break;
@@ -66,6 +74,26 @@
}
}
+ private void runSetCompatibilityDisplayProperties() throws RemoteException {
+ String widthStr = nextArgRequired();
+ int width = Integer.parseInt(widthStr);
+
+ String heightStr = nextArgRequired();
+ int height = Integer.parseInt(heightStr);
+
+ String dpiStr = nextArgRequired();
+ int dpi = Integer.parseInt(dpiStr);
+
+ CompatibilityDisplayProperties compatDisplayProperties =
+ new CompatibilityDisplayProperties(width, height, dpi);
+
+ try {
+ mVrService.setCompatibilityDisplayProperties(compatDisplayProperties);
+ } catch (RemoteException re) {
+ System.err.println("Error: Can't set persistent mode " + re);
+ }
+ }
+
private void runSetPersistentVrModeEnabled() throws RemoteException {
String enableStr = nextArg();
boolean enabled = Boolean.parseBoolean(enableStr);
diff --git a/core/java/android/app/CompatibilityDisplayProperties.aidl b/core/java/android/app/CompatibilityDisplayProperties.aidl
new file mode 100644
index 0000000..626a63e
--- /dev/null
+++ b/core/java/android/app/CompatibilityDisplayProperties.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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;
+
+/** @hide */
+parcelable CompatibilityDisplayProperties;
diff --git a/core/java/android/app/CompatibilityDisplayProperties.java b/core/java/android/app/CompatibilityDisplayProperties.java
new file mode 100644
index 0000000..9a9bc2c
--- /dev/null
+++ b/core/java/android/app/CompatibilityDisplayProperties.java
@@ -0,0 +1,123 @@
+/*
+ * 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;
+
+import android.content.ComponentName;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.io.PrintWriter;
+
+/**
+ * Display properties to be used by VR mode when creating a virtual display.
+ *
+ * @hide
+ */
+public class CompatibilityDisplayProperties implements Parcelable {
+
+ /**
+ * The actual width, height and dpi.
+ */
+ private final int mWidth;
+ private final int mHeight;
+ private final int mDpi;
+
+ public CompatibilityDisplayProperties(int width, int height, int dpi) {
+ mWidth = width;
+ mHeight = height;
+ mDpi = dpi;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = getWidth();
+ result = 31 * result + getHeight();
+ result = 31 * result + getDpi();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "CompatibilityDisplayProperties{" +
+ "mWidth=" + mWidth +
+ ", mHeight=" + mHeight +
+ ", mDpi=" + mDpi +
+ "}";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ CompatibilityDisplayProperties that = (CompatibilityDisplayProperties) o;
+
+ if (getWidth() != that.getWidth()) return false;
+ if (getHeight() != that.getHeight()) return false;
+ return getDpi() == that.getDpi();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mWidth);
+ dest.writeInt(mHeight);
+ dest.writeInt(mDpi);
+ }
+
+ public static final Parcelable.Creator<CompatibilityDisplayProperties> CREATOR
+ = new Parcelable.Creator<CompatibilityDisplayProperties>() {
+ @Override
+ public CompatibilityDisplayProperties createFromParcel(Parcel source) {
+ return new CompatibilityDisplayProperties(source);
+ }
+
+ @Override
+ public CompatibilityDisplayProperties[] newArray(int size) {
+ return new CompatibilityDisplayProperties[size];
+ }
+ };
+
+ private CompatibilityDisplayProperties(Parcel source) {
+ mWidth = source.readInt();
+ mHeight = source.readInt();
+ mDpi = source.readInt();
+ }
+
+ public void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix + "CompatibilityDisplayProperties:");
+ pw.println(prefix + " width=" + mWidth);
+ pw.println(prefix + " height=" + mHeight);
+ pw.println(prefix + " dpi=" + mDpi);
+ }
+
+ public int getWidth() {
+ return mWidth;
+ }
+
+ public int getHeight() {
+ return mHeight;
+ }
+
+ public int getDpi() {
+ return mDpi;
+ }
+}
diff --git a/core/java/android/app/VrManager.java b/core/java/android/app/VrManager.java
index 4dd578e..878c8c3 100644
--- a/core/java/android/app/VrManager.java
+++ b/core/java/android/app/VrManager.java
@@ -45,6 +45,26 @@
}
/**
+ * Sets the resolution and DPI of the compatibility virtual display used to display 2D
+ * applications in VR mode.
+ *
+ * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
+ *
+ * @param {@link android.app.CompatibilityDisplayProperties} properties to be set to the
+ * virtual display for 2D applications in VR mode.
+ *
+ * {@hide}
+ */
+ public void setCompatibilityDisplayProperties(
+ CompatibilityDisplayProperties compatDisplayProp) {
+ try {
+ mService.setCompatibilityDisplayProperties(compatDisplayProp);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Initiate connection for system controller data.
*
* @param fd Controller data file descriptor.
diff --git a/core/java/android/service/vr/IVrManager.aidl b/core/java/android/service/vr/IVrManager.aidl
index 6eea07d..8b2d0c6 100644
--- a/core/java/android/service/vr/IVrManager.aidl
+++ b/core/java/android/service/vr/IVrManager.aidl
@@ -16,6 +16,7 @@
package android.service.vr;
+import android.app.CompatibilityDisplayProperties;
import android.service.vr.IVrStateCallbacks;
import android.service.vr.IPersistentVrStateCallbacks;
@@ -67,6 +68,18 @@
void setPersistentVrModeEnabled(in boolean enabled);
/**
+ * Sets the resolution and DPI of the compatibility virtual display used to display
+ * 2D applications in VR mode.
+ *
+ * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
+ *
+ * @param compatDisplayProperties Compatibitlity display properties to be set for
+ * the VR virtual display
+ */
+ void setCompatibilityDisplayProperties(
+ in CompatibilityDisplayProperties compatDisplayProperties);
+
+ /**
* Return current virtual display id.
*
* @return {@link android.view.Display.INVALID_DISPLAY} if there is no virtual display
diff --git a/services/core/java/com/android/server/vr/CompatibilityDisplay.java b/services/core/java/com/android/server/vr/CompatibilityDisplay.java
index c6e52cd..d7cdf08 100644
--- a/services/core/java/com/android/server/vr/CompatibilityDisplay.java
+++ b/services/core/java/com/android/server/vr/CompatibilityDisplay.java
@@ -3,6 +3,7 @@
import static android.view.Display.INVALID_DISPLAY;
import android.app.ActivityManagerInternal;
+import android.app.CompatibilityDisplayProperties;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -35,9 +36,9 @@
private final static boolean DEBUG = false;
// TODO: Go over these values and figure out what is best
- private final static int HEIGHT = 1800;
- private final static int WIDTH = 1400;
- private final static int DPI = 320;
+ private int mVirtualDisplayHeight;
+ private int mVirtualDisplayWidth;
+ private int mVirtualDisplayDpi;
private final static int STOP_VIRTUAL_DISPLAY_DELAY_MILLIS = 2000;
private final static String DEBUG_ACTION_SET_MODE =
@@ -49,6 +50,28 @@
private final static String DEBUG_EXTRA_SURFACE =
"com.android.server.vr.CompatibilityDisplay.EXTRA_SURFACE";
+ /**
+ * The default width of the VR virtual display
+ */
+ public static final int DEFAULT_VR_DISPLAY_WIDTH = 1400;
+
+ /**
+ * The default height of the VR virtual display
+ */
+ public static final int DEFAULT_VR_DISPLAY_HEIGHT = 1800;
+
+ /**
+ * The default height of the VR virtual dpi.
+ */
+ public static final int DEFAULT_VR_DISPLAY_DPI = 320;
+
+ /**
+ * The minimum height, width and dpi of VR virtual display.
+ */
+ public static final int MIN_VR_DISPLAY_WIDTH = 1;
+ public static final int MIN_VR_DISPLAY_HEIGHT = 1;
+ public static final int MIN_VR_DISPLAY_DPI = 1;
+
private final ActivityManagerInternal mActivityManagerInternal;
private final DisplayManager mDisplayManager;
private final IVrManager mVrManager;
@@ -81,6 +104,9 @@
mDisplayManager = displayManager;
mActivityManagerInternal = activityManagerInternal;
mVrManager = vrManager;
+ mVirtualDisplayWidth = DEFAULT_VR_DISPLAY_WIDTH;
+ mVirtualDisplayHeight = DEFAULT_VR_DISPLAY_HEIGHT;
+ mVirtualDisplayDpi = DEFAULT_VR_DISPLAY_DPI;
}
/**
@@ -164,6 +190,47 @@
}
/**
+ * Sets the resolution and DPI of the compatibility virtual display used to display
+ * 2D applications in VR mode.
+ *
+ * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
+ *
+ * @param compatDisplayProperties Properties of the virtual display for 2D applications
+ * in VR mode.
+ */
+ public void setVirtualDisplayProperties(CompatibilityDisplayProperties compatDisplayProperties) {
+ synchronized(mVdLock) {
+ if (DEBUG) {
+ Log.i(TAG, "VD setVirtualDisplayProperties: res = " +
+ compatDisplayProperties.getWidth() + "X" + compatDisplayProperties.getHeight() +
+ ", dpi = " + compatDisplayProperties.getDpi());
+ }
+
+ if (compatDisplayProperties.getWidth() < MIN_VR_DISPLAY_WIDTH ||
+ compatDisplayProperties.getHeight() < MIN_VR_DISPLAY_HEIGHT ||
+ compatDisplayProperties.getDpi() < MIN_VR_DISPLAY_DPI) {
+ throw new IllegalArgumentException (
+ "Illegal argument: height, width, dpi cannot be negative. res = " +
+ compatDisplayProperties.getWidth() + "X" + compatDisplayProperties.getHeight() +
+ ", dpi = " + compatDisplayProperties.getDpi());
+ }
+
+ mVirtualDisplayWidth = compatDisplayProperties.getWidth();
+ mVirtualDisplayHeight = compatDisplayProperties.getHeight();
+ mVirtualDisplayDpi = compatDisplayProperties.getDpi();
+
+ if (mVirtualDisplay != null) {
+ mVirtualDisplay.resize(mVirtualDisplayWidth, mVirtualDisplayHeight,
+ mVirtualDisplayDpi);
+ ImageReader oldImageReader = mImageReader;
+ mImageReader = null;
+ startImageReader();
+ oldImageReader.close();
+ }
+ }
+ }
+
+ /**
* Returns the virtual display ID if one currently exists, otherwise returns
* {@link INVALID_DISPLAY_ID}.
*
@@ -174,7 +241,7 @@
if (mVirtualDisplay != null) {
int virtualDisplayId = mVirtualDisplay.getDisplay().getDisplayId();
if (DEBUG) {
- Log.e(TAG, "VD id: " + virtualDisplayId);
+ Log.i(TAG, "VD id: " + virtualDisplayId);
}
return virtualDisplayId;
}
@@ -201,8 +268,9 @@
return;
}
- mVirtualDisplay = mDisplayManager.createVirtualDisplay("VR 2D Display", WIDTH, HEIGHT,
- DPI, null /* Surface */, 0 /* flags */);
+ mVirtualDisplay = mDisplayManager.createVirtualDisplay("VR 2D Display",
+ mVirtualDisplayWidth, mVirtualDisplayHeight, mVirtualDisplayDpi,
+ null /* Surface */, 0 /* flags */);
if (mVirtualDisplay != null) {
mActivityManagerInternal.setVrCompatibilityDisplayId(
@@ -216,9 +284,7 @@
}
}
- if (DEBUG) {
- Log.d(TAG, "VD created: " + mVirtualDisplay);
- }
+ Log.i(TAG, "VD created: " + mVirtualDisplay);
}
/**
@@ -281,8 +347,10 @@
*/
private void startImageReader() {
if (mImageReader == null) {
- mImageReader = ImageReader.newInstance(WIDTH, HEIGHT, PixelFormat.RGBA_8888,
- 2 /* maxImages */);
+ mImageReader = ImageReader.newInstance(mVirtualDisplayWidth, mVirtualDisplayHeight,
+ PixelFormat.RGBA_8888, 2 /* maxImages */);
+ Log.i(TAG, "VD startImageReader: res = " + mVirtualDisplayWidth + "X" +
+ mVirtualDisplayHeight + ", dpi = " + mVirtualDisplayDpi);
}
synchronized (mVdLock) {
setSurfaceLocked(mImageReader.getSurface());
diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java
index 358861d..63c6195 100644
--- a/services/core/java/com/android/server/vr/VrManagerInternal.java
+++ b/services/core/java/com/android/server/vr/VrManagerInternal.java
@@ -16,6 +16,7 @@
package com.android.server.vr;
import android.annotation.NonNull;
+import android.app.CompatibilityDisplayProperties;
import android.content.ComponentName;
import android.service.vr.IPersistentVrStateCallbacks;
@@ -82,6 +83,18 @@
public abstract int hasVrPackage(@NonNull ComponentName packageName, int userId);
/**
+ * Sets the resolution and DPI of the compatibility virtual display used to display
+ * 2D applications in VR mode.
+ *
+ * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
+ *
+ * @param compatDisplayProp Properties of the virtual display for 2D applications
+ * in VR mode.
+ */
+ public abstract void setCompatibilityDisplayProperties(
+ CompatibilityDisplayProperties compatDisplayProp);
+
+ /**
* 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.
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index cc08918..39a1573 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -21,6 +21,7 @@
import android.app.ActivityManagerInternal;
import android.app.ActivityManager;
import android.app.AppOpsManager;
+import android.app.CompatibilityDisplayProperties;
import android.app.NotificationManager;
import android.annotation.NonNull;
import android.content.ComponentName;
@@ -427,6 +428,13 @@
}
@Override
+ public void setCompatibilityDisplayProperties(
+ CompatibilityDisplayProperties compatDisplayProp) {
+ enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS);
+ VrManagerService.this.setCompatibilityDisplayProperties(compatDisplayProp);
+ }
+
+ @Override
public int getCompatibilityDisplayId() {
return VrManagerService.this.getCompatibilityDisplayId();
}
@@ -541,6 +549,12 @@
}
@Override
+ public void setCompatibilityDisplayProperties(
+ CompatibilityDisplayProperties compatDisplayProp) {
+ VrManagerService.this.setCompatibilityDisplayProperties(compatDisplayProp);
+ }
+
+ @Override
public int getCompatibilityDisplayId() {
return VrManagerService.this.getCompatibilityDisplayId();
}
@@ -1106,6 +1120,15 @@
}
}
+ public void setCompatibilityDisplayProperties(
+ CompatibilityDisplayProperties compatDisplayProp) {
+ if (mCompatibilityDisplay != null) {
+ mCompatibilityDisplay.setVirtualDisplayProperties(compatDisplayProp);
+ return;
+ }
+ Slog.w(TAG, "CompatibilityDisplay is null!");
+ }
+
private int getCompatibilityDisplayId() {
if (mCompatibilityDisplay != null) {
return mCompatibilityDisplay.getVirtualDisplayId();