QS: Introduce cast control panel.
Make cast controller more granular, at the route level, and
bind a common detail item panel to the available routes.
Fix tile icon, add connecting label.
Remove dialog presentation, no longer needed.
Add the new empty state, and add controller state to dump.
Found a bug in keyguard when in presentation mode, added
a workaround - don't crash when no owner info in keyguard
status view.
Bug:15833210
Change-Id: I19afec390eac2260bccf4a7064065b666b7bceca
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
index 38316ff..150ab74 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -86,7 +86,7 @@
private void setEnableMarquee(boolean enabled) {
if (DEBUG) Log.v(TAG, (enabled ? "Enable" : "Disable") + " transport text marquee");
if (mAlarmStatusView != null) mAlarmStatusView.setSelected(enabled);
- mOwnerInfo.setSelected(enabled);
+ if (mOwnerInfo != null) mOwnerInfo.setSelected(enabled);
}
@Override
@@ -131,6 +131,7 @@
}
private void updateOwnerInfo() {
+ if (mOwnerInfo == null) return;
String ownerInfo = getOwnerInfo();
if (!TextUtils.isEmpty(ownerInfo)) {
mOwnerInfo.setVisibility(View.VISIBLE);
diff --git a/packages/SystemUI/res/drawable/ic_qs_cast_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_cast_detail_empty.xml
new file mode 100644
index 0000000..fbc21d4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_cast_detail_empty.xml
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <size
+ android:width="56dp"
+ android:height="56dp"/>
+
+ <viewport
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0"/>
+
+ <path
+ android:fill="@color/qs_detail_empty"
+ android:pathData="M42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0zM2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_cast_on.xml b/packages/SystemUI/res/drawable/ic_qs_cast_on.xml
index 8dacdc9..159bf65 100644
--- a/packages/SystemUI/res/drawable/ic_qs_cast_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_cast_on.xml
@@ -24,5 +24,5 @@
<path
android:fill="#FFFFFFFF"
- android:pathData="M42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0zM2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0z"/>
+ android:pathData="M2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM38.0,14.0L10.0,14.0l0.0,3.3c7.9,2.6 14.2,8.8 16.7,16.7L38.0,34.0L38.0,14.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0zM42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0z"/>
</vector>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index b0f2133..6a7b450 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -526,8 +526,16 @@
<string name="quick_settings_wifi_off_label">Wi-Fi Off</string>
<!-- QuickSettings: Wifi detail panel, text when there are no items [CHAR LIMIT=NONE] -->
<string name="quick_settings_wifi_detail_empty_text">No saved networks available</string>
- <!-- QuickSettings: Remote display [CHAR LIMIT=NONE] -->
- <string name="quick_settings_remote_display_no_connection_label">Cast screen</string>
+ <!-- QuickSettings: Cast title [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_cast_title">Cast screen</string>
+ <!-- QuickSettings: Cast detail panel, status text when casting [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_casting">Casting</string>
+ <!-- QuickSettings: Cast detail panel, default device name [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_cast_device_default_name">Unnamed device</string>
+ <!-- QuickSettings: Cast detail panel, default device description [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_cast_device_default_description">Ready to cast</string>
+ <!-- QuickSettings: Cast detail panel, text when there are no items [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_cast_detail_empty_text">No devices available</string>
<!-- QuickSettings: Brightness dialog title [CHAR LIMIT=NONE] -->
<string name="quick_settings_brightness_dialog_title">Brightness</string>
<!-- QuickSettings: Brightness dialog auto brightness button [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 502713f..ab952c6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -16,17 +16,23 @@
package com.android.systemui.qs.tiles;
-import android.app.Dialog;
+import android.content.Context;
import android.content.Intent;
-import android.media.MediaRouter;
import android.provider.Settings;
+import android.util.Log;
import android.view.View;
-import android.view.WindowManager;
+import android.view.View.OnAttachStateChangeListener;
+import android.view.ViewGroup;
-import com.android.internal.app.MediaRouteDialogPresenter;
import com.android.systemui.R;
+import com.android.systemui.qs.QSDetailItems;
+import com.android.systemui.qs.QSDetailItems.Item;
import com.android.systemui.qs.QSTile;
import com.android.systemui.statusbar.policy.CastController;
+import com.android.systemui.statusbar.policy.CastController.CastDevice;
+
+import java.util.LinkedHashMap;
+import java.util.Set;
/** Quick settings tile: Cast **/
public class CastTile extends QSTile<QSTile.BooleanState> {
@@ -34,10 +40,17 @@
new Intent(Settings.ACTION_WIFI_DISPLAY_SETTINGS);
private final CastController mController;
+ private final CastDetailAdapter mDetailAdapter;
public CastTile(Host host) {
super(host);
mController = host.getCastController();
+ mDetailAdapter = new CastDetailAdapter();
+ }
+
+ @Override
+ public DetailAdapter getDetailAdapter() {
+ return mDetailAdapter;
}
@Override
@@ -48,12 +61,13 @@
@Override
public void setListening(boolean listening) {
if (mController == null) return;
+ if (DEBUG) Log.d(TAG, "setListening " + listening);
if (listening) {
mController.addCallback(mCallback);
} else {
+ mController.setDiscovering(false);
mController.removeCallback(mCallback);
}
- mController.setDiscovering(listening);
}
@Override
@@ -65,61 +79,147 @@
@Override
protected void handleClick() {
- mHandler.post(new Runnable() {
- public void run() {
- mHost.collapsePanels();
- mUiHandler.post(mShowDialog);
- }
- });
+ showDetail(true);
}
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
state.visible = true;
- state.label = mContext
- .getString(R.string.quick_settings_remote_display_no_connection_label);
- if (arg instanceof CallbackInfo) {
- final CallbackInfo cb = (CallbackInfo) arg;
- if (cb.connectedRouteName != null) {
- state.value = !cb.connecting;
+ state.label = mContext.getString(R.string.quick_settings_cast_title);
+ state.value = false;
+ final Set<CastDevice> devices = mController.getCastDevices();
+ boolean connecting = false;
+ for (CastDevice device : devices) {
+ if (device.state == CastDevice.STATE_CONNECTED) {
+ state.value = true;
+ state.label = getDeviceName(device);
+ } else if (device.state == CastDevice.STATE_CONNECTING) {
+ connecting = true;
}
}
+ if (!state.value && connecting) {
+ state.label = mContext.getString(R.string.quick_settings_connecting);
+ }
state.iconId = state.value ? R.drawable.ic_qs_cast_on : R.drawable.ic_qs_cast_off;
+ mDetailAdapter.updateItems(devices);
}
- private static class CallbackInfo {
- boolean enabled;
- boolean connecting;
- String connectedRouteName;
+ private String getDeviceName(CastDevice device) {
+ return device.name != null ? device.name
+ : mContext.getString(R.string.quick_settings_cast_device_default_name);
}
private final CastController.Callback mCallback = new CastController.Callback() {
@Override
- public void onStateChanged(boolean enabled, boolean connecting,
- String connectedRouteName) {
- final CallbackInfo info = new CallbackInfo(); // TODO pool
- info.enabled = enabled;
- info.connecting = connecting;
- info.connectedRouteName = connectedRouteName;
- refreshState(info);
+ public void onCastDevicesChanged() {
+ refreshState();
}
};
- private final Runnable mShowDialog = new Runnable() {
- private Dialog mDialog;
+ private final class CastDetailAdapter implements DetailAdapter, QSDetailItems.Callback {
+ private final LinkedHashMap<String, CastDevice> mVisibleOrder = new LinkedHashMap<>();
+
+ private QSDetailItems mItems;
+
@Override
- public void run() {
- mDialog = MediaRouteDialogPresenter.createDialog(mContext,
- MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mDialog.dismiss();
- mHost.startSettingsActivity(WIFI_DISPLAY_SETTINGS);
- }
- });
- mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
- mDialog.show();
+ public int getTitle() {
+ return R.string.quick_settings_cast_title;
}
- };
+
+ @Override
+ public Boolean getToggleState() {
+ return null;
+ }
+
+ @Override
+ public Intent getSettingsIntent() {
+ return WIFI_DISPLAY_SETTINGS;
+ }
+
+ @Override
+ public void setToggleState(boolean state) {
+ // noop
+ }
+
+ @Override
+ public View createDetailView(Context context, View convertView, ViewGroup parent) {
+ mItems = QSDetailItems.convertOrInflate(context, convertView, parent);
+ mItems.setTagSuffix("Cast");
+ if (convertView == null) {
+ if (DEBUG) Log.d(TAG, "addOnAttachStateChangeListener");
+ mItems.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ if (DEBUG) Log.d(TAG, "onViewAttachedToWindow");
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ if (DEBUG) Log.d(TAG, "onViewDetachedFromWindow");
+ mVisibleOrder.clear();
+ }
+ });
+ }
+ mItems.setEmptyState(R.drawable.ic_qs_cast_detail_empty,
+ R.string.quick_settings_cast_detail_empty_text);
+ mItems.setCallback(this);
+ updateItems(mController.getCastDevices());
+ mController.setDiscovering(true);
+ return mItems;
+ }
+
+ private void updateItems(Set<CastDevice> devices) {
+ if (mItems == null) return;
+ Item[] items = null;
+ if (devices != null && !devices.isEmpty()) {
+ // if we are connected, simply show that device
+ for (CastDevice device : devices) {
+ if (device.state == CastDevice.STATE_CONNECTED) {
+ final Item item = new Item();
+ item.icon = R.drawable.ic_qs_cast_on;
+ item.line1 = getDeviceName(device);
+ item.line2 = mContext.getString(R.string.quick_settings_connected);
+ item.tag = device;
+ item.canDisconnect = true;
+ items = new Item[] { item };
+ break;
+ }
+ }
+ // otherwise list all available devices, and don't move them around
+ if (items == null) {
+ for (CastDevice device : devices) {
+ mVisibleOrder.put(device.id, device);
+ }
+ items = new Item[devices.size()];
+ int i = 0;
+ for (String id : mVisibleOrder.keySet()) {
+ final CastDevice device = mVisibleOrder.get(id);
+ if (!devices.contains(device)) continue;
+ final Item item = new Item();
+ item.icon = R.drawable.ic_qs_cast_off;
+ item.line1 = getDeviceName(device);
+ if (device.state == CastDevice.STATE_CONNECTING) {
+ item.line2 = mContext.getString(R.string.quick_settings_connecting);
+ }
+ item.tag = device;
+ items[i++] = item;
+ }
+ }
+ }
+ mItems.setItems(items);
+ }
+
+ @Override
+ public void onDetailItemClick(Item item) {
+ if (item == null || item.tag == null) return;
+ final CastDevice device = (CastDevice) item.tag;
+ mController.startCasting(device);
+ }
+
+ @Override
+ public void onDetailItemDisconnect(Item item) {
+ if (item == null || item.tag == null) return;
+ mController.stopCasting();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 9d7d933..505af44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -2322,6 +2322,9 @@
if (mBluetoothController != null) {
mBluetoothController.dump(fd, pw, args);
}
+ if (mCastController != null) {
+ mCastController.dump(fd, pw, args);
+ }
}
private String hunStateToString(Entry entry) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
index 54041e1..eb5804a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
@@ -16,13 +16,30 @@
package com.android.systemui.statusbar.policy;
+import java.util.Set;
+
public interface CastController {
void addCallback(Callback callback);
void removeCallback(Callback callback);
void setDiscovering(boolean request);
void setCurrentUserId(int currentUserId);
+ Set<CastDevice> getCastDevices();
+ void startCasting(CastDevice device);
+ void stopCasting();
public interface Callback {
- void onStateChanged(boolean enabled, boolean connecting, String connectedRouteName);
+ void onCastDevicesChanged();
+ }
+
+ public static final class CastDevice {
+ public static final int STATE_DISCONNECTED = 0;
+ public static final int STATE_CONNECTING = 1;
+ public static final int STATE_CONNECTED = 2;
+
+ public String id;
+ public String name;
+ public String description;
+ public int state = STATE_DISCONNECTED;
+ public Object tag;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
index bcd865c..22179e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
@@ -16,30 +16,55 @@
package com.android.systemui.statusbar.policy;
+import static android.media.MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY;
+
import android.content.Context;
import android.media.MediaRouter;
import android.media.MediaRouter.RouteInfo;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Set;
+import java.util.UUID;
/** Platform implementation of the cast controller. **/
public class CastControllerImpl implements CastController {
+ private static final String TAG = "CastController";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private final Context mContext;
private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
private final MediaRouter mMediaRouter;
+ private final ArrayMap<String, RouteInfo> mRoutes = new ArrayMap<>();
+ private final Object mDiscoveringLock = new Object();
- private boolean mEnabled;
- private boolean mConnecting;
- private String mConnectedRouteName;
+ private boolean mDiscovering;
public CastControllerImpl(Context context) {
+ mContext = context;
mMediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+ if (DEBUG) Log.d(TAG, "new CastController()");
+ }
+
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("CastController state:");
+ pw.print(" mDiscovering="); pw.println(mDiscovering);
+ pw.print(" mCallbacks.size="); pw.println(mCallbacks.size());
+ pw.print(" mRoutes.size="); pw.println(mRoutes.size());
+ for (int i = 0; i < mRoutes.size(); i++) {
+ final RouteInfo route = mRoutes.valueAt(i);
+ pw.print(" "); pw.println(routeToString(route));
+ }
}
@Override
public void addCallback(Callback callback) {
mCallbacks.add(callback);
- fireStateChanged(callback);
+ fireOnCastDevicesChanged(callback);
}
@Override
@@ -49,12 +74,16 @@
@Override
public void setDiscovering(boolean request) {
- if (request) {
- mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY,
- mMediaCallback,
- MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
- } else {
- mMediaRouter.removeCallback(mMediaCallback);
+ synchronized (mDiscoveringLock) {
+ if (mDiscovering == request) return;
+ mDiscovering = request;
+ if (DEBUG) Log.d(TAG, "setDiscovering: " + request);
+ if (request) {
+ mMediaRouter.addCallback(ROUTE_TYPE_REMOTE_DISPLAY, mMediaCallback,
+ MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
+ } else {
+ mMediaRouter.removeCallback(mMediaCallback);
+ }
}
}
@@ -63,63 +92,113 @@
mMediaRouter.rebindAsUser(currentUserId);
}
+ @Override
+ public Set<CastDevice> getCastDevices() {
+ final ArraySet<CastDevice> devices = new ArraySet<CastDevice>();
+ synchronized(mRoutes) {
+ for (RouteInfo route : mRoutes.values()) {
+ final CastDevice device = new CastDevice();
+ device.id = route.getTag().toString();
+ final CharSequence name = route.getName(mContext);
+ device.name = name != null ? name.toString() : null;
+ final CharSequence description = route.getDescription();
+ device.description = description != null ? description.toString() : null;
+ device.state = route.isConnecting() ? CastDevice.STATE_CONNECTING
+ : route.isSelected() ? CastDevice.STATE_CONNECTED
+ : CastDevice.STATE_DISCONNECTED;
+ device.tag = route;
+ devices.add(device);
+ }
+ }
+ return devices;
+ }
+
+ @Override
+ public void startCasting(CastDevice device) {
+ if (device == null || device.tag == null) return;
+ final RouteInfo route = (RouteInfo) device.tag;
+ if (DEBUG) Log.d(TAG, "startCasting: " + routeToString(route));
+ mMediaRouter.selectRoute(ROUTE_TYPE_REMOTE_DISPLAY, route);
+ }
+
+ @Override
+ public void stopCasting() {
+ if (DEBUG) Log.d(TAG, "stopCasting");
+ mMediaRouter.getDefaultRoute().select();
+ }
+
private void updateRemoteDisplays() {
- final MediaRouter.RouteInfo connectedRoute = mMediaRouter.getSelectedRoute(
- MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY);
- boolean enabled = connectedRoute != null
- && connectedRoute.matchesTypes(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY);
- boolean connecting;
- if (enabled) {
- connecting = connectedRoute.isConnecting();
- } else {
- connecting = false;
- enabled = mMediaRouter.isRouteAvailable(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY,
- MediaRouter.AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE);
+ synchronized(mRoutes) {
+ mRoutes.clear();
+ final int n = mMediaRouter.getRouteCount();
+ for (int i = 0; i < n; i++) {
+ final RouteInfo route = mMediaRouter.getRouteAt(i);
+ if (!route.isEnabled()) continue;
+ if (!route.matchesTypes(ROUTE_TYPE_REMOTE_DISPLAY)) continue;
+ ensureTagExists(route);
+ mRoutes.put(route.getTag().toString(), route);
+ }
+ final RouteInfo selected = mMediaRouter.getSelectedRoute(ROUTE_TYPE_REMOTE_DISPLAY);
+ if (selected != null && !selected.isDefault()) {
+ ensureTagExists(selected);
+ mRoutes.put(selected.getTag().toString(), selected);
+ }
}
-
- String connectedRouteName = null;
- if (connectedRoute != null) {
- connectedRouteName = connectedRoute.getName().toString();
- }
- synchronized(mCallbacks) {
- mEnabled = enabled;
- mConnecting = connecting;
- mConnectedRouteName = connectedRouteName;
- }
- fireStateChanged();
+ fireOnCastDevicesChanged();
}
- private void fireStateChanged() {
+ private void ensureTagExists(RouteInfo route) {
+ if (route.getTag() == null) {
+ route.setTag(UUID.randomUUID().toString());
+ }
+ }
+
+ private void fireOnCastDevicesChanged() {
for (Callback callback : mCallbacks) {
- fireStateChanged(callback);
+ fireOnCastDevicesChanged(callback);
}
}
- private void fireStateChanged(Callback callback) {
- synchronized(mCallbacks) {
- callback.onStateChanged(mEnabled, mConnecting, mConnectedRouteName);
- }
+ private void fireOnCastDevicesChanged(Callback callback) {
+ callback.onCastDevicesChanged();
+ }
+
+ private static String routeToString(RouteInfo route) {
+ if (route == null) return null;
+ final StringBuilder sb = new StringBuilder().append(route.getName()).append('/')
+ .append(route.getDescription()).append('@').append(route.getDeviceAddress())
+ .append(",status=").append(route.getStatus());
+ if (route.isDefault()) sb.append(",default");
+ if (route.isEnabled()) sb.append(",enabled");
+ if (route.isConnecting()) sb.append(",connecting");
+ if (route.isSelected()) sb.append(",selected");
+ return sb.append(",id=").append(route.getTag()).toString();
}
private final MediaRouter.SimpleCallback mMediaCallback = new MediaRouter.SimpleCallback() {
@Override
public void onRouteAdded(MediaRouter router, RouteInfo route) {
+ if (DEBUG) Log.d(TAG, "onRouteAdded: " + routeToString(route));
updateRemoteDisplays();
}
@Override
public void onRouteChanged(MediaRouter router, RouteInfo route) {
+ if (DEBUG) Log.d(TAG, "onRouteChanged: " + routeToString(route));
updateRemoteDisplays();
}
@Override
public void onRouteRemoved(MediaRouter router, RouteInfo route) {
+ if (DEBUG) Log.d(TAG, "onRouteRemoved: " + routeToString(route));
updateRemoteDisplays();
}
@Override
public void onRouteSelected(MediaRouter router, int type, RouteInfo route) {
+ if (DEBUG) Log.d(TAG, "onRouteSelected(" + type + "): " + routeToString(route));
updateRemoteDisplays();
}
@Override
public void onRouteUnselected(MediaRouter router, int type, RouteInfo route) {
+ if (DEBUG) Log.d(TAG, "onRouteUnselected(" + type + "): " + routeToString(route));
updateRemoteDisplays();
}
};