Merge "MediaRouter/Wifi Display improvements" into jb-mr1-dev
@@ -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();
|
||||
|
||||
BIN
core/res/res/drawable-hdpi/ic_media_route_on_0_holo_dark.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
core/res/res/drawable-hdpi/ic_media_route_on_0_holo_light.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
core/res/res/drawable-hdpi/ic_media_route_on_1_holo_dark.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
core/res/res/drawable-hdpi/ic_media_route_on_1_holo_light.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
core/res/res/drawable-hdpi/ic_media_route_on_2_holo_dark.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
core/res/res/drawable-hdpi/ic_media_route_on_2_holo_light.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
core/res/res/drawable-mdpi/ic_media_route_on_0_holo_dark.png
Normal file
|
After Width: | Height: | Size: 967 B |
BIN
core/res/res/drawable-mdpi/ic_media_route_on_0_holo_light.png
Normal file
|
After Width: | Height: | Size: 978 B |
BIN
core/res/res/drawable-mdpi/ic_media_route_on_1_holo_dark.png
Normal file
|
After Width: | Height: | Size: 976 B |
BIN
core/res/res/drawable-mdpi/ic_media_route_on_1_holo_light.png
Normal file
|
After Width: | Height: | Size: 997 B |
BIN
core/res/res/drawable-mdpi/ic_media_route_on_2_holo_dark.png
Normal file
|
After Width: | Height: | Size: 988 B |
BIN
core/res/res/drawable-mdpi/ic_media_route_on_2_holo_light.png
Normal file
|
After Width: | Height: | Size: 1006 B |
BIN
core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_dark.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_light.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_dark.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_light.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_dark.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_light.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Copyright 2012, 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.
|
||||
*/
|
||||
-->
|
||||
<animation-list
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:oneshot="false">
|
||||
<item android:drawable="@drawable/ic_media_route_on_0_holo_dark" android:duration="500" />
|
||||
<item android:drawable="@drawable/ic_media_route_on_1_holo_dark" android:duration="500" />
|
||||
<item android:drawable="@drawable/ic_media_route_on_2_holo_dark" android:duration="500" />
|
||||
<item android:drawable="@drawable/ic_media_route_on_holo_dark" android:duration="500" />
|
||||
<item android:drawable="@drawable/ic_media_route_on_2_holo_dark" android:duration="500" />
|
||||
<item android:drawable="@drawable/ic_media_route_on_1_holo_dark" android:duration="500" />
|
||||
</animation-list>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Copyright 2012, 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.
|
||||
*/
|
||||
-->
|
||||
<animation-list
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:oneshot="false">
|
||||
<item android:drawable="@drawable/ic_media_route_on_0_holo_light" android:duration="500" />
|
||||
<item android:drawable="@drawable/ic_media_route_on_1_holo_light" android:duration="500" />
|
||||
<item android:drawable="@drawable/ic_media_route_on_2_holo_light" android:duration="500" />
|
||||
<item android:drawable="@drawable/ic_media_route_on_holo_light" android:duration="500" />
|
||||
<item android:drawable="@drawable/ic_media_route_on_2_holo_light" android:duration="500" />
|
||||
<item android:drawable="@drawable/ic_media_route_on_1_holo_light" android:duration="500" />
|
||||
</animation-list>
|
||||
@@ -15,6 +15,7 @@
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_checked="true" android:state_enabled="true" android:drawable="@android:drawable/ic_media_route_connecting_holo_dark" />
|
||||
<item android:state_activated="true" android:state_enabled="true" android:drawable="@android:drawable/ic_media_route_on_holo_dark" />
|
||||
<item android:state_enabled="true" android:drawable="@android:drawable/ic_media_route_off_holo_dark" />
|
||||
<item android:drawable="@android:drawable/ic_media_route_disabled_holo_dark" />
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_checked="true" android:state_enabled="true" android:drawable="@android:drawable/ic_media_route_connecting_holo_light" />
|
||||
<item android:state_activated="true" android:state_enabled="true" android:drawable="@android:drawable/ic_media_route_on_holo_light" />
|
||||
<item android:state_enabled="true" android:drawable="@android:drawable/ic_media_route_off_holo_light" />
|
||||
<item android:drawable="@android:drawable/ic_media_route_disabled_holo_light" />
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||