diff options
7 files changed, 291 insertions, 11 deletions
diff --git a/core/java/android/app/CompatibilityDisplayProperties.aidl b/core/java/android/app/CompatibilityDisplayProperties.aidl new file mode 100644 index 000000000000..626a63e05819 --- /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 000000000000..9a9bc2c40d94 --- /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 4dd578e7deab..878c8c38516d 100644 --- a/core/java/android/app/VrManager.java +++ b/core/java/android/app/VrManager.java @@ -45,6 +45,26 @@ public class VrManager { } /** + * 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 6eea07d33c40..8b2d0c6293e8 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 @@ interface IVrManager { 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 ee615fd6fde4..9e7012750ff5 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 @@ package com.android.server.vr; 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 @@ class CompatibilityDisplay { 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 @@ class CompatibilityDisplay { 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 @@ class CompatibilityDisplay { mDisplayManager = displayManager; mActivityManagerInternal = activityManagerInternal; mVrManager = vrManager; + mVirtualDisplayWidth = DEFAULT_VR_DISPLAY_WIDTH; + mVirtualDisplayHeight = DEFAULT_VR_DISPLAY_HEIGHT; + mVirtualDisplayDpi = DEFAULT_VR_DISPLAY_DPI; } /** @@ -165,6 +191,47 @@ class CompatibilityDisplay { } /** + * 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}. * @@ -175,7 +242,7 @@ class CompatibilityDisplay { if (mVirtualDisplay != null) { int virtualDisplayId = mVirtualDisplay.getDisplay().getDisplayId(); if (DEBUG) { - Log.e(TAG, "VD id: " + virtualDisplayId); + Log.i(TAG, "VD id: " + virtualDisplayId); } return virtualDisplayId; } @@ -202,8 +269,9 @@ class CompatibilityDisplay { 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( @@ -215,9 +283,7 @@ class CompatibilityDisplay { } } - if (DEBUG) { - Log.d(TAG, "VD created: " + mVirtualDisplay); - } + Log.i(TAG, "VD created: " + mVirtualDisplay); } /** @@ -279,8 +345,10 @@ class CompatibilityDisplay { */ 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 358861d0c9c4..63c61955bcd7 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 class VrManagerInternal { 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 cc089184d2ed..39a157355fe6 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.Manifest; 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 @@ public class VrManagerService extends SystemService implements EnabledComponentC } @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 @@ public class VrManagerService extends SystemService implements EnabledComponentC } @Override + public void setCompatibilityDisplayProperties( + CompatibilityDisplayProperties compatDisplayProp) { + VrManagerService.this.setCompatibilityDisplayProperties(compatDisplayProp); + } + + @Override public int getCompatibilityDisplayId() { return VrManagerService.this.getCompatibilityDisplayId(); } @@ -1106,6 +1120,15 @@ public class VrManagerService extends SystemService implements EnabledComponentC } } + 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(); |