summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andre Le <leandre@google.com> 2025-03-13 01:02:10 +0000
committer Andre Le <leandre@google.com> 2025-03-18 06:39:39 +0000
commitfdf991d92991e9604af9040f249059e1fb65392d (patch)
tree620c8c17227c618395ca370124f0b5e52c51aa93
parentedf584d173f2fbfbfeee3d75aff106e6be1fc20b (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.java212
-rw-r--r--core/java/com/android/internal/app/MediaRouteChooserDialog.java187
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());
- }
- }
}