diff --git a/core/java/android/app/MediaRouteButton.java b/core/java/android/app/MediaRouteButton.java index a9ccef002863a..3ecafc3bc9b90 100644 --- a/core/java/android/app/MediaRouteButton.java +++ b/core/java/android/app/MediaRouteButton.java @@ -50,6 +50,7 @@ public class MediaRouteButton extends View { private boolean mRemoteActive; private boolean mToggleMode; private boolean mCheatSheetEnabled; + private boolean mIsConnecting; private int mMinWidth; private int mMinHeight; @@ -57,6 +58,10 @@ public class MediaRouteButton extends View { private OnClickListener mExtendedSettingsClickListener; private MediaRouteChooserDialogFragment mDialogFragment; + private static final int[] CHECKED_STATE_SET = { + R.attr.state_checked + }; + private static final int[] ACTIVATED_STATE_SET = { R.attr.state_activated }; @@ -210,10 +215,21 @@ public class MediaRouteButton extends View { } void updateRemoteIndicator() { - final boolean isRemote = - mRouter.getSelectedRoute(mRouteTypes) != mRouter.getSystemAudioRoute(); + final RouteInfo selected = mRouter.getSelectedRoute(mRouteTypes); + final boolean isRemote = selected != mRouter.getSystemAudioRoute(); + final boolean isConnecting = selected.getStatusCode() == RouteInfo.STATUS_CONNECTING; + + boolean needsRefresh = false; if (mRemoteActive != isRemote) { mRemoteActive = isRemote; + needsRefresh = true; + } + if (mIsConnecting != isConnecting) { + mIsConnecting = isConnecting; + needsRefresh = true; + } + + if (needsRefresh) { refreshDrawableState(); } } @@ -248,7 +264,14 @@ public class MediaRouteButton extends View { @Override protected int[] onCreateDrawableState(int extraSpace) { final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); - if (mRemoteActive) { + + // Technically we should be handling this more completely, but these + // are implementation details here. Checked is used to express the connecting + // drawable state and it's mutually exclusive with activated for the purposes + // of state selection here. + if (mIsConnecting) { + mergeDrawableStates(drawableState, CHECKED_STATE_SET); + } else if (mRemoteActive) { mergeDrawableStates(drawableState, ACTIVATED_STATE_SET); } return drawableState; @@ -425,6 +448,11 @@ public class MediaRouteButton extends View { updateRemoteIndicator(); } + @Override + public void onRouteChanged(MediaRouter router, RouteInfo info) { + updateRemoteIndicator(); + } + @Override public void onRouteAdded(MediaRouter router, RouteInfo info) { updateRouteCount(); diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_dark.png new file mode 100644 index 0000000000000..10fc8dac3b651 Binary files /dev/null and b/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_dark.png differ diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_light.png new file mode 100644 index 0000000000000..a0e5060727c49 Binary files /dev/null and b/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_light.png differ diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_dark.png new file mode 100644 index 0000000000000..8364a3672b16d Binary files /dev/null and b/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_dark.png differ diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_light.png new file mode 100644 index 0000000000000..44b89e1ae8c75 Binary files /dev/null and b/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_light.png differ diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_dark.png new file mode 100644 index 0000000000000..770bf78d13673 Binary files /dev/null and b/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_dark.png differ diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_light.png new file mode 100644 index 0000000000000..2a2467b8c3cee Binary files /dev/null and b/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_light.png differ diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_dark.png new file mode 100644 index 0000000000000..fb2ac25a5edc5 Binary files /dev/null and b/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_dark.png differ diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_light.png new file mode 100644 index 0000000000000..0c200910a0a3e Binary files /dev/null and b/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_light.png differ diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_dark.png new file mode 100644 index 0000000000000..2f70ceef3b7e1 Binary files /dev/null and b/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_dark.png differ diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_light.png new file mode 100644 index 0000000000000..0b76d8e08fe78 Binary files /dev/null and b/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_light.png differ diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_dark.png new file mode 100644 index 0000000000000..ae7b10534ef00 Binary files /dev/null and b/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_dark.png differ diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_light.png new file mode 100644 index 0000000000000..8d37b9940a188 Binary files /dev/null and b/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_light.png differ diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_dark.png new file mode 100644 index 0000000000000..483b61270a0ea Binary files /dev/null and b/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_dark.png differ diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_light.png new file mode 100644 index 0000000000000..c3507dc30cea3 Binary files /dev/null and b/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_light.png differ diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_dark.png new file mode 100644 index 0000000000000..24c65198f21a3 Binary files /dev/null and b/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_dark.png differ diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_light.png new file mode 100644 index 0000000000000..2be0380fdbfce Binary files /dev/null and b/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_light.png differ diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_dark.png new file mode 100644 index 0000000000000..4fd69bd765cb1 Binary files /dev/null and b/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_dark.png differ diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_light.png new file mode 100644 index 0000000000000..51588564da424 Binary files /dev/null and b/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_light.png differ diff --git a/core/res/res/drawable/ic_media_route_connecting_holo_dark.xml b/core/res/res/drawable/ic_media_route_connecting_holo_dark.xml new file mode 100644 index 0000000000000..36e01f6ef7d38 --- /dev/null +++ b/core/res/res/drawable/ic_media_route_connecting_holo_dark.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/core/res/res/drawable/ic_media_route_connecting_holo_light.xml b/core/res/res/drawable/ic_media_route_connecting_holo_light.xml new file mode 100644 index 0000000000000..6683db84bd0d0 --- /dev/null +++ b/core/res/res/drawable/ic_media_route_connecting_holo_light.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/core/res/res/drawable/ic_media_route_holo_dark.xml b/core/res/res/drawable/ic_media_route_holo_dark.xml index 0b267d7cff959..b4c1fac9cca9c 100644 --- a/core/res/res/drawable/ic_media_route_holo_dark.xml +++ b/core/res/res/drawable/ic_media_route_holo_dark.xml @@ -15,6 +15,7 @@ --> + diff --git a/core/res/res/drawable/ic_media_route_holo_light.xml b/core/res/res/drawable/ic_media_route_holo_light.xml index 377253a2e077e..553721d6678c5 100644 --- a/core/res/res/drawable/ic_media_route_holo_light.xml +++ b/core/res/res/drawable/ic_media_route_holo_light.xml @@ -15,6 +15,7 @@ --> + diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java index 36c9c705e3221..e5b9637a44b4d 100644 --- a/media/java/android/media/MediaRouter.java +++ b/media/java/android/media/MediaRouter.java @@ -105,8 +105,13 @@ public class MediaRouter { mDefaultAudioVideo = new RouteInfo(mSystemCategory); mDefaultAudioVideo.mNameResId = com.android.internal.R.string.default_audio_route_name; mDefaultAudioVideo.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO; - addRoute(mDefaultAudioVideo); + addRouteStatic(mDefaultAudioVideo); + // This will select the active wifi display route if there is one. + updateWifiDisplayStatus(mDisplayService.getWifiDisplayStatus()); + + appContext.registerReceiver(new WifiDisplayStatusChangedReceiver(), + new IntentFilter(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)); appContext.registerReceiver(new VolumeChangeReceiver(), new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION)); @@ -116,13 +121,17 @@ public class MediaRouter { } catch (RemoteException e) { } if (newAudioRoutes != null) { + // This will select the active BT route if there is one and the current + // selected route is the default system route, or if there is no selected + // route yet. updateAudioRoutes(newAudioRoutes); } - updateWifiDisplayStatus(mDisplayService.getWifiDisplayStatus()); - - appContext.registerReceiver(new WifiDisplayStatusChangedReceiver(), - new IntentFilter(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)); + // Select the default route if the above didn't sync us up + // appropriately with relevant system state. + if (mSelectedRoute == null) { + selectRouteStatic(mDefaultAudioVideo.getSupportedTypes(), mDefaultAudioVideo); + } } void updateAudioRoutes(AudioRoutesInfo newRoutes) { @@ -159,7 +168,7 @@ public class MediaRouter { info.mName = mCurAudioRoutesInfo.mBluetoothName; info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO; sStatic.mBluetoothA2dpRoute = info; - addRoute(sStatic.mBluetoothA2dpRoute); + addRouteStatic(sStatic.mBluetoothA2dpRoute); } else { sStatic.mBluetoothA2dpRoute.mName = mCurAudioRoutesInfo.mBluetoothName; dispatchRouteChanged(sStatic.mBluetoothA2dpRoute); @@ -175,7 +184,8 @@ public class MediaRouter { mSelectedRoute == mBluetoothA2dpRoute) { selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo); } else if (mCurAudioRoutesInfo.mMainType == AudioRoutesInfo.MAIN_SPEAKER && - mSelectedRoute == mDefaultAudioVideo && a2dpEnabled) { + (mSelectedRoute == mDefaultAudioVideo || mSelectedRoute == null) && + a2dpEnabled) { selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute); } } @@ -393,22 +403,21 @@ public class MediaRouter { * @see #removeUserRoute(UserRouteInfo) */ public void addUserRoute(UserRouteInfo info) { - addRoute(info); + addRouteStatic(info); } /** * @hide Framework use only */ public void addRouteInt(RouteInfo info) { - addRoute(info); + addRouteStatic(info); } - static void addRoute(RouteInfo info) { + static void addRouteStatic(RouteInfo info) { final RouteCategory cat = info.getCategory(); if (!sStatic.mCategories.contains(cat)) { sStatic.mCategories.add(cat); } - final boolean onlyRoute = sStatic.mRoutes.isEmpty(); if (cat.isGroupable() && !(info instanceof RouteGroup)) { // Enforce that any added route in a groupable category must be in a group. final RouteGroup group = new RouteGroup(info.getCategory()); @@ -422,10 +431,6 @@ public class MediaRouter { sStatic.mRoutes.add(info); dispatchRouteAdded(info); } - - if (onlyRoute) { - selectRouteStatic(info.getSupportedTypes(), info); - } } /** @@ -693,18 +698,25 @@ public class MediaRouter { oldStatus.getRememberedDisplays() : new WifiDisplay[0]; WifiDisplay[] newDisplays = newStatus.getRememberedDisplays(); WifiDisplay[] availableDisplays = newStatus.getAvailableDisplays(); + WifiDisplay activeDisplay = newStatus.getActiveDisplay(); for (int i = 0; i < newDisplays.length; i++) { final WifiDisplay d = newDisplays[i]; final WifiDisplay oldRemembered = findMatchingDisplay(d, oldDisplays); if (oldRemembered == null) { - addRoute(makeWifiDisplayRoute(d)); + addRouteStatic(makeWifiDisplayRoute(d)); needScan = true; } else { final boolean available = findMatchingDisplay(d, availableDisplays) != null; final RouteInfo route = findWifiDisplayRoute(d); updateWifiDisplayRoute(route, d, available, newStatus); } + if (d.equals(activeDisplay)) { + final RouteInfo activeRoute = findWifiDisplayRoute(d); + if (activeRoute != null) { + selectRouteStatic(activeRoute.getSupportedTypes(), activeRoute); + } + } } for (int i = 0; i < oldDisplays.length; i++) { final WifiDisplay d = oldDisplays[i]; @@ -840,11 +852,11 @@ public class MediaRouter { // A predetermined connection status that can override mStatus private int mStatusCode; - static final int STATUS_NONE = 0; - static final int STATUS_SCANNING = 1; - static final int STATUS_CONNECTING = 2; - static final int STATUS_AVAILABLE = 3; - static final int STATUS_NOT_AVAILABLE = 4; + /** @hide */ public static final int STATUS_NONE = 0; + /** @hide */ public static final int STATUS_SCANNING = 1; + /** @hide */ public static final int STATUS_CONNECTING = 2; + /** @hide */ public static final int STATUS_AVAILABLE = 3; + /** @hide */ public static final int STATUS_NOT_AVAILABLE = 4; private Object mTag; @@ -940,6 +952,13 @@ public class MediaRouter { return false; } + /** + * @hide + */ + public int getStatusCode() { + return mStatusCode; + } + /** * @return A media type flag set describing which types this route supports. */