Merge "Added BasicMediaRouter sample based on the PresentationWithMediaRouterActivity API demo." into jb-mr2-dev
diff --git a/media/BasicMediaRouter/AndroidManifest.xml b/media/BasicMediaRouter/AndroidManifest.xml
new file mode 100644
index 0000000..f909d5e
--- /dev/null
+++ b/media/BasicMediaRouter/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.output.mediaroutersample"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="17"
+        android:targetSdkVersion="17" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name="com.example.android.media.basicmediarouter.MainActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
\ No newline at end of file
diff --git a/media/BasicMediaRouter/mediarouter.jd b/media/BasicMediaRouter/mediarouter.jd
new file mode 100644
index 0000000..fcf6ec9
--- /dev/null
+++ b/media/BasicMediaRouter/mediarouter.jd
@@ -0,0 +1,26 @@
+page.title=MediaRouter Sample
+@jd:body
+<p>
+This sample demonstrates the use of the MediaRouter API to show content on a
+secondary display using a {@link Presentation}.
+</p>
+<p>
+The activity uses the 
+<a href="http://developer.android.com/reference/android/media/MediaRouter.html">MediaRouter</a> API
+ to automatically detect when a
+ presentation display is available and to allow the user to control the media routes using a menu
+ item provided by the 
+ <a href="http://developer.android.com/reference/android/app/MediaRouteActionProvider.html">
+ MediaRouteActionProvider</a>.
+When a presentation display is available a
+ <a href="http://developer.android.com/reference/android/app/Presentation.html">Presentation</a>
+ is shown on the preferred display. A button toggles the background color of the secondary screen
+ to show the interaction between the primary and secondary screens.
+</p>
+<p>
+This sample requires an HDMI or Wifi display. Alternatively, the
+ "Simulate secondary displays" feature in Development Settings can be enabled
+ to simulate secondary displays.
+</p>
+
+
diff --git a/media/BasicMediaRouter/res/drawable-hdpi/ic_launcher.png b/media/BasicMediaRouter/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..2fd4ce4
--- /dev/null
+++ b/media/BasicMediaRouter/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/media/BasicMediaRouter/res/drawable-mdpi/ic_launcher.png b/media/BasicMediaRouter/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..56b78c5
--- /dev/null
+++ b/media/BasicMediaRouter/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/media/BasicMediaRouter/res/drawable-xhdpi/ic_launcher.png b/media/BasicMediaRouter/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..da3db3b
--- /dev/null
+++ b/media/BasicMediaRouter/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/media/BasicMediaRouter/res/drawable-xxhdpi/ic_launcher.png b/media/BasicMediaRouter/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4aa8bdd
--- /dev/null
+++ b/media/BasicMediaRouter/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/media/BasicMediaRouter/res/layout/activity_main.xml b/media/BasicMediaRouter/res/layout/activity_main.xml
new file mode 100644
index 0000000..18565c4
--- /dev/null
+++ b/media/BasicMediaRouter/res/layout/activity_main.xml
@@ -0,0 +1,32 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/LinearLayout1"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center"
+    android:orientation="vertical"
+    tools:context=".MainActivity" >
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="5dp"
+        android:text="@string/intro" />
+
+    <TextView
+        android:id="@+id/textStatus"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:text="@string/secondary_notconnected"
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:layout_margin="5dp" />
+
+    <Button
+        android:id="@+id/button1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:enabled="false"
+        android:text="@string/change_color" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/media/BasicMediaRouter/res/layout/display.xml b/media/BasicMediaRouter/res/layout/display.xml
new file mode 100644
index 0000000..47d5aa9
--- /dev/null
+++ b/media/BasicMediaRouter/res/layout/display.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/display_layout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/display_text"
+        style="@style/DisplayLargeText"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="" />
+
+    <TextView
+        android:id="@+id/display_smalltext"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text=""
+        android:textAppearance="?android:attr/textAppearanceMedium" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/media/BasicMediaRouter/res/menu/main.xml b/media/BasicMediaRouter/res/menu/main.xml
new file mode 100644
index 0000000..ebb6286
--- /dev/null
+++ b/media/BasicMediaRouter/res/menu/main.xml
@@ -0,0 +1,12 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <!-- This ActionProvider is configured to  -->
+    <item
+        android:id="@+id/menu_media_route"
+        android:actionProviderClass="android.app.MediaRouteActionProvider"
+        android:orderInCategory="1"
+        android:showAsAction="always"
+        android:title="@string/menu_present_to"
+        android:visible="true"/>
+
+</menu>
\ No newline at end of file
diff --git a/media/BasicMediaRouter/res/values-v11/styles.xml b/media/BasicMediaRouter/res/values-v11/styles.xml
new file mode 100644
index 0000000..541752f
--- /dev/null
+++ b/media/BasicMediaRouter/res/values-v11/styles.xml
@@ -0,0 +1,11 @@
+<resources>
+
+    <!--
+        Base application theme for API 11+. This theme completely replaces
+        AppBaseTheme from res/values/styles.xml on API 11+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+        <!-- API 11 theme customizations can go here. -->
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/media/BasicMediaRouter/res/values-v14/styles.xml b/media/BasicMediaRouter/res/values-v14/styles.xml
new file mode 100644
index 0000000..f20e015
--- /dev/null
+++ b/media/BasicMediaRouter/res/values-v14/styles.xml
@@ -0,0 +1,12 @@
+<resources>
+
+    <!--
+        Base application theme for API 14+. This theme completely replaces
+        AppBaseTheme from BOTH res/values/styles.xml and
+        res/values-v11/styles.xml on API 14+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+        <!-- API 14 theme customizations can go here. -->
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/media/BasicMediaRouter/res/values/colors.xml b/media/BasicMediaRouter/res/values/colors.xml
new file mode 100644
index 0000000..521d9cd
--- /dev/null
+++ b/media/BasicMediaRouter/res/values/colors.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <item name="blue" type="color">#FF33B5E5</item>
+    <item name="purple" type="color">#FFAA66CC</item>
+    <item name="green" type="color">#FF99CC00</item>
+    <item name="orange" type="color">#FFFFBB33</item>
+    <item name="red" type="color">#FFFF4444</item>
+    <item name="darkblue" type="color">#FF0099CC</item>
+    <item name="darkpurple" type="color">#FF9933CC</item>
+    <item name="darkgreen" type="color">#FF669900</item>
+    <item name="darkorange" type="color">#FFFF8800</item>
+    <item name="darkred" type="color">#FFCC0000</item>
+
+    <integer-array name="androidcolors">
+        <item>@color/blue</item>
+        <item>@color/purple</item>
+        <item>@color/green</item>
+        <item>@color/orange</item>
+        <item>@color/red</item>
+        <item>@color/darkblue</item>
+        <item>@color/darkpurple</item>
+        <item>@color/darkgreen</item>
+        <item>@color/darkorange</item>
+        <item>@color/darkred</item>
+    </integer-array>
+
+</resources> 
\ No newline at end of file
diff --git a/media/BasicMediaRouter/res/values/strings.xml b/media/BasicMediaRouter/res/values/strings.xml
new file mode 100644
index 0000000..ca9e53f
--- /dev/null
+++ b/media/BasicMediaRouter/res/values/strings.xml
@@ -0,0 +1,19 @@
+<resources>
+
+    <string name="menu_present_to">Present to</string>
+    <string name="app_name">BasicMediaRouter Sample</string>
+    <string name="title_activity_main">MainActivity</string>
+    <string name="intro">This sample demonstrates the use of the MediaRouter API to display
+ content on a secondary display.\n\nUse the <b>Media Route Action Item</b> in the ActionBar
+ to select an output device. If your device supports Miracast wireless displays,
+ you may need to enable <b>Wireless Display</b> functionality in the system settings.
+ Secondary screen simulation can also be enabled from the <b>Developer Options</b>.\n\n
+Once connected, use the <b>Change Color</b> button to change the background color of the secondary screen.
+</string>
+    <string name="secondary_connected">Connected to:\n%s</string>
+    <string name="secondary_notconnected">No secondary display connected.</string>
+    <string name="change_color">Change Color</string>
+    <string name="display_name">This display is: %s</string>
+    <string name="display_color">Background color: #%X</string>
+
+</resources>
\ No newline at end of file
diff --git a/media/BasicMediaRouter/res/values/styles.xml b/media/BasicMediaRouter/res/values/styles.xml
new file mode 100644
index 0000000..05c67f3
--- /dev/null
+++ b/media/BasicMediaRouter/res/values/styles.xml
@@ -0,0 +1,26 @@
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Light">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="AppBaseTheme">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+
+    <style name="DisplayLargeText">
+        <item name="android:textSize">30sp</item>
+        <item name="android:textStyle">bold</item>
+        <item name="android:textColor">#FFFFFF</item>
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/media/BasicMediaRouter/src/com/example/android/media/basicmediarouter/MainActivity.java b/media/BasicMediaRouter/src/com/example/android/media/basicmediarouter/MainActivity.java
new file mode 100644
index 0000000..ccf6ad0
--- /dev/null
+++ b/media/BasicMediaRouter/src/com/example/android/media/basicmediarouter/MainActivity.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2013 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 com.example.android.media.basicmediarouter;
+
+import android.app.Activity;
+import android.app.MediaRouteActionProvider;
+import android.app.Presentation;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.media.MediaRouter;
+import android.media.MediaRouter.RouteInfo;
+import android.os.Bundle;
+import android.view.Display;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.example.android.output.mediaroutersample.R;
+
+/**
+ * <p>
+ * This sample demonstrates the use of the MediaRouter API to show content on a
+ * secondary display using a {@link Presentation}.
+ * </p>
+ * <p>
+ * The activity uses the {@link MediaRouter} API to automatically detect when a
+ * presentation display is available and to allow the user to control the media
+ * routes using a menu item provided by the {@link MediaRouteActionProvider}.
+ * When a presentation display is available a {@link Presentation} (implemented
+ * as a {@link SamplePresentation}) is shown on the preferred display. A button
+ * toggles the background color of the secondary screen to show the interaction
+ * between the primary and secondary screens.
+ * </p>
+ * <p>
+ * This sample requires an HDMI or Wifi display. Alternatively, the
+ * "Simulate secondary displays" feature in Development Settings can be enabled
+ * to simulate secondary displays.
+ * </p>
+ *
+ * @see Presentation
+ * @see MediaRouter
+ */
+public class MainActivity extends Activity {
+
+    private MediaRouter mMediaRouter;
+
+    // Active Presentation, set to null if no secondary screen is enabled
+    private SamplePresentation mPresentation;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.activity_main);
+        mTextStatus = (TextView) findViewById(R.id.textStatus);
+
+        // get the list of background colors
+        mColors = getResources().getIntArray(R.array.androidcolors);
+
+        // Enable clicks on the 'change color' button
+        mButton = (Button) findViewById(R.id.button1);
+        mButton.setOnClickListener(new View.OnClickListener() {
+
+            @Override
+            public void onClick(View v) {
+                showNextColor();
+            }
+        });
+
+        // BEGIN_INCLUDE(getMediaRouter)
+        // Get the MediaRouter service
+        mMediaRouter = (MediaRouter) getSystemService(Context.MEDIA_ROUTER_SERVICE);
+        // END_INCLUDE(getMediaRouter)
+    }
+
+    /**
+     * Implementing a {@link MediaRouter.Callback} to update the displayed
+     * {@link Presentation} when a route is selected, unselected or the
+     * presentation display has changed. The provided stub implementation
+     * {@link MediaRouter.SimpleCallback} is extended and only
+     * {@link MediaRouter.SimpleCallback#onRouteSelected(MediaRouter, int, RouteInfo)}
+     * ,
+     * {@link MediaRouter.SimpleCallback#onRouteUnselected(MediaRouter, int, RouteInfo)}
+     * and
+     * {@link MediaRouter.SimpleCallback#onRoutePresentationDisplayChanged(MediaRouter, RouteInfo)}
+     * are overridden to update the displayed {@link Presentation} in
+     * {@link #updatePresentation()}. These callbacks enable or disable the
+     * second screen presentation based on the routing provided by the
+     * {@link MediaRouter} for {@link MediaRouter#ROUTE_TYPE_LIVE_VIDEO}
+     * streams. @
+     */
+    private final MediaRouter.SimpleCallback mMediaRouterCallback =
+            new MediaRouter.SimpleCallback() {
+
+                // BEGIN_INCLUDE(SimpleCallback)
+                /**
+                 * A new route has been selected as active. Disable the current
+                 * route and enable the new one.
+                 */
+                @Override
+                public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
+                    updatePresentation();
+                }
+
+                /**
+                 * The route has been unselected.
+                 */
+                @Override
+                public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
+                    updatePresentation();
+
+                }
+
+                /**
+                 * The route's presentation display has changed. This callback
+                 * is called when the presentation has been activated, removed
+                 * or its properties have changed.
+                 */
+                @Override
+                public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo info) {
+                    updatePresentation();
+                }
+                // END_INCLUDE(SimpleCallback)
+            };
+
+    /**
+     * Updates the displayed presentation to enable a secondary screen if it has
+     * been selected in the {@link MediaRouter} for the
+     * {@link MediaRouter#ROUTE_TYPE_LIVE_VIDEO} type. If no screen has been
+     * selected by the {@link MediaRouter}, the current screen is disabled.
+     * Otherwise a new {@link SamplePresentation} is initialized and shown on
+     * the secondary screen.
+     */
+    private void updatePresentation() {
+
+        // BEGIN_INCLUDE(updatePresentationInit)
+        // Get the selected route for live video
+        MediaRouter.RouteInfo selectedRoute = mMediaRouter.getSelectedRoute(
+                MediaRouter.ROUTE_TYPE_LIVE_VIDEO);
+
+        // Get its Display if a valid route has been selected
+        Display selectedDisplay = null;
+        if (selectedRoute != null) {
+            selectedDisplay = selectedRoute.getPresentationDisplay();
+        }
+        // END_INCLUDE(updatePresentationInit)
+
+        // BEGIN_INCLUDE(updatePresentationDismiss)
+        /*
+         * Dismiss the current presentation if the display has changed or no new
+         * route has been selected
+         */
+        if (mPresentation != null && mPresentation.getDisplay() != selectedDisplay) {
+            mPresentation.dismiss();
+            mPresentation = null;
+            mButton.setEnabled(false);
+            mTextStatus.setText(R.string.secondary_notconnected);
+        }
+        // END_INCLUDE(updatePresentationDismiss)
+
+        // BEGIN_INCLUDE(updatePresentationNew)
+        /*
+         * Show a new presentation if the previous one has been dismissed and a
+         * route has been selected.
+         */
+        if (mPresentation == null && selectedDisplay != null) {
+
+            // Initialise a new Presentation for the Display
+            mPresentation = new SamplePresentation(this, selectedDisplay);
+            mPresentation.setOnDismissListener(mOnDismissListener);
+
+            // Try to show the presentation, this might fail if the display has
+            // gone away in the mean time
+            try {
+                mPresentation.show();
+                mTextStatus.setText(getResources().getString(R.string.secondary_connected,
+                        selectedRoute.getName(MainActivity.this)));
+                mButton.setEnabled(true);
+                showNextColor();
+            } catch (WindowManager.InvalidDisplayException ex) {
+                // Couldn't show presentation - display was already removed
+                mPresentation = null;
+            }
+        }
+        // END_INCLUDE(updatePresentationNew)
+
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        // BEGIN_INCLUDE(addCallback)
+        // Register a callback for all events related to live video devices
+        mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_LIVE_VIDEO, mMediaRouterCallback);
+        // END_INCLUDE(addCallback)
+
+        // Show the 'Not connected' status message
+        mButton.setEnabled(false);
+        mTextStatus.setText(R.string.secondary_notconnected);
+
+        // Update the displays based on the currently active routes
+        updatePresentation();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        // BEGIN_INCLUDE(onPause)
+        // Stop listening for changes to media routes.
+        mMediaRouter.removeCallback(mMediaRouterCallback);
+        // END_INCLUDE(onPause)
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+
+        // BEGIN_INCLUDE(onStop)
+        // Dismiss the presentation when the activity is not visible.
+        if (mPresentation != null) {
+            mPresentation.dismiss();
+            mPresentation = null;
+        }
+        // BEGIN_INCLUDE(onStop)
+    }
+
+    /**
+     * Inflates the ActionBar or options menu. The menu file defines an item for
+     * the {@link MediaRouteActionProvider}, which is registered here for all
+     * live video devices using {@link MediaRouter#ROUTE_TYPE_LIVE_VIDEO}.
+     */
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+
+        getMenuInflater().inflate(R.menu.main, menu);
+
+        // BEGIN_INCLUDE(MediaRouteActionProvider)
+        // Configure the media router action provider
+        MenuItem mediaRouteMenuItem = menu.findItem(R.id.menu_media_route);
+        MediaRouteActionProvider mediaRouteActionProvider =
+                (MediaRouteActionProvider) mediaRouteMenuItem.getActionProvider();
+        mediaRouteActionProvider.setRouteTypes(MediaRouter.ROUTE_TYPE_LIVE_VIDEO);
+        // BEGIN_INCLUDE(MediaRouteActionProvider)
+
+        return true;
+    }
+
+    /**
+     * Listens for dismissal of the {@link SamplePresentation} and removes its
+     * reference.
+     */
+    private final DialogInterface.OnDismissListener mOnDismissListener =
+            new DialogInterface.OnDismissListener() {
+                @Override
+                public void onDismiss(DialogInterface dialog) {
+                    if (dialog == mPresentation) {
+                        mPresentation = null;
+                    }
+                }
+            };
+
+    // Views used to display status information on the primary screen
+    private TextView mTextStatus;
+    private Button mButton;
+
+    // selected color index
+    private int mColor = 0;
+
+    // background colors
+    public int[] mColors;
+
+    /**
+     * Displays the next color on the secondary screen if it is activate.
+     */
+    private void showNextColor() {
+        if (mPresentation != null) {
+            // a second screen is active and initialized, show the next color
+            mPresentation.setColor(mColors[mColor]);
+            mColor = (mColor + 1) % mColors.length;
+        }
+    }
+
+}
diff --git a/media/BasicMediaRouter/src/com/example/android/media/basicmediarouter/SamplePresentation.java b/media/BasicMediaRouter/src/com/example/android/media/basicmediarouter/SamplePresentation.java
new file mode 100644
index 0000000..0938635
--- /dev/null
+++ b/media/BasicMediaRouter/src/com/example/android/media/basicmediarouter/SamplePresentation.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2013 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 com.example.android.media.basicmediarouter;
+
+import android.app.Presentation;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.Display;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.example.android.output.mediaroutersample.R;
+
+/**
+ * <p>
+ * A {@link Presentation} used to demonstrate interaction between primary and
+ * secondary screens.
+ * </p>
+ * <p>
+ * It displays the name of the display in which it has been embedded (see
+ * {@link Presentation#getDisplay()}) and exposes a facility to change its
+ * background color and display its text.
+ * </p>
+ */
+public class SamplePresentation extends Presentation {
+
+    private LinearLayout mLayout;
+    private TextView mText;
+
+    public SamplePresentation(Context outerContext, Display display) {
+        super(outerContext, display);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Set the content view to the custom layout
+        setContentView(R.layout.display);
+
+        // Get the Views
+        mLayout = (LinearLayout) findViewById(R.id.display_layout);
+        mText = (TextView) findViewById(R.id.display_text);
+
+        /*
+         * Show the name of the display this presentation was embedded in.
+         */
+        TextView smallText = (TextView) findViewById(R.id.display_smalltext);
+        final String name = getDisplay().getName();
+        smallText.setText(getResources().getString(R.string.display_name, name));
+    }
+
+    /**
+     * Set the background color of the layout and display the color as a String.
+     *
+     * @param color The background color
+     */
+    public void setColor(int color) {
+        mLayout.setBackgroundColor(color);
+
+        // Display the color as a string on screen
+        String s = getResources().getString(R.string.display_color, color);
+        mText.setText(s);
+    }
+
+}