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 android.app;
     18 
     19 import com.android.internal.app.MediaRouteChooserDialogFragment;
     20 
     21 import android.content.Context;
     22 import android.content.ContextWrapper;
     23 import android.media.MediaRouter;
     24 import android.media.MediaRouter.RouteInfo;
     25 import android.util.Log;
     26 import android.view.ActionProvider;
     27 import android.view.MenuItem;
     28 import android.view.View;
     29 
     30 import java.lang.ref.WeakReference;
     31 
     32 public class MediaRouteActionProvider extends ActionProvider {
     33     private static final String TAG = "MediaRouteActionProvider";
     34 
     35     private Context mContext;
     36     private MediaRouter mRouter;
     37     private MenuItem mMenuItem;
     38     private MediaRouteButton mView;
     39     private int mRouteTypes;
     40     private View.OnClickListener mExtendedSettingsListener;
     41     private RouterCallback mCallback;
     42 
     43     public MediaRouteActionProvider(Context context) {
     44         super(context);
     45         mContext = context;
     46         mRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
     47         mCallback = new RouterCallback(this);
     48 
     49         // Start with live audio by default.
     50         // TODO Update this when new route types are added; segment by API level
     51         // when different route types were added.
     52         setRouteTypes(MediaRouter.ROUTE_TYPE_LIVE_AUDIO);
     53     }
     54 
     55     public void setRouteTypes(int types) {
     56         if (mRouteTypes == types) return;
     57         if (mRouteTypes != 0) {
     58             mRouter.removeCallback(mCallback);
     59         }
     60         mRouteTypes = types;
     61         if (types != 0) {
     62             mRouter.addCallback(types, mCallback);
     63         }
     64         if (mView != null) {
     65             mView.setRouteTypes(mRouteTypes);
     66         }
     67     }
     68 
     69     @Override
     70     public View onCreateActionView() {
     71         throw new UnsupportedOperationException("Use onCreateActionView(MenuItem) instead.");
     72     }
     73 
     74     @Override
     75     public View onCreateActionView(MenuItem item) {
     76         if (mMenuItem != null || mView != null) {
     77             Log.e(TAG, "onCreateActionView: this ActionProvider is already associated " +
     78                     "with a menu item. Don't reuse MediaRouteActionProvider instances! " +
     79                     "Abandoning the old one...");
     80         }
     81         mMenuItem = item;
     82         mView = new MediaRouteButton(mContext);
     83         mView.setRouteTypes(mRouteTypes);
     84         mView.setExtendedSettingsClickListener(mExtendedSettingsListener);
     85         return mView;
     86     }
     87 
     88     @Override
     89     public boolean onPerformDefaultAction() {
     90         final FragmentManager fm = getActivity().getFragmentManager();
     91         // See if one is already attached to this activity.
     92         MediaRouteChooserDialogFragment dialogFragment =
     93                 (MediaRouteChooserDialogFragment) fm.findFragmentByTag(
     94                 MediaRouteChooserDialogFragment.FRAGMENT_TAG);
     95         if (dialogFragment != null) {
     96             Log.w(TAG, "onPerformDefaultAction(): Chooser dialog already showing!");
     97             return false;
     98         }
     99 
    100         dialogFragment = new MediaRouteChooserDialogFragment();
    101         dialogFragment.setExtendedSettingsClickListener(mExtendedSettingsListener);
    102         dialogFragment.setRouteTypes(mRouteTypes);
    103         dialogFragment.show(fm, MediaRouteChooserDialogFragment.FRAGMENT_TAG);
    104         return true;
    105     }
    106 
    107     private Activity getActivity() {
    108         // Gross way of unwrapping the Activity so we can get the FragmentManager
    109         Context context = mContext;
    110         while (context instanceof ContextWrapper && !(context instanceof Activity)) {
    111             context = ((ContextWrapper) context).getBaseContext();
    112         }
    113         if (!(context instanceof Activity)) {
    114             throw new IllegalStateException("The MediaRouteActionProvider's Context " +
    115                     "is not an Activity.");
    116         }
    117 
    118         return (Activity) context;
    119     }
    120 
    121     public void setExtendedSettingsClickListener(View.OnClickListener listener) {
    122         mExtendedSettingsListener = listener;
    123         if (mView != null) {
    124             mView.setExtendedSettingsClickListener(listener);
    125         }
    126     }
    127 
    128     @Override
    129     public boolean overridesItemVisibility() {
    130         return true;
    131     }
    132 
    133     @Override
    134     public boolean isVisible() {
    135         return mRouter.getRouteCount() > 1;
    136     }
    137 
    138     private static class RouterCallback extends MediaRouter.SimpleCallback {
    139         private WeakReference<MediaRouteActionProvider> mAp;
    140 
    141         RouterCallback(MediaRouteActionProvider ap) {
    142             mAp = new WeakReference<MediaRouteActionProvider>(ap);
    143         }
    144 
    145         @Override
    146         public void onRouteAdded(MediaRouter router, RouteInfo info) {
    147             final MediaRouteActionProvider ap = mAp.get();
    148             if (ap == null) {
    149                 router.removeCallback(this);
    150                 return;
    151             }
    152 
    153             ap.refreshVisibility();
    154         }
    155 
    156         @Override
    157         public void onRouteRemoved(MediaRouter router, RouteInfo info) {
    158             final MediaRouteActionProvider ap = mAp.get();
    159             if (ap == null) {
    160                 router.removeCallback(this);
    161                 return;
    162             }
    163 
    164             ap.refreshVisibility();
    165         }
    166     }
    167 }
    168