MediaRouteActionProvider.java revision 39d5c6172503620ac3761148adac5fd7fa20d02d
1690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell/* 2690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * Copyright (C) 2012 The Android Open Source Project 3690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * 4690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 5690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * you may not use this file except in compliance with the License. 6690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * You may obtain a copy of the License at 7690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * 8690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * http://www.apache.org/licenses/LICENSE-2.0 9690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * 10690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * Unless required by applicable law or agreed to in writing, software 11690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * distributed under the License is distributed on an "AS IS" BASIS, 12690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * See the License for the specific language governing permissions and 14690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * limitations under the License. 15690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell */ 16690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 17690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellpackage android.app; 18690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 1970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport com.android.internal.app.MediaRouteChooserDialogFragment; 2070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 21690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.content.Context; 2270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.content.ContextWrapper; 23690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.media.MediaRouter; 2439d5c6172503620ac3761148adac5fd7fa20d02dAdam Powellimport android.media.MediaRouter.RouteInfo; 25690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.util.Log; 26690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.view.ActionProvider; 27690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.view.MenuItem; 28690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.view.View; 29690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 3039d5c6172503620ac3761148adac5fd7fa20d02dAdam Powellimport java.lang.ref.WeakReference; 3139d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell 32690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellpublic class MediaRouteActionProvider extends ActionProvider { 33690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private static final String TAG = "MediaRouteActionProvider"; 34690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 35690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private Context mContext; 36690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private MediaRouter mRouter; 37690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private MenuItem mMenuItem; 38690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private MediaRouteButton mView; 39690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private int mRouteTypes; 40b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell private View.OnClickListener mExtendedSettingsListener; 4139d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell private RouterCallback mCallback; 42690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 43690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public MediaRouteActionProvider(Context context) { 44690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell super(context); 45690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mContext = context; 46b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell mRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE); 4739d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell mCallback = new RouterCallback(this); 48690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 49690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell // Start with live audio by default. 50690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell // TODO Update this when new route types are added; segment by API level 51690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell // when different route types were added. 52690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell setRouteTypes(MediaRouter.ROUTE_TYPE_LIVE_AUDIO); 53690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 54690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 55690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public void setRouteTypes(int types) { 5639d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell if (mRouteTypes == types) return; 5739d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell if (mRouteTypes != 0) { 5839d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell mRouter.removeCallback(mCallback); 5939d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell } 60690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRouteTypes = types; 6139d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell if (types != 0) { 6239d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell mRouter.addCallback(types, mCallback); 6339d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell } 64690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (mView != null) { 65690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mView.setRouteTypes(mRouteTypes); 66690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 67690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 68690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 69690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 70690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public View onCreateActionView() { 71690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell throw new UnsupportedOperationException("Use onCreateActionView(MenuItem) instead."); 72690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 73690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 74690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 75690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public View onCreateActionView(MenuItem item) { 76690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (mMenuItem != null || mView != null) { 77690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell Log.e(TAG, "onCreateActionView: this ActionProvider is already associated " + 78690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell "with a menu item. Don't reuse MediaRouteActionProvider instances! " + 79690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell "Abandoning the old one..."); 80690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 81690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mMenuItem = item; 82690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mView = new MediaRouteButton(mContext); 83690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mView.setRouteTypes(mRouteTypes); 84b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell mView.setExtendedSettingsClickListener(mExtendedSettingsListener); 85690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell return mView; 86690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 87690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 88690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 89690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public boolean onPerformDefaultAction() { 9070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell final FragmentManager fm = getActivity().getFragmentManager(); 9170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell // See if one is already attached to this activity. 9270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell MediaRouteChooserDialogFragment dialogFragment = 9370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell (MediaRouteChooserDialogFragment) fm.findFragmentByTag( 9470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell MediaRouteChooserDialogFragment.FRAGMENT_TAG); 9570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell if (dialogFragment != null) { 9670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell Log.w(TAG, "onPerformDefaultAction(): Chooser dialog already showing!"); 9770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell return false; 9870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 9970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 10070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell dialogFragment = new MediaRouteChooserDialogFragment(); 10170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell dialogFragment.setExtendedSettingsClickListener(mExtendedSettingsListener); 10270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell dialogFragment.setRouteTypes(mRouteTypes); 10370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell dialogFragment.show(fm, MediaRouteChooserDialogFragment.FRAGMENT_TAG); 104690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell return true; 105690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 106690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 10770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell private Activity getActivity() { 10870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell // Gross way of unwrapping the Activity so we can get the FragmentManager 10970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell Context context = mContext; 11070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell while (context instanceof ContextWrapper && !(context instanceof Activity)) { 11170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell context = ((ContextWrapper) context).getBaseContext(); 11270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 11370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell if (!(context instanceof Activity)) { 11470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell throw new IllegalStateException("The MediaRouteActionProvider's Context " + 11570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell "is not an Activity."); 11670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 11770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 11870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell return (Activity) context; 11970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 12070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 121b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell public void setExtendedSettingsClickListener(View.OnClickListener listener) { 122b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell mExtendedSettingsListener = listener; 123b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell if (mView != null) { 124b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell mView.setExtendedSettingsClickListener(listener); 125b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell } 126b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell } 127b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell 128130b4572d1f3df702e5b296a655d15a41f6d4c66Adam Powell @Override 129130b4572d1f3df702e5b296a655d15a41f6d4c66Adam Powell public boolean overridesItemVisibility() { 130130b4572d1f3df702e5b296a655d15a41f6d4c66Adam Powell return true; 131130b4572d1f3df702e5b296a655d15a41f6d4c66Adam Powell } 132690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 133130b4572d1f3df702e5b296a655d15a41f6d4c66Adam Powell @Override 134130b4572d1f3df702e5b296a655d15a41f6d4c66Adam Powell public boolean isVisible() { 135130b4572d1f3df702e5b296a655d15a41f6d4c66Adam Powell return mRouter.getRouteCount() > 1; 136690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 13739d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell 13839d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell private static class RouterCallback extends MediaRouter.SimpleCallback { 13939d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell private WeakReference<MediaRouteActionProvider> mAp; 14039d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell 14139d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell RouterCallback(MediaRouteActionProvider ap) { 14239d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell mAp = new WeakReference<MediaRouteActionProvider>(ap); 14339d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell } 14439d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell 14539d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell @Override 14639d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell public void onRouteAdded(MediaRouter router, RouteInfo info) { 14739d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell final MediaRouteActionProvider ap = mAp.get(); 14839d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell if (ap == null) { 14939d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell router.removeCallback(this); 15039d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell return; 15139d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell } 15239d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell 15339d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell ap.refreshVisibility(); 15439d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell } 15539d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell 15639d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell @Override 15739d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell public void onRouteRemoved(MediaRouter router, RouteInfo info) { 15839d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell final MediaRouteActionProvider ap = mAp.get(); 15939d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell if (ap == null) { 16039d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell router.removeCallback(this); 16139d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell return; 16239d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell } 16339d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell 16439d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell ap.refreshVisibility(); 16539d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell } 16639d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell } 167690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell} 168