Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.example.android.apis.app;
     18 
     19 import com.example.android.apis.R;
     20 import com.example.android.apis.graphics.CubeRenderer;
     21 
     22 import android.app.Activity;
     23 import android.app.MediaRouteActionProvider;
     24 import android.app.Presentation;
     25 import android.content.Context;
     26 import android.content.DialogInterface;
     27 import android.content.res.Resources;
     28 import android.media.MediaRouter;
     29 import android.media.MediaRouter.RouteInfo;
     30 import android.opengl.GLSurfaceView;
     31 import android.os.Bundle;
     32 import android.util.Log;
     33 import android.view.Display;
     34 import android.view.Menu;
     35 import android.view.MenuItem;
     36 import android.view.View;
     37 import android.view.WindowManager;
     38 import android.widget.TextView;
     39 
     40 //BEGIN_INCLUDE(activity)
     41 /**
     42  * <h3>Presentation Activity</h3>
     43  *
     44  * <p>
     45  * This demonstrates how to create an activity that shows some content
     46  * on a secondary display using a {@link Presentation}.
     47  * </p><p>
     48  * The activity uses the {@link MediaRouter} API to automatically detect when
     49  * a presentation display is available and to allow the user to control the
     50  * media routes using a menu item.  When a presentation display is available,
     51  * we stop showing content in the main activity and instead open up a
     52  * {@link Presentation} on the preferred presentation display.  When a presentation
     53  * display is removed, we revert to showing content in the main activity.
     54  * We also write information about displays and display-related events to
     55  * the Android log which you can read using <code>adb logcat</code>.
     56  * </p><p>
     57  * You can try this out using an HDMI or Wifi display or by using the
     58  * "Simulate secondary displays" feature in Development Settings to create a few
     59  * simulated secondary displays.  Each display will appear in the list along with a
     60  * checkbox to show a presentation on that display.
     61  * </p><p>
     62  * See also the {@link PresentationActivity} sample which
     63  * uses the low-level display manager to enumerate displays and to show multiple
     64  * simultaneous presentations on different displays.
     65  * </p>
     66  */
     67 public class PresentationWithMediaRouterActivity extends Activity {
     68     private final String TAG = "PresentationWithMediaRouterActivity";
     69 
     70     private MediaRouter mMediaRouter;
     71     private DemoPresentation mPresentation;
     72     private GLSurfaceView mSurfaceView;
     73     private TextView mInfoTextView;
     74     private boolean mPaused;
     75 
     76     /**
     77      * Initialization of the Activity after it is first created.  Must at least
     78      * call {@link android.app.Activity#setContentView setContentView()} to
     79      * describe what is to be displayed in the screen.
     80      */
     81     @Override
     82     protected void onCreate(Bundle savedInstanceState) {
     83         // Be sure to call the super class.
     84         super.onCreate(savedInstanceState);
     85 
     86         // Get the media router service.
     87         mMediaRouter = (MediaRouter)getSystemService(Context.MEDIA_ROUTER_SERVICE);
     88 
     89         // See assets/res/any/layout/presentation_with_media_router_activity.xml for this
     90         // view layout definition, which is being set here as
     91         // the content of our screen.
     92         setContentView(R.layout.presentation_with_media_router_activity);
     93 
     94         // Set up the surface view for visual interest.
     95         mSurfaceView = (GLSurfaceView)findViewById(R.id.surface_view);
     96         mSurfaceView.setRenderer(new CubeRenderer(false));
     97 
     98         // Get a text view where we will show information about what's happening.
     99         mInfoTextView = (TextView)findViewById(R.id.info);
    100     }
    101 
    102     @Override
    103     protected void onResume() {
    104         // Be sure to call the super class.
    105         super.onResume();
    106 
    107         // Listen for changes to media routes.
    108         mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_LIVE_VIDEO, mMediaRouterCallback);
    109 
    110         // Update the presentation based on the currently selected route.
    111         mPaused = false;
    112         updatePresentation();
    113     }
    114 
    115     @Override
    116     protected void onPause() {
    117         // Be sure to call the super class.
    118         super.onPause();
    119 
    120         // Stop listening for changes to media routes.
    121         mMediaRouter.removeCallback(mMediaRouterCallback);
    122 
    123         // Pause rendering.
    124         mPaused = true;
    125         updateContents();
    126     }
    127 
    128     @Override
    129     protected void onStop() {
    130         // Be sure to call the super class.
    131         super.onStop();
    132 
    133         // Dismiss the presentation when the activity is not visible.
    134         if (mPresentation != null) {
    135             Log.i(TAG, "Dismissing presentation because the activity is no longer visible.");
    136             mPresentation.dismiss();
    137             mPresentation = null;
    138         }
    139     }
    140 
    141     @Override
    142     public boolean onCreateOptionsMenu(Menu menu) {
    143         // Be sure to call the super class.
    144         super.onCreateOptionsMenu(menu);
    145 
    146         // Inflate the menu and configure the media router action provider.
    147         getMenuInflater().inflate(R.menu.presentation_with_media_router_menu, menu);
    148 
    149         MenuItem mediaRouteMenuItem = menu.findItem(R.id.menu_media_route);
    150         MediaRouteActionProvider mediaRouteActionProvider =
    151                 (MediaRouteActionProvider)mediaRouteMenuItem.getActionProvider();
    152         mediaRouteActionProvider.setRouteTypes(MediaRouter.ROUTE_TYPE_LIVE_VIDEO);
    153 
    154         // Return true to show the menu.
    155         return true;
    156     }
    157 
    158     private void updatePresentation() {
    159         // Get the current route and its presentation display.
    160         MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(
    161                 MediaRouter.ROUTE_TYPE_LIVE_VIDEO);
    162         Display presentationDisplay = route != null ? route.getPresentationDisplay() : null;
    163 
    164         // Dismiss the current presentation if the display has changed.
    165         if (mPresentation != null && mPresentation.getDisplay() != presentationDisplay) {
    166             Log.i(TAG, "Dismissing presentation because the current route no longer "
    167                     + "has a presentation display.");
    168             mPresentation.dismiss();
    169             mPresentation = null;
    170         }
    171 
    172         // Show a new presentation if needed.
    173         if (mPresentation == null && presentationDisplay != null) {
    174             Log.i(TAG, "Showing presentation on display: " + presentationDisplay);
    175             mPresentation = new DemoPresentation(this, presentationDisplay);
    176             mPresentation.setOnDismissListener(mOnDismissListener);
    177             try {
    178                 mPresentation.show();
    179             } catch (WindowManager.InvalidDisplayException ex) {
    180                 Log.w(TAG, "Couldn't show presentation!  Display was removed in "
    181                         + "the meantime.", ex);
    182                 mPresentation = null;
    183             }
    184         }
    185 
    186         // Update the contents playing in this activity.
    187         updateContents();
    188     }
    189 
    190     private void updateContents() {
    191         // Show either the content in the main activity or the content in the presentation
    192         // along with some descriptive text about what is happening.
    193         if (mPresentation != null) {
    194             mInfoTextView.setText(getResources().getString(
    195                     R.string.presentation_with_media_router_now_playing_remotely,
    196                     mPresentation.getDisplay().getName()));
    197             mSurfaceView.setVisibility(View.INVISIBLE);
    198             mSurfaceView.onPause();
    199             if (mPaused) {
    200                 mPresentation.getSurfaceView().onPause();
    201             } else {
    202                 mPresentation.getSurfaceView().onResume();
    203             }
    204         } else {
    205             mInfoTextView.setText(getResources().getString(
    206                     R.string.presentation_with_media_router_now_playing_locally,
    207                     getWindowManager().getDefaultDisplay().getName()));
    208             mSurfaceView.setVisibility(View.VISIBLE);
    209             if (mPaused) {
    210                 mSurfaceView.onPause();
    211             } else {
    212                 mSurfaceView.onResume();
    213             }
    214         }
    215     }
    216 
    217     private final MediaRouter.SimpleCallback mMediaRouterCallback =
    218             new MediaRouter.SimpleCallback() {
    219         @Override
    220         public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
    221             Log.d(TAG, "onRouteSelected: type=" + type + ", info=" + info);
    222             updatePresentation();
    223         }
    224 
    225         @Override
    226         public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
    227             Log.d(TAG, "onRouteUnselected: type=" + type + ", info=" + info);
    228             updatePresentation();
    229         }
    230 
    231         @Override
    232         public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo info) {
    233             Log.d(TAG, "onRoutePresentationDisplayChanged: info=" + info);
    234             updatePresentation();
    235         }
    236     };
    237 
    238     /**
    239      * Listens for when presentations are dismissed.
    240      */
    241     private final DialogInterface.OnDismissListener mOnDismissListener =
    242             new DialogInterface.OnDismissListener() {
    243         @Override
    244         public void onDismiss(DialogInterface dialog) {
    245             if (dialog == mPresentation) {
    246                 Log.i(TAG, "Presentation was dismissed.");
    247                 mPresentation = null;
    248                 updateContents();
    249             }
    250         }
    251     };
    252 
    253     /**
    254      * The presentation to show on the secondary display.
    255      * <p>
    256      * Note that this display may have different metrics from the display on which
    257      * the main activity is showing so we must be careful to use the presentation's
    258      * own {@link Context} whenever we load resources.
    259      * </p>
    260      */
    261     private final static class DemoPresentation extends Presentation {
    262         private GLSurfaceView mSurfaceView;
    263 
    264         public DemoPresentation(Context context, Display display) {
    265             super(context, display);
    266         }
    267 
    268         @Override
    269         protected void onCreate(Bundle savedInstanceState) {
    270             // Be sure to call the super class.
    271             super.onCreate(savedInstanceState);
    272 
    273             // Get the resources for the context of the presentation.
    274             // Notice that we are getting the resources from the context of the presentation.
    275             Resources r = getContext().getResources();
    276 
    277             // Inflate the layout.
    278             setContentView(R.layout.presentation_with_media_router_content);
    279 
    280             // Set up the surface view for visual interest.
    281             mSurfaceView = (GLSurfaceView)findViewById(R.id.surface_view);
    282             mSurfaceView.setRenderer(new CubeRenderer(false));
    283         }
    284 
    285         public GLSurfaceView getSurfaceView() {
    286             return mSurfaceView;
    287         }
    288     }
    289 }
    290 //END_INCLUDE(activity)
    291