diff options
author | 2025-03-13 01:02:10 +0000 | |
---|---|---|
committer | 2025-03-18 06:39:39 +0000 | |
commit | fdf991d92991e9604af9040f249059e1fb65392d (patch) | |
tree | 620c8c17227c618395ca370124f0b5e52c51aa93 | |
parent | edf584d173f2fbfbfeee3d75aff106e6be1fc20b (diff) |
CastDetailsView: Migrate functionalities to chooser content manager
Move all the necessary functionalities from MediaRouteChooserDialog to
MediaRouteChooserContentManager.
This CL follows the refactor mentioned in go/cast-details-view.
Bug: 395947047
Flag: NONE refactor
Test: http://ag/32396457, atest MediaRouteChooserContentManagerTest
Test: Cast to a device, click on the Cast tile, launched the dialog and
verified that the chooser UI works.
Change-Id: I423379bfdaf38fece2243de2cea29daeb2f6df79
-rw-r--r-- | core/java/com/android/internal/app/MediaRouteChooserContentManager.java | 212 | ||||
-rw-r--r-- | core/java/com/android/internal/app/MediaRouteChooserDialog.java | 187 |
2 files changed, 225 insertions, 174 deletions
diff --git a/core/java/com/android/internal/app/MediaRouteChooserContentManager.java b/core/java/com/android/internal/app/MediaRouteChooserContentManager.java index 09c6f5e6caaa..63abc9c35a96 100644 --- a/core/java/com/android/internal/app/MediaRouteChooserContentManager.java +++ b/core/java/com/android/internal/app/MediaRouteChooserContentManager.java @@ -17,21 +17,56 @@ package com.android.internal.app; import android.content.Context; +import android.media.MediaRouter; +import android.text.TextUtils; import android.view.Gravity; +import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; import android.widget.LinearLayout; import android.widget.ListView; +import android.widget.TextView; import com.android.internal.R; +import java.util.Comparator; + public class MediaRouteChooserContentManager { + /** + * A delegate interface that a MediaRouteChooser UI should implement. It allows the content + * manager to inform the UI of any UI changes that need to be made in response to content + * updates. + */ + public interface Delegate { + /** + * Dismiss the UI to transition to a different workflow. + */ + void dismissView(); + + /** + * Returns true if the progress bar should be shown when the list view is empty. + */ + boolean showProgressBarWhenEmpty(); + } + Context mContext; + Delegate mDelegate; - private final boolean mShowProgressBarWhenEmpty; + private final MediaRouter mRouter; + private final MediaRouterCallback mCallback; - public MediaRouteChooserContentManager(Context context, boolean showProgressBarWhenEmpty) { + private int mRouteTypes; + private RouteAdapter mAdapter; + private boolean mAttachedToWindow; + + public MediaRouteChooserContentManager(Context context, Delegate delegate) { mContext = context; - mShowProgressBarWhenEmpty = showProgressBarWhenEmpty; + mDelegate = delegate; + + mRouter = context.getSystemService(MediaRouter.class); + mCallback = new MediaRouterCallback(); } /** @@ -40,10 +75,13 @@ public class MediaRouteChooserContentManager { */ public void bindViews(View containerView) { View emptyView = containerView.findViewById(android.R.id.empty); + mAdapter = new RouteAdapter(mContext); ListView listView = containerView.findViewById(R.id.media_route_list); + listView.setAdapter(mAdapter); + listView.setOnItemClickListener(mAdapter); listView.setEmptyView(emptyView); - if (!mShowProgressBarWhenEmpty) { + if (!mDelegate.showProgressBarWhenEmpty()) { containerView.findViewById(R.id.media_route_progress_bar).setVisibility(View.GONE); // Center the empty view when the progress bar is not shown. @@ -53,4 +91,170 @@ public class MediaRouteChooserContentManager { emptyView.setLayoutParams(params); } } + + /** + * Called when this UI is attached to a window.. + */ + public void onAttachedToWindow() { + mAttachedToWindow = true; + mRouter.addCallback(mRouteTypes, mCallback, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN); + refreshRoutes(); + } + + /** + * Called when this UI is detached from a window.. + */ + public void onDetachedFromWindow() { + mAttachedToWindow = false; + mRouter.removeCallback(mCallback); + } + + /** + * Gets the media route types for filtering the routes that the user can + * select using the media route chooser dialog. + * + * @return The route types. + */ + public int getRouteTypes() { + return mRouteTypes; + } + + /** + * Sets the types of routes that will be shown in the media route chooser dialog + * launched by this button. + * + * @param types The route types to match. + */ + public void setRouteTypes(int types) { + if (mRouteTypes != types) { + mRouteTypes = types; + + if (mAttachedToWindow) { + mRouter.removeCallback(mCallback); + mRouter.addCallback(types, mCallback, + MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN); + } + + refreshRoutes(); + } + } + + /** + * Refreshes the list of routes that are shown in the chooser dialog. + */ + public void refreshRoutes() { + if (mAttachedToWindow) { + mAdapter.update(); + } + } + + /** + * Returns true if the route should be included in the list. + * <p> + * The default implementation returns true for enabled non-default routes that + * match the route types. Subclasses can override this method to filter routes + * differently. + * </p> + * + * @param route The route to consider, never null. + * @return True if the route should be included in the chooser dialog. + */ + public boolean onFilterRoute(MediaRouter.RouteInfo route) { + return !route.isDefault() && route.isEnabled() && route.matchesTypes(mRouteTypes); + } + + private final class RouteAdapter extends ArrayAdapter<MediaRouter.RouteInfo> + implements AdapterView.OnItemClickListener { + private final LayoutInflater mInflater; + + RouteAdapter(Context context) { + super(context, 0); + mInflater = LayoutInflater.from(context); + } + + public void update() { + clear(); + final int count = mRouter.getRouteCount(); + for (int i = 0; i < count; i++) { + MediaRouter.RouteInfo route = mRouter.getRouteAt(i); + if (onFilterRoute(route)) { + add(route); + } + } + sort(RouteComparator.sInstance); + notifyDataSetChanged(); + } + + @Override + public boolean areAllItemsEnabled() { + return false; + } + + @Override + public boolean isEnabled(int position) { + return getItem(position).isEnabled(); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View view = convertView; + if (view == null) { + view = mInflater.inflate(R.layout.media_route_list_item, parent, false); + } + MediaRouter.RouteInfo route = getItem(position); + TextView text1 = view.findViewById(android.R.id.text1); + TextView text2 = view.findViewById(android.R.id.text2); + text1.setText(route.getName()); + CharSequence description = route.getDescription(); + if (TextUtils.isEmpty(description)) { + text2.setVisibility(View.GONE); + text2.setText(""); + } else { + text2.setVisibility(View.VISIBLE); + text2.setText(description); + } + view.setEnabled(route.isEnabled()); + return view; + } + + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + MediaRouter.RouteInfo route = getItem(position); + if (route.isEnabled()) { + route.select(); + mDelegate.dismissView(); + } + } + } + + private static final class RouteComparator implements Comparator<MediaRouter.RouteInfo> { + public static final RouteComparator sInstance = new RouteComparator(); + + @Override + public int compare(MediaRouter.RouteInfo lhs, MediaRouter.RouteInfo rhs) { + return lhs.getName().toString().compareTo(rhs.getName().toString()); + } + } + + private final class MediaRouterCallback extends MediaRouter.SimpleCallback { + @Override + public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) { + refreshRoutes(); + } + + @Override + public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) { + refreshRoutes(); + } + + @Override + public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo info) { + refreshRoutes(); + } + + @Override + public void onRouteSelected(MediaRouter router, int type, MediaRouter.RouteInfo info) { + mDelegate.dismissView(); + } + } } diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialog.java b/core/java/com/android/internal/app/MediaRouteChooserDialog.java index 5030a143ea94..fc7ed89f395c 100644 --- a/core/java/com/android/internal/app/MediaRouteChooserDialog.java +++ b/core/java/com/android/internal/app/MediaRouteChooserDialog.java @@ -19,23 +19,14 @@ package com.android.internal.app; import android.app.AlertDialog; import android.content.Context; import android.media.MediaRouter; -import android.media.MediaRouter.RouteInfo; import android.os.Bundle; -import android.text.TextUtils; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; import android.widget.Button; -import android.widget.ListView; -import android.widget.TextView; import com.android.internal.R; -import java.util.Comparator; - /** * This class implements the route chooser dialog for {@link MediaRouter}. * <p> @@ -47,15 +38,11 @@ import java.util.Comparator; * * TODO: Move this back into the API, as in the support library media router. */ -public class MediaRouteChooserDialog extends AlertDialog { - private final MediaRouter mRouter; - private final MediaRouterCallback mCallback; - - private int mRouteTypes; +public class MediaRouteChooserDialog extends AlertDialog implements + MediaRouteChooserContentManager.Delegate { private View.OnClickListener mExtendedSettingsClickListener; - private RouteAdapter mAdapter; private Button mExtendedSettingsButton; - private boolean mAttachedToWindow; + private final boolean mShowProgressBarWhenEmpty; private final MediaRouteChooserContentManager mContentManager; @@ -66,19 +53,8 @@ public class MediaRouteChooserDialog extends AlertDialog { public MediaRouteChooserDialog(Context context, int theme, boolean showProgressBarWhenEmpty) { super(context, theme); - mRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE); - mCallback = new MediaRouterCallback(); - mContentManager = new MediaRouteChooserContentManager(context, showProgressBarWhenEmpty); - } - - /** - * Gets the media route types for filtering the routes that the user can - * select using the media route chooser dialog. - * - * @return The route types. - */ - public int getRouteTypes() { - return mRouteTypes; + mShowProgressBarWhenEmpty = showProgressBarWhenEmpty; + mContentManager = new MediaRouteChooserContentManager(context, this); } /** @@ -88,17 +64,7 @@ public class MediaRouteChooserDialog extends AlertDialog { * @param types The route types to match. */ public void setRouteTypes(int types) { - if (mRouteTypes != types) { - mRouteTypes = types; - - if (mAttachedToWindow) { - mRouter.removeCallback(mCallback); - mRouter.addCallback(types, mCallback, - MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN); - } - - refreshRoutes(); - } + mContentManager.setRouteTypes(types); } public void setExtendedSettingsClickListener(View.OnClickListener listener) { @@ -108,21 +74,6 @@ public class MediaRouteChooserDialog extends AlertDialog { } } - /** - * Returns true if the route should be included in the list. - * <p> - * The default implementation returns true for enabled non-default routes that - * match the route types. Subclasses can override this method to filter routes - * differently. - * </p> - * - * @param route The route to consider, never null. - * @return True if the route should be included in the chooser dialog. - */ - public boolean onFilterRoute(MediaRouter.RouteInfo route) { - return !route.isDefault() && route.isEnabled() && route.matchesTypes(mRouteTypes); - } - @Override protected void onCreate(Bundle savedInstanceState) { // Note: setView must be called before super.onCreate(). @@ -130,7 +81,7 @@ public class MediaRouteChooserDialog extends AlertDialog { R.layout.media_route_chooser_dialog, null); setView(containerView); - setTitle(mRouteTypes == MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY + setTitle(mContentManager.getRouteTypes() == MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY ? R.string.media_route_chooser_title_for_remote_display : R.string.media_route_chooser_title); @@ -139,11 +90,6 @@ public class MediaRouteChooserDialog extends AlertDialog { super.onCreate(savedInstanceState); - mAdapter = new RouteAdapter(getContext()); - ListView listView = findViewById(R.id.media_route_list); - listView.setAdapter(mAdapter); - listView.setOnItemClickListener(mAdapter); - mExtendedSettingsButton = findViewById(R.id.media_route_extended_settings_button); updateExtendedSettingsButton(); @@ -161,27 +107,23 @@ public class MediaRouteChooserDialog extends AlertDialog { @Override public void onAttachedToWindow() { super.onAttachedToWindow(); - - mAttachedToWindow = true; - mRouter.addCallback(mRouteTypes, mCallback, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN); - refreshRoutes(); + mContentManager.onAttachedToWindow(); } @Override public void onDetachedFromWindow() { - mAttachedToWindow = false; - mRouter.removeCallback(mCallback); - + mContentManager.onDetachedFromWindow(); super.onDetachedFromWindow(); } - /** - * Refreshes the list of routes that are shown in the chooser dialog. - */ - public void refreshRoutes() { - if (mAttachedToWindow) { - mAdapter.update(); - } + @Override + public void dismissView() { + dismiss(); + } + + @Override + public boolean showProgressBarWhenEmpty() { + return mShowProgressBarWhenEmpty; } static boolean isLightTheme(Context context) { @@ -189,99 +131,4 @@ public class MediaRouteChooserDialog extends AlertDialog { return context.getTheme().resolveAttribute(R.attr.isLightTheme, value, true) && value.data != 0; } - - private final class RouteAdapter extends ArrayAdapter<MediaRouter.RouteInfo> - implements ListView.OnItemClickListener { - private final LayoutInflater mInflater; - - public RouteAdapter(Context context) { - super(context, 0); - mInflater = LayoutInflater.from(context); - } - - public void update() { - clear(); - final int count = mRouter.getRouteCount(); - for (int i = 0; i < count; i++) { - MediaRouter.RouteInfo route = mRouter.getRouteAt(i); - if (onFilterRoute(route)) { - add(route); - } - } - sort(RouteComparator.sInstance); - notifyDataSetChanged(); - } - - @Override - public boolean areAllItemsEnabled() { - return false; - } - - @Override - public boolean isEnabled(int position) { - return getItem(position).isEnabled(); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View view = convertView; - if (view == null) { - view = mInflater.inflate(R.layout.media_route_list_item, parent, false); - } - MediaRouter.RouteInfo route = getItem(position); - TextView text1 = view.findViewById(android.R.id.text1); - TextView text2 = view.findViewById(android.R.id.text2); - text1.setText(route.getName()); - CharSequence description = route.getDescription(); - if (TextUtils.isEmpty(description)) { - text2.setVisibility(View.GONE); - text2.setText(""); - } else { - text2.setVisibility(View.VISIBLE); - text2.setText(description); - } - view.setEnabled(route.isEnabled()); - return view; - } - - @Override - public void onItemClick(AdapterView<?> parent, View view, int position, long id) { - MediaRouter.RouteInfo route = getItem(position); - if (route.isEnabled()) { - route.select(); - dismiss(); - } - } - } - - private final class MediaRouterCallback extends MediaRouter.SimpleCallback { - @Override - public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) { - refreshRoutes(); - } - - @Override - public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) { - refreshRoutes(); - } - - @Override - public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo info) { - refreshRoutes(); - } - - @Override - public void onRouteSelected(MediaRouter router, int type, RouteInfo info) { - dismiss(); - } - } - - private static final class RouteComparator implements Comparator<MediaRouter.RouteInfo> { - public static final RouteComparator sInstance = new RouteComparator(); - - @Override - public int compare(MediaRouter.RouteInfo lhs, MediaRouter.RouteInfo rhs) { - return lhs.getName().toString().compareTo(rhs.getName().toString()); - } - } } |