OSDN Git Service

libmedia_jni.so doesn't need libjhead.so am: 9a4a34afd8 -s ours am: 398d50feeb ...
[android-x86/frameworks-base.git] / core / java / android / app / MediaRouteActionProvider.java
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 android.content.Context;
20 import android.media.MediaRouter;
21 import android.media.MediaRouter.RouteInfo;
22 import android.util.Log;
23 import android.view.ActionProvider;
24 import android.view.MenuItem;
25 import android.view.View;
26 import android.view.ViewGroup;
27
28 import java.lang.ref.WeakReference;
29
30 /**
31  * The media route action provider displays a {@link MediaRouteButton media route button}
32  * in the application's {@link ActionBar} to allow the user to select routes and
33  * to control the currently selected route.
34  * <p>
35  * The application must specify the kinds of routes that the user should be allowed
36  * to select by specifying the route types with the {@link #setRouteTypes} method.
37  * </p><p>
38  * Refer to {@link MediaRouteButton} for a description of the button that will
39  * appear in the action bar menu.  Note that instead of disabling the button
40  * when no routes are available, the action provider will instead make the
41  * menu item invisible.  In this way, the button will only be visible when it
42  * is possible for the user to discover and select a matching route.
43  * </p>
44  */
45 public class MediaRouteActionProvider extends ActionProvider {
46     private static final String TAG = "MediaRouteActionProvider";
47
48     private final Context mContext;
49     private final MediaRouter mRouter;
50     private final MediaRouterCallback mCallback;
51
52     private int mRouteTypes;
53     private MediaRouteButton mButton;
54     private View.OnClickListener mExtendedSettingsListener;
55
56     public MediaRouteActionProvider(Context context) {
57         super(context);
58
59         mContext = context;
60         mRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
61         mCallback = new MediaRouterCallback(this);
62
63         // Start with live audio by default.
64         // TODO Update this when new route types are added; segment by API level
65         // when different route types were added.
66         setRouteTypes(MediaRouter.ROUTE_TYPE_LIVE_AUDIO);
67     }
68
69     /**
70      * Sets the types of routes that will be shown in the media route chooser dialog
71      * launched by this button.
72      *
73      * @param types The route types to match.
74      */
75     public void setRouteTypes(int types) {
76         if (mRouteTypes != types) {
77             // FIXME: We currently have no way of knowing whether the action provider
78             // is still needed by the UI.  Unfortunately this means the action provider
79             // may leak callbacks until garbage collection occurs.  This may result in
80             // media route providers doing more work than necessary in the short term
81             // while trying to discover routes that are no longer of interest to the
82             // application.  To solve this problem, the action provider will need some
83             // indication from the framework that it is being destroyed.
84             if (mRouteTypes != 0) {
85                 mRouter.removeCallback(mCallback);
86             }
87             mRouteTypes = types;
88             if (types != 0) {
89                 mRouter.addCallback(types, mCallback,
90                         MediaRouter.CALLBACK_FLAG_PASSIVE_DISCOVERY);
91             }
92             refreshRoute();
93
94             if (mButton != null) {
95                 mButton.setRouteTypes(mRouteTypes);
96             }
97         }
98     }
99
100     public void setExtendedSettingsClickListener(View.OnClickListener listener) {
101         mExtendedSettingsListener = listener;
102         if (mButton != null) {
103             mButton.setExtendedSettingsClickListener(listener);
104         }
105     }
106
107     @Override
108     @SuppressWarnings("deprecation")
109     public View onCreateActionView() {
110         throw new UnsupportedOperationException("Use onCreateActionView(MenuItem) instead.");
111     }
112
113     @Override
114     public View onCreateActionView(MenuItem item) {
115         if (mButton != null) {
116             Log.e(TAG, "onCreateActionView: this ActionProvider is already associated " +
117                     "with a menu item. Don't reuse MediaRouteActionProvider instances! " +
118                     "Abandoning the old one...");
119         }
120
121         mButton = new MediaRouteButton(mContext);
122         mButton.setCheatSheetEnabled(true);
123         mButton.setRouteTypes(mRouteTypes);
124         mButton.setExtendedSettingsClickListener(mExtendedSettingsListener);
125         mButton.setLayoutParams(new ViewGroup.LayoutParams(
126                 ViewGroup.LayoutParams.WRAP_CONTENT,
127                 ViewGroup.LayoutParams.MATCH_PARENT));
128         return mButton;
129     }
130
131     @Override
132     public boolean onPerformDefaultAction() {
133         if (mButton != null) {
134             return mButton.showDialogInternal();
135         }
136         return false;
137     }
138
139     @Override
140     public boolean overridesItemVisibility() {
141         return true;
142     }
143
144     @Override
145     public boolean isVisible() {
146         return mRouter.isRouteAvailable(mRouteTypes,
147                 MediaRouter.AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE);
148     }
149
150     private void refreshRoute() {
151         refreshVisibility();
152     }
153
154     private static class MediaRouterCallback extends MediaRouter.SimpleCallback {
155         private final WeakReference<MediaRouteActionProvider> mProviderWeak;
156
157         public MediaRouterCallback(MediaRouteActionProvider provider) {
158             mProviderWeak = new WeakReference<MediaRouteActionProvider>(provider);
159         }
160
161         @Override
162         public void onRouteAdded(MediaRouter router, RouteInfo info) {
163             refreshRoute(router);
164         }
165
166         @Override
167         public void onRouteRemoved(MediaRouter router, RouteInfo info) {
168             refreshRoute(router);
169         }
170
171         @Override
172         public void onRouteChanged(MediaRouter router, RouteInfo info) {
173             refreshRoute(router);
174         }
175
176         private void refreshRoute(MediaRouter router) {
177             MediaRouteActionProvider provider = mProviderWeak.get();
178             if (provider != null) {
179                 provider.refreshRoute();
180             } else {
181                 router.removeCallback(this);
182             }
183         }
184     }
185 }