/* * Copyright (C) 2012 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.apis.app; import com.example.android.apis.R; import com.example.android.apis.graphics.CubeRenderer; import android.app.Activity; import android.app.MediaRouteActionProvider; import android.app.Presentation; import android.content.Context; import android.content.DialogInterface; import android.content.res.Resources; import android.media.MediaRouter; import android.media.MediaRouter.RouteInfo; import android.opengl.GLSurfaceView; import android.os.Bundle; import android.util.Log; import android.view.Display; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.WindowManager; import android.widget.TextView; /** * <h3>Presentation Activity</h3> * * <p> * This demonstrates how to create an activity that shows some 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. When a presentation display is available, * we stop showing content in the main activity and instead open up a * {@link Presentation} on the preferred presentation display. When a presentation * display is removed, we revert to showing content in the main activity. * We also write information about displays and display-related events to * the Android log which you can read using <code>adb logcat</code>. * </p><p> * You can try this out using an HDMI or Wifi display or by using the * "Simulate secondary displays" feature in Development Settings to create a few * simulated secondary displays. Each display will appear in the list along with a * checkbox to show a presentation on that display. * </p><p> * See also the {@link PresentationActivity} sample which * uses the low-level display manager to enumerate displays and to show multiple * simultaneous presentations on different displays. * </p> */ public class PresentationWithMediaRouterActivity extends Activity { private final String TAG = "PresentationWithMediaRouterActivity"; private MediaRouter mMediaRouter; private DemoPresentation mPresentation; private GLSurfaceView mSurfaceView; private TextView mInfoTextView; private boolean mPaused; /** * Initialization of the Activity after it is first created. Must at least * call {@link android.app.Activity#setContentView setContentView()} to * describe what is to be displayed in the screen. */ @Override protected void onCreate(Bundle savedInstanceState) { // Be sure to call the super class. super.onCreate(savedInstanceState); // Get the media router service. mMediaRouter = (MediaRouter)getSystemService(Context.MEDIA_ROUTER_SERVICE); // See assets/res/any/layout/presentation_with_media_router_activity.xml for this // view layout definition, which is being set here as // the content of our screen. setContentView(R.layout.presentation_with_media_router_activity); // Set up the surface view for visual interest. mSurfaceView = (GLSurfaceView)findViewById(R.id.surface_view); mSurfaceView.setRenderer(new CubeRenderer(false)); // Get a text view where we will show information about what's happening. mInfoTextView = (TextView)findViewById(R.id.info); } @Override protected void onResume() { // Be sure to call the super class. super.onResume(); // Listen for changes to media routes. mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_LIVE_VIDEO, mMediaRouterCallback); // Update the presentation based on the currently selected route. mPaused = false; updatePresentation(); } @Override protected void onPause() { // Be sure to call the super class. super.onPause(); // Stop listening for changes to media routes. mMediaRouter.removeCallback(mMediaRouterCallback); // Pause rendering. mPaused = true; updateContents(); } @Override protected void onStop() { // Be sure to call the super class. super.onStop(); // Dismiss the presentation when the activity is not visible. if (mPresentation != null) { Log.i(TAG, "Dismissing presentation because the activity is no longer visible."); mPresentation.dismiss(); mPresentation = null; } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Be sure to call the super class. super.onCreateOptionsMenu(menu); // Inflate the menu and configure the media router action provider. getMenuInflater().inflate(R.menu.presentation_with_media_router_menu, menu); MenuItem mediaRouteMenuItem = menu.findItem(R.id.menu_media_route); MediaRouteActionProvider mediaRouteActionProvider = (MediaRouteActionProvider)mediaRouteMenuItem.getActionProvider(); mediaRouteActionProvider.setRouteTypes(MediaRouter.ROUTE_TYPE_LIVE_VIDEO); // Return true to show the menu. return true; } private void updatePresentation() { // Get the current route and its presentation display. MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute( MediaRouter.ROUTE_TYPE_LIVE_VIDEO); Display presentationDisplay = route != null ? route.getPresentationDisplay() : null; // Dismiss the current presentation if the display has changed. if (mPresentation != null && mPresentation.getDisplay() != presentationDisplay) { Log.i(TAG, "Dismissing presentation because the current route no longer " + "has a presentation display."); mPresentation.dismiss(); mPresentation = null; } // Show a new presentation if needed. if (mPresentation == null && presentationDisplay != null) { Log.i(TAG, "Showing presentation on display: " + presentationDisplay); mPresentation = new DemoPresentation(this, presentationDisplay); mPresentation.setOnDismissListener(mOnDismissListener); try { mPresentation.show(); } catch (WindowManager.InvalidDisplayException ex) { Log.w(TAG, "Couldn't show presentation! Display was removed in " + "the meantime.", ex); mPresentation = null; } } // Update the contents playing in this activity. updateContents(); } private void updateContents() { // Show either the content in the main activity or the content in the presentation // along with some descriptive text about what is happening. if (mPresentation != null) { mInfoTextView.setText(getResources().getString( R.string.presentation_with_media_router_now_playing_remotely, mPresentation.getDisplay().getName())); mSurfaceView.setVisibility(View.INVISIBLE); mSurfaceView.onPause(); if (mPaused) { mPresentation.getSurfaceView().onPause(); } else { mPresentation.getSurfaceView().onResume(); } } else { mInfoTextView.setText(getResources().getString( R.string.presentation_with_media_router_now_playing_locally, getWindowManager().getDefaultDisplay().getName())); mSurfaceView.setVisibility(View.VISIBLE); if (mPaused) { mSurfaceView.onPause(); } else { mSurfaceView.onResume(); } } } private final MediaRouter.SimpleCallback mMediaRouterCallback = new MediaRouter.SimpleCallback() { @Override public void onRouteSelected(MediaRouter router, int type, RouteInfo info) { Log.d(TAG, "onRouteSelected: type=" + type + ", info=" + info); updatePresentation(); } @Override public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) { Log.d(TAG, "onRouteUnselected: type=" + type + ", info=" + info); updatePresentation(); } @Override public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo info) { Log.d(TAG, "onRoutePresentationDisplayChanged: info=" + info); updatePresentation(); } }; /** * Listens for when presentations are dismissed. */ private final DialogInterface.OnDismissListener mOnDismissListener = new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { if (dialog == mPresentation) { Log.i(TAG, "Presentation was dismissed."); mPresentation = null; updateContents(); } } }; /** * The presentation to show on the secondary display. * <p> * Note that this display may have different metrics from the display on which * the main activity is showing so we must be careful to use the presentation's * own {@link Context} whenever we load resources. * </p> */ private final static class DemoPresentation extends Presentation { private GLSurfaceView mSurfaceView; public DemoPresentation(Context context, Display display) { super(context, display); } @Override protected void onCreate(Bundle savedInstanceState) { // Be sure to call the super class. super.onCreate(savedInstanceState); // Get the resources for the context of the presentation. // Notice that we are getting the resources from the context of the presentation. Resources r = getContext().getResources(); // Inflate the layout. setContentView(R.layout.presentation_with_media_router_content); // Set up the surface view for visual interest. mSurfaceView = (GLSurfaceView)findViewById(R.id.surface_view); mSurfaceView.setRenderer(new CubeRenderer(false)); } public GLSurfaceView getSurfaceView() { return mSurfaceView; } } }