Add MediaRouter API to get presentation display.

This new API makes it possible for an application to ask on
which Display it should show a Presentation based on the currently
selected media route.

Also added a new API on DisplayManager to query displays that
support a certain category of uses.

Improved the documentation of the Presentation class to explain
how to choose an appropriate Display for presentation.

Bug: 7409073
Change-Id: Iab451215e570ae55f3718fc228303143c800fe51
diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/java/com/android/server/display/DisplayDeviceInfo.java
index e76bf44..247d8a0 100644
--- a/services/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/java/com/android/server/display/DisplayDeviceInfo.java
@@ -17,6 +17,7 @@
 package com.android.server.display;
 
 import android.util.DisplayMetrics;
+import android.view.Display;
 import android.view.Surface;
 
 import libcore.util.Objects;
@@ -138,6 +139,17 @@
      */
     public int rotation = Surface.ROTATION_0;
 
+    /**
+     * Display type.
+     */
+    public int type;
+
+    /**
+     * Display address, or null if none.
+     * Interpretation varies by display type.
+     */
+    public String address;
+
     public void setAssumedDensityForExternalDisplay(int width, int height) {
         densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080;
         // Technically, these values should be smaller than the apparent density
@@ -162,7 +174,9 @@
                 && yDpi == other.yDpi
                 && flags == other.flags
                 && touch == other.touch
-                && rotation == other.rotation;
+                && rotation == other.rotation
+                && type == other.type
+                && Objects.equal(address, other.address);
     }
 
     @Override
@@ -181,6 +195,8 @@
         flags = other.flags;
         touch = other.touch;
         rotation = other.rotation;
+        type = other.type;
+        address = other.address;
     }
 
     // For debugging purposes
@@ -191,6 +207,8 @@
                 + "density " + densityDpi + ", " + xDpi + " x " + yDpi + " dpi"
                 + ", touch " + touchToString(touch) + flagsToString(flags)
                 + ", rotation " + rotation
+                + ", type " + Display.typeToString(type)
+                + ", address " + address
                 + "}";
     }
 
diff --git a/services/java/com/android/server/display/HeadlessDisplayAdapter.java b/services/java/com/android/server/display/HeadlessDisplayAdapter.java
index 919733d..7a104d7 100644
--- a/services/java/com/android/server/display/HeadlessDisplayAdapter.java
+++ b/services/java/com/android/server/display/HeadlessDisplayAdapter.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.os.Handler;
 import android.util.DisplayMetrics;
+import android.view.Display;
 
 /**
  * Provides a fake default display for headless systems.
@@ -63,6 +64,7 @@
                 mInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
                         | DisplayDeviceInfo.FLAG_SECURE
                         | DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS;
+                mInfo.type = Display.TYPE_BUILT_IN;
                 mInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
             }
             return mInfo;
diff --git a/services/java/com/android/server/display/LocalDisplayAdapter.java b/services/java/com/android/server/display/LocalDisplayAdapter.java
index fa56b83..b37d57f 100644
--- a/services/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/java/com/android/server/display/LocalDisplayAdapter.java
@@ -22,6 +22,7 @@
 import android.os.Looper;
 import android.os.SystemProperties;
 import android.util.SparseArray;
+import android.view.Display;
 import android.view.DisplayEventReceiver;
 import android.view.Surface;
 import android.view.Surface.PhysicalDisplayInfo;
@@ -139,11 +140,13 @@
                             com.android.internal.R.string.display_manager_built_in_display_name);
                     mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
                             | DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
+                    mInfo.type = Display.TYPE_BUILT_IN;
                     mInfo.densityDpi = (int)(mPhys.density * 160 + 0.5f);
                     mInfo.xDpi = mPhys.xDpi;
                     mInfo.yDpi = mPhys.yDpi;
                     mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
                 } else {
+                    mInfo.type = Display.TYPE_HDMI;
                     mInfo.name = getContext().getResources().getString(
                             com.android.internal.R.string.display_manager_hdmi_display_name);
                     mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
diff --git a/services/java/com/android/server/display/LogicalDisplay.java b/services/java/com/android/server/display/LogicalDisplay.java
index aa62aee..1583137 100644
--- a/services/java/com/android/server/display/LogicalDisplay.java
+++ b/services/java/com/android/server/display/LogicalDisplay.java
@@ -189,6 +189,8 @@
             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SECURE) != 0) {
                 mBaseDisplayInfo.flags |= Display.FLAG_SECURE;
             }
+            mBaseDisplayInfo.type = deviceInfo.type;
+            mBaseDisplayInfo.address = deviceInfo.address;
             mBaseDisplayInfo.name = deviceInfo.name;
             mBaseDisplayInfo.appWidth = deviceInfo.width;
             mBaseDisplayInfo.appHeight = deviceInfo.height;
diff --git a/services/java/com/android/server/display/OverlayDisplayAdapter.java b/services/java/com/android/server/display/OverlayDisplayAdapter.java
index c35fd98..36e9f74 100644
--- a/services/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -27,6 +27,7 @@
 import android.provider.Settings;
 import android.util.DisplayMetrics;
 import android.util.Slog;
+import android.view.Display;
 import android.view.Gravity;
 import android.view.Surface;
 
@@ -240,6 +241,7 @@
                 mInfo.xDpi = mDensityDpi;
                 mInfo.yDpi = mDensityDpi;
                 mInfo.flags = 0;
+                mInfo.type = Display.TYPE_OVERLAY;
                 mInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
             }
             return mInfo;
diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java
index 2ea83ee..45fff30 100644
--- a/services/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/java/com/android/server/display/WifiDisplayAdapter.java
@@ -39,6 +39,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Slog;
+import android.view.Display;
 import android.view.Surface;
 
 import java.io.PrintWriter;
@@ -293,9 +294,10 @@
         float refreshRate = 60.0f; // TODO: get this for real
 
         String name = display.getFriendlyDisplayName();
+        String address = display.getDeviceAddress();
         IBinder displayToken = Surface.createDisplay(name, secure);
         mDisplayDevice = new WifiDisplayDevice(displayToken, name, width, height,
-                refreshRate, deviceFlags, surface);
+                refreshRate, deviceFlags, address, surface);
         sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_ADDED);
 
         scheduleUpdateNotificationLocked();
@@ -515,12 +517,13 @@
         private final int mHeight;
         private final float mRefreshRate;
         private final int mFlags;
+        private final String mAddress;
 
         private Surface mSurface;
         private DisplayDeviceInfo mInfo;
 
         public WifiDisplayDevice(IBinder displayToken, String name,
-                int width, int height, float refreshRate, int flags,
+                int width, int height, float refreshRate, int flags, String address,
                 Surface surface) {
             super(WifiDisplayAdapter.this, displayToken);
             mName = name;
@@ -528,6 +531,7 @@
             mHeight = height;
             mRefreshRate = refreshRate;
             mFlags = flags;
+            mAddress = address;
             mSurface = surface;
         }
 
@@ -555,6 +559,8 @@
                 mInfo.height = mHeight;
                 mInfo.refreshRate = mRefreshRate;
                 mInfo.flags = mFlags;
+                mInfo.type = Display.TYPE_WIFI;
+                mInfo.address = mAddress;
                 mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
                 mInfo.setAssumedDensityForExternalDisplay(mWidth, mHeight);
             }