Merge "Add ability to turn off VR virtual display functionality." into oc-dr1-dev am: 67143a8cfc
am: 99eac47966

Change-Id: I5fb247a2291ee4fdc96b25e297cb7f7e0ec49d5a
diff --git a/cmds/vr/src/com/android/commands/vr/Vr.java b/cmds/vr/src/com/android/commands/vr/Vr.java
index b765866..8fb1b7b 100644
--- a/cmds/vr/src/com/android/commands/vr/Vr.java
+++ b/cmds/vr/src/com/android/commands/vr/Vr.java
@@ -41,6 +41,7 @@
         "set-persistent-vr-mode-enabled";
     private static final String COMMAND_SET_VR2D_DISPLAY_PROPERTIES =
         "set-display-props";
+    private static final String COMMAND_ENABLE_VD = "enable-virtual-display";
 
     private IVrManager mVrService;
 
@@ -49,7 +50,8 @@
         out.println(
                 "usage: vr [subcommand]\n" +
                 "usage: vr set-persistent-vr-mode-enabled [true|false]\n" +
-                "usage: vr set-display-props [width] [height] [dpi]\n"
+                "usage: vr set-display-props [width] [height] [dpi]\n" +
+                "usage: vr enable-virtual-display [true|false]\n"
                 );
     }
 
@@ -69,6 +71,9 @@
             case COMMAND_SET_PERSISTENT_VR_MODE_ENABLED:
                 runSetPersistentVrModeEnabled();
                 break;
+            case COMMAND_ENABLE_VD:
+                runEnableVd();
+                break;
             default:
                 throw new IllegalArgumentException ("unknown command '" + command + "'");
         }
@@ -94,6 +99,23 @@
         }
     }
 
+    private void runEnableVd() throws RemoteException {
+        Vr2dDisplayProperties.Builder builder = new Vr2dDisplayProperties.Builder();
+
+        String value = nextArgRequired();
+        if ("true".equals(value)) {
+            builder.setEnabled(true);
+        } else if ("false".equals(value)) {
+            builder.setEnabled(false);
+        } // Don't do anything if not exactly true/false
+
+        try {
+            mVrService.setVr2dDisplayProperties(builder.build());
+        } catch (RemoteException re) {
+            System.err.println("Error: Can't enable (" + value +") virtual display" + re);
+        }
+    }
+
     private void runSetPersistentVrModeEnabled() throws RemoteException {
         String enableStr = nextArg();
         boolean enabled = Boolean.parseBoolean(enableStr);
diff --git a/core/java/android/app/Vr2dDisplayProperties.java b/core/java/android/app/Vr2dDisplayProperties.java
index a608bb0..0eb2af3 100644
--- a/core/java/android/app/Vr2dDisplayProperties.java
+++ b/core/java/android/app/Vr2dDisplayProperties.java
@@ -16,7 +16,6 @@
 
 package android.app;
 
-import android.content.ComponentName;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -27,19 +26,31 @@
  *
  * @hide
  */
-public class Vr2dDisplayProperties implements Parcelable {
+public final class Vr2dDisplayProperties implements Parcelable {
 
-   /**
-    * The actual width, height and dpi.
-    */
+    public static final int FLAG_VIRTUAL_DISPLAY_ENABLED = 1;
+
+    /**
+     * The actual width, height and dpi.
+     */
     private final int mWidth;
     private final int mHeight;
     private final int mDpi;
 
+    // Flags describing the virtual display behavior.
+    private final int mAddedFlags;
+    private final int mRemovedFlags;
+
     public Vr2dDisplayProperties(int width, int height, int dpi) {
+        this(width, height, dpi, 0, 0);
+    }
+
+    private Vr2dDisplayProperties(int width, int height, int dpi, int flags, int removedFlags) {
         mWidth = width;
         mHeight = height;
         mDpi = dpi;
+        mAddedFlags = flags;
+        mRemovedFlags = removedFlags;
     }
 
     @Override
@@ -52,11 +63,13 @@
 
     @Override
     public String toString() {
-        return "Vr2dDisplayProperties{" +
-                "mWidth=" + mWidth +
-                ", mHeight=" + mHeight +
-                ", mDpi=" + mDpi +
-                "}";
+        return "Vr2dDisplayProperties{"
+                + "mWidth=" + mWidth
+                + ", mHeight=" + mHeight
+                + ", mDpi=" + mDpi
+                + ", flags=" + toReadableFlags(mAddedFlags)
+                + ", removed_flags=" + toReadableFlags(mRemovedFlags)
+                + "}";
     }
 
     @Override
@@ -66,6 +79,8 @@
 
         Vr2dDisplayProperties that = (Vr2dDisplayProperties) o;
 
+        if (getFlags() != that.getFlags()) return false;
+        if (getRemovedFlags() != that.getRemovedFlags()) return false;
         if (getWidth() != that.getWidth()) return false;
         if (getHeight() != that.getHeight()) return false;
         return getDpi() == that.getDpi();
@@ -81,6 +96,8 @@
         dest.writeInt(mWidth);
         dest.writeInt(mHeight);
         dest.writeInt(mDpi);
+        dest.writeInt(mAddedFlags);
+        dest.writeInt(mRemovedFlags);
     }
 
     public static final Parcelable.Creator<Vr2dDisplayProperties> CREATOR
@@ -100,13 +117,12 @@
         mWidth = source.readInt();
         mHeight = source.readInt();
         mDpi = source.readInt();
+        mAddedFlags = source.readInt();
+        mRemovedFlags = source.readInt();
     }
 
     public void dump(PrintWriter pw, String prefix) {
-        pw.println(prefix + "Vr2dDisplayProperties:");
-        pw.println(prefix + "  width=" + mWidth);
-        pw.println(prefix + "  height=" + mHeight);
-        pw.println(prefix + "  dpi=" + mDpi);
+        pw.println(prefix + toString());
     }
 
     public int getWidth() {
@@ -120,4 +136,83 @@
     public int getDpi() {
         return mDpi;
     }
+
+    public int getFlags() {
+        return mAddedFlags;
+    }
+
+    public int getRemovedFlags() {
+        return mRemovedFlags;
+    }
+
+    private static String toReadableFlags(int flags) {
+        String retval = "{";
+        if ((flags & FLAG_VIRTUAL_DISPLAY_ENABLED) == FLAG_VIRTUAL_DISPLAY_ENABLED) {
+            retval += "enabled";
+        }
+        return retval + "}";
+    }
+
+    /**
+     * Convenience class for creating Vr2dDisplayProperties.
+     */
+    public static class Builder {
+        private int mAddedFlags = 0;
+        private int mRemovedFlags = 0;
+
+        // Negative values are translated as an "ignore" to VrManagerService.
+        private int mWidth = -1;
+        private int mHeight = -1;
+        private int mDpi = -1;
+
+        public Builder() {
+        }
+
+        /**
+         * Sets the dimensions to use for the virtual display.
+         */
+        public Builder setDimensions(int width, int height, int dpi) {
+            mWidth = width;
+            mHeight = height;
+            mDpi = dpi;
+            return this;
+        }
+
+        /**
+         * Toggles the virtual display functionality for 2D activities in VR.
+         */
+        public Builder setEnabled(boolean enabled) {
+            if (enabled) {
+                addFlags(FLAG_VIRTUAL_DISPLAY_ENABLED);
+            } else {
+                removeFlags(FLAG_VIRTUAL_DISPLAY_ENABLED);
+            }
+            return this;
+        }
+
+        /**
+         * Adds property flags.
+         */
+        public Builder addFlags(int flags) {
+            mAddedFlags |= flags;
+            mRemovedFlags &= ~flags;
+            return this;
+        }
+
+        /**
+         * Removes property flags.
+         */
+        public Builder removeFlags(int flags) {
+            mRemovedFlags |= flags;
+            mAddedFlags &= ~flags;
+            return this;
+        }
+
+        /**
+         * Builds the Vr2dDisplayProperty instance.
+         */
+        public Vr2dDisplayProperties build() {
+            return new Vr2dDisplayProperties(mWidth, mHeight, mDpi, mAddedFlags, mRemovedFlags);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/vr/Vr2dDisplay.java b/services/core/java/com/android/server/vr/Vr2dDisplay.java
index 8335243..fa98f17 100644
--- a/services/core/java/com/android/server/vr/Vr2dDisplay.java
+++ b/services/core/java/com/android/server/vr/Vr2dDisplay.java
@@ -100,6 +100,7 @@
     private Runnable mStopVDRunnable;
     private boolean mIsVrModeOverrideEnabled;
     private boolean mIsVrModeEnabled;
+    private boolean mIsVirtualDisplayAllowed = true;
 
     public Vr2dDisplay(DisplayManager displayManager,
            ActivityManagerInternal activityManagerInternal, IVrManager vrManager) {
@@ -124,10 +125,11 @@
      */
     private void updateVirtualDisplay() {
         if (DEBUG) {
-            Log.i(TAG, "isVrMode: " + mIsVrModeEnabled + ", override: " + mIsVrModeOverrideEnabled);
+            Log.i(TAG, "isVrMode: " + mIsVrModeEnabled + ", override: " + mIsVrModeOverrideEnabled
+                    + ", isAllowed: " + mIsVirtualDisplayAllowed);
         }
 
-        if (mIsVrModeEnabled || mIsVrModeOverrideEnabled) {
+        if (shouldRunVirtualDisplay()) {
             // TODO: Consider not creating the display until ActivityManager needs one on
             // which to display a 2D application.
             startVirtualDisplay();
@@ -190,33 +192,43 @@
      *
      * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
      *
-     * @param compatDisplayProperties Properties of the virtual display for 2D applications
+     * @param displayProperties Properties of the virtual display for 2D applications
      * in VR mode.
      */
-    public void setVirtualDisplayProperties(Vr2dDisplayProperties compatDisplayProperties) {
+    public void setVirtualDisplayProperties(Vr2dDisplayProperties displayProperties) {
         synchronized(mVdLock) {
             if (DEBUG) {
-                Log.i(TAG, "VD setVirtualDisplayProperties: res = "
-                        + compatDisplayProperties.getWidth() + "X"
-                        + compatDisplayProperties.getHeight() + ", dpi = "
-                        + compatDisplayProperties.getDpi());
+                Log.i(TAG, "VD setVirtualDisplayProperties: " +
+                        displayProperties.toString());
             }
 
-            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());
+            int width = displayProperties.getWidth();
+            int height = displayProperties.getHeight();
+            int dpi = displayProperties.getDpi();
+            boolean resized = false;
+
+            if (width < MIN_VR_DISPLAY_WIDTH || height < MIN_VR_DISPLAY_HEIGHT ||
+                    dpi < MIN_VR_DISPLAY_DPI) {
+                Log.i(TAG, "Ignoring Width/Height/Dpi values of " + width + "," + height + ","
+                        + dpi);
+            } else {
+                Log.i(TAG, "Setting width/height/dpi to " + width + "," + height + "," + dpi);
+                mVirtualDisplayWidth = width;
+                mVirtualDisplayHeight = height;
+                mVirtualDisplayDpi = dpi;
+                resized = true;
             }
 
-            mVirtualDisplayWidth = compatDisplayProperties.getWidth();
-            mVirtualDisplayHeight = compatDisplayProperties.getHeight();
-            mVirtualDisplayDpi = compatDisplayProperties.getDpi();
+            if ((displayProperties.getFlags() & Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED)
+                    == Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED) {
+                mIsVirtualDisplayAllowed = true;
+            } else if ((displayProperties.getRemovedFlags() &
+                    Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED)
+                    == Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED) {
+                mIsVirtualDisplayAllowed = false;
+            }
 
-            if (mVirtualDisplay != null) {
+            if (mVirtualDisplay != null && resized && mIsVirtualDisplayAllowed) {
                 mVirtualDisplay.resize(mVirtualDisplayWidth, mVirtualDisplayHeight,
                     mVirtualDisplayDpi);
                 ImageReader oldImageReader = mImageReader;
@@ -224,6 +236,9 @@
                 startImageReader();
                 oldImageReader.close();
             }
+
+            // Start/Stop the virtual display in case the updates indicated that we should.
+            updateVirtualDisplay();
         }
     }
 
@@ -297,7 +312,7 @@
            mStopVDRunnable = new Runnable() {
                @Override
                public void run() {
-                    if (mIsVrModeEnabled) {
+                    if (shouldRunVirtualDisplay()) {
                         Log.i(TAG, "Virtual Display destruction stopped: VrMode is back on.");
                     } else {
                         Log.i(TAG, "Stopping Virtual Display");
@@ -366,4 +381,8 @@
             mImageReader = null;
         }
     }
+
+    private boolean shouldRunVirtualDisplay() {
+        return mIsVirtualDisplayAllowed && (mIsVrModeEnabled || mIsVrModeOverrideEnabled);
+    }
 }