• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
MediaRouteActionProvider(Context context)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 
setRouteTypes(int types)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
onCreateActionView()70     public View onCreateActionView() {
71         throw new UnsupportedOperationException("Use onCreateActionView(MenuItem) instead.");
72     }
73 
74     @Override
onCreateActionView(MenuItem item)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
onPerformDefaultAction()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 
getActivity()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 
setExtendedSettingsClickListener(View.OnClickListener listener)121     public void setExtendedSettingsClickListener(View.OnClickListener listener) {
122         mExtendedSettingsListener = listener;
123         if (mView != null) {
124             mView.setExtendedSettingsClickListener(listener);
125         }
126     }
127 
128     @Override
overridesItemVisibility()129     public boolean overridesItemVisibility() {
130         return true;
131     }
132 
133     @Override
isVisible()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 
RouterCallback(MediaRouteActionProvider ap)141         RouterCallback(MediaRouteActionProvider ap) {
142             mAp = new WeakReference<MediaRouteActionProvider>(ap);
143         }
144 
145         @Override
onRouteAdded(MediaRouter router, RouteInfo info)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
onRouteRemoved(MediaRouter router, RouteInfo info)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