diff options
author | Adam Powell <adamp@google.com> | 2012-06-16 14:25:38 -0700 |
---|---|---|
committer | Adam Powell <adamp@google.com> | 2012-06-16 14:49:13 -0700 |
commit | 39d5c6172503620ac3761148adac5fd7fa20d02d (patch) | |
tree | 8720e26aeab2ae36577309dd912be3f0933c6f14 /core | |
parent | c4637d3efbbeb3e204691da96c357b5fea4ae2f1 (diff) | |
download | frameworks_base-39d5c6172503620ac3761148adac5fd7fa20d02d.zip frameworks_base-39d5c6172503620ac3761148adac5fd7fa20d02d.tar.gz frameworks_base-39d5c6172503620ac3761148adac5fd7fa20d02d.tar.bz2 |
Make MediaRouter UI more robust around route count changes
Improve the API around ActionProvider visibility overriding. Allow the
application to notify whatever is hosting the ActionProvider that
visibility has changed in a way that is friendly to alternate support
library-style reimplementations of MenuItem.
Allow MediaRouter.Callback implementations to add or remove themselves
or other Callbacks during dispatch of callback events.
Make MediaRouteActionProvider track the visibility of corresponding
menu items more accurately.
Change-Id: Ic7ddb6a87c3637904750d2661e4a9fa323b09ea0
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/app/MediaRouteActionProvider.java | 43 | ||||
-rw-r--r-- | core/java/android/view/ActionProvider.java | 40 | ||||
-rw-r--r-- | core/java/com/android/internal/view/menu/MenuItemImpl.java | 8 |
3 files changed, 90 insertions, 1 deletions
diff --git a/core/java/android/app/MediaRouteActionProvider.java b/core/java/android/app/MediaRouteActionProvider.java index b1fc90a..c2f5ac1 100644 --- a/core/java/android/app/MediaRouteActionProvider.java +++ b/core/java/android/app/MediaRouteActionProvider.java @@ -21,11 +21,14 @@ import com.android.internal.app.MediaRouteChooserDialogFragment; import android.content.Context; import android.content.ContextWrapper; import android.media.MediaRouter; +import android.media.MediaRouter.RouteInfo; import android.util.Log; import android.view.ActionProvider; import android.view.MenuItem; import android.view.View; +import java.lang.ref.WeakReference; + public class MediaRouteActionProvider extends ActionProvider { private static final String TAG = "MediaRouteActionProvider"; @@ -35,11 +38,13 @@ public class MediaRouteActionProvider extends ActionProvider { private MediaRouteButton mView; private int mRouteTypes; private View.OnClickListener mExtendedSettingsListener; + private RouterCallback mCallback; public MediaRouteActionProvider(Context context) { super(context); mContext = context; mRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE); + mCallback = new RouterCallback(this); // Start with live audio by default. // TODO Update this when new route types are added; segment by API level @@ -48,7 +53,14 @@ public class MediaRouteActionProvider extends ActionProvider { } public void setRouteTypes(int types) { + if (mRouteTypes == types) return; + if (mRouteTypes != 0) { + mRouter.removeCallback(mCallback); + } mRouteTypes = types; + if (types != 0) { + mRouter.addCallback(types, mCallback); + } if (mView != null) { mView.setRouteTypes(mRouteTypes); } @@ -68,7 +80,6 @@ public class MediaRouteActionProvider extends ActionProvider { } mMenuItem = item; mView = new MediaRouteButton(mContext); - mMenuItem.setVisible(mRouter.getRouteCount() > 1); mView.setRouteTypes(mRouteTypes); mView.setExtendedSettingsClickListener(mExtendedSettingsListener); return mView; @@ -123,4 +134,34 @@ public class MediaRouteActionProvider extends ActionProvider { public boolean isVisible() { return mRouter.getRouteCount() > 1; } + + private static class RouterCallback extends MediaRouter.SimpleCallback { + private WeakReference<MediaRouteActionProvider> mAp; + + RouterCallback(MediaRouteActionProvider ap) { + mAp = new WeakReference<MediaRouteActionProvider>(ap); + } + + @Override + public void onRouteAdded(MediaRouter router, RouteInfo info) { + final MediaRouteActionProvider ap = mAp.get(); + if (ap == null) { + router.removeCallback(this); + return; + } + + ap.refreshVisibility(); + } + + @Override + public void onRouteRemoved(MediaRouter router, RouteInfo info) { + final MediaRouteActionProvider ap = mAp.get(); + if (ap == null) { + router.removeCallback(this); + return; + } + + ap.refreshVisibility(); + } + } } diff --git a/core/java/android/view/ActionProvider.java b/core/java/android/view/ActionProvider.java index af9bf9e..c3aafde 100644 --- a/core/java/android/view/ActionProvider.java +++ b/core/java/android/view/ActionProvider.java @@ -17,6 +17,7 @@ package android.view; import android.content.Context; +import android.util.Log; /** * An ActionProvider defines rich menu interaction in a single component. @@ -55,7 +56,9 @@ import android.content.Context; * @see MenuItem#getActionProvider() */ public abstract class ActionProvider { + private static final String TAG = "ActionProvider"; private SubUiVisibilityListener mSubUiVisibilityListener; + private VisibilityListener mVisibilityListener; /** * Creates a new instance. ActionProvider classes should always implement a @@ -122,6 +125,18 @@ public abstract class ActionProvider { } /** + * If this ActionProvider is associated with an item in a menu, + * refresh the visibility of the item based on {@link #overridesItemVisibility()} and + * {@link #isVisible()}. If {@link #overridesItemVisibility()} returns false, this call + * will have no effect. + */ + public void refreshVisibility() { + if (mVisibilityListener != null && overridesItemVisibility()) { + mVisibilityListener.onActionProviderVisibilityChanged(isVisible()); + } + } + + /** * Performs an optional default action. * <p> * For the case of an action provider placed in a menu item not shown as an action this @@ -207,9 +222,34 @@ public abstract class ActionProvider { } /** + * Set a listener to be notified when this ActionProvider's overridden visibility changes. + * This should only be used by MenuItem implementations. + * + * @param listener listener to set + */ + public void setVisibilityListener(VisibilityListener listener) { + if (mVisibilityListener != null) { + Log.w(TAG, "setVisibilityListener: Setting a new ActionProvider.VisibilityListener " + + "when one is already set. Are you reusing this " + getClass().getSimpleName() + + " instance while it is still in use somewhere else?"); + } + mVisibilityListener = listener; + } + + /** * @hide Internal use only */ public interface SubUiVisibilityListener { public void onSubUiVisibilityChanged(boolean isVisible); } + + /** + * Listens to changes in visibility as reported by {@link ActionProvider#refreshVisibility()}. + * + * @see ActionProvider#overridesItemVisibility() + * @see ActionProvider#isVisible() + */ + public interface VisibilityListener { + public void onActionProviderVisibilityChanged(boolean isVisible); + } } diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java index 9baface..9f7441d 100644 --- a/core/java/com/android/internal/view/menu/MenuItemImpl.java +++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java @@ -589,9 +589,17 @@ public final class MenuItemImpl implements MenuItem { } public MenuItem setActionProvider(ActionProvider actionProvider) { + if (mActionProvider != null) { + mActionProvider.setVisibilityListener(null); + } mActionView = null; mActionProvider = actionProvider; mMenu.onItemsChanged(true); // Measurement can be changed + mActionProvider.setVisibilityListener(new ActionProvider.VisibilityListener() { + @Override public void onActionProviderVisibilityChanged(boolean isVisible) { + mMenu.onItemVisibleChanged(MenuItemImpl.this); + } + }); return this; } |