am f7910e31: Merge "Add wireless display selection support to MediaRouter." into jb-mr1-dev
* commit 'f7910e3148cd5ea21c9c3cdb7023c997139264ce': Add wireless display selection support to MediaRouter.
This commit is contained in:
@@ -11750,6 +11750,7 @@ package android.media {
|
|||||||
method public void removeUserRoute(android.media.MediaRouter.UserRouteInfo);
|
method public void removeUserRoute(android.media.MediaRouter.UserRouteInfo);
|
||||||
method public void selectRoute(int, android.media.MediaRouter.RouteInfo);
|
method public void selectRoute(int, android.media.MediaRouter.RouteInfo);
|
||||||
field public static final int ROUTE_TYPE_LIVE_AUDIO = 1; // 0x1
|
field public static final int ROUTE_TYPE_LIVE_AUDIO = 1; // 0x1
|
||||||
|
field public static final int ROUTE_TYPE_LIVE_VIDEO = 2; // 0x2
|
||||||
field public static final int ROUTE_TYPE_USER = 8388608; // 0x800000
|
field public static final int ROUTE_TYPE_USER = 8388608; // 0x800000
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11798,6 +11799,7 @@ package android.media {
|
|||||||
method public int getVolume();
|
method public int getVolume();
|
||||||
method public int getVolumeHandling();
|
method public int getVolumeHandling();
|
||||||
method public int getVolumeMax();
|
method public int getVolumeMax();
|
||||||
|
method public boolean isEnabled();
|
||||||
method public void requestSetVolume(int);
|
method public void requestSetVolume(int);
|
||||||
method public void requestUpdateVolume(int);
|
method public void requestUpdateVolume(int);
|
||||||
method public void setTag(java.lang.Object);
|
method public void setTag(java.lang.Object);
|
||||||
|
|||||||
@@ -221,21 +221,28 @@ public class MediaRouteButton extends View {
|
|||||||
void updateRouteCount() {
|
void updateRouteCount() {
|
||||||
final int N = mRouter.getRouteCount();
|
final int N = mRouter.getRouteCount();
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
boolean hasVideoRoutes = false;
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
final RouteInfo route = mRouter.getRouteAt(i);
|
final RouteInfo route = mRouter.getRouteAt(i);
|
||||||
if ((route.getSupportedTypes() & mRouteTypes) != 0) {
|
final int routeTypes = route.getSupportedTypes();
|
||||||
|
if ((routeTypes & mRouteTypes) != 0) {
|
||||||
if (route instanceof RouteGroup) {
|
if (route instanceof RouteGroup) {
|
||||||
count += ((RouteGroup) route).getRouteCount();
|
count += ((RouteGroup) route).getRouteCount();
|
||||||
} else {
|
} else {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
if ((routeTypes & MediaRouter.ROUTE_TYPE_LIVE_VIDEO) != 0) {
|
||||||
|
hasVideoRoutes = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setEnabled(count != 0);
|
setEnabled(count != 0);
|
||||||
|
|
||||||
// Only allow toggling if we have more than just user routes
|
// Only allow toggling if we have more than just user routes.
|
||||||
mToggleMode = count == 2 && (mRouteTypes & MediaRouter.ROUTE_TYPE_LIVE_AUDIO) != 0;
|
// Don't toggle if we support video routes, we may have to let the dialog scan.
|
||||||
|
mToggleMode = count == 2 && (mRouteTypes & MediaRouter.ROUTE_TYPE_LIVE_AUDIO) != 0 &&
|
||||||
|
!hasVideoRoutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import android.app.MediaRouteActionProvider;
|
|||||||
import android.app.MediaRouteButton;
|
import android.app.MediaRouteButton;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.media.AudioManager;
|
import android.hardware.display.DisplayManager;
|
||||||
import android.media.MediaRouter;
|
import android.media.MediaRouter;
|
||||||
import android.media.MediaRouter.RouteCategory;
|
import android.media.MediaRouter.RouteCategory;
|
||||||
import android.media.MediaRouter.RouteGroup;
|
import android.media.MediaRouter.RouteGroup;
|
||||||
@@ -70,6 +70,7 @@ public class MediaRouteChooserDialogFragment extends DialogFragment {
|
|||||||
};
|
};
|
||||||
|
|
||||||
MediaRouter mRouter;
|
MediaRouter mRouter;
|
||||||
|
DisplayManager mDisplayService;
|
||||||
private int mRouteTypes;
|
private int mRouteTypes;
|
||||||
|
|
||||||
private LayoutInflater mInflater;
|
private LayoutInflater mInflater;
|
||||||
@@ -97,6 +98,7 @@ public class MediaRouteChooserDialogFragment extends DialogFragment {
|
|||||||
public void onAttach(Activity activity) {
|
public void onAttach(Activity activity) {
|
||||||
super.onAttach(activity);
|
super.onAttach(activity);
|
||||||
mRouter = (MediaRouter) activity.getSystemService(Context.MEDIA_ROUTER_SERVICE);
|
mRouter = (MediaRouter) activity.getSystemService(Context.MEDIA_ROUTER_SERVICE);
|
||||||
|
mDisplayService = (DisplayManager) activity.getSystemService(Context.DISPLAY_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -119,6 +121,15 @@ public class MediaRouteChooserDialogFragment extends DialogFragment {
|
|||||||
|
|
||||||
public void setRouteTypes(int types) {
|
public void setRouteTypes(int types) {
|
||||||
mRouteTypes = types;
|
mRouteTypes = types;
|
||||||
|
if ((mRouteTypes & MediaRouter.ROUTE_TYPE_LIVE_VIDEO) != 0 && mDisplayService == null) {
|
||||||
|
final Context activity = getActivity();
|
||||||
|
if (activity != null) {
|
||||||
|
mDisplayService = (DisplayManager) activity.getSystemService(
|
||||||
|
Context.DISPLAY_SERVICE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mDisplayService = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateVolume() {
|
void updateVolume() {
|
||||||
@@ -194,6 +205,9 @@ public class MediaRouteChooserDialogFragment extends DialogFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
if (mDisplayService != null) {
|
||||||
|
mDisplayService.scanWifiDisplays();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ViewHolder {
|
private static class ViewHolder {
|
||||||
@@ -253,7 +267,9 @@ public class MediaRouteChooserDialogFragment extends DialogFragment {
|
|||||||
final RouteCategory cat = mRouter.getCategoryAt(i);
|
final RouteCategory cat = mRouter.getCategoryAt(i);
|
||||||
routes = cat.getRoutes(mCatRouteList);
|
routes = cat.getRoutes(mCatRouteList);
|
||||||
|
|
||||||
mItems.add(cat);
|
if (!cat.isSystem()) {
|
||||||
|
mItems.add(cat);
|
||||||
|
}
|
||||||
|
|
||||||
if (cat == mCategoryEditingGroups) {
|
if (cat == mCategoryEditingGroups) {
|
||||||
addGroupEditingCategoryRoutes(routes);
|
addGroupEditingCategoryRoutes(routes);
|
||||||
@@ -370,6 +386,7 @@ public class MediaRouteChooserDialogFragment extends DialogFragment {
|
|||||||
public boolean isEnabled(int position) {
|
public boolean isEnabled(int position) {
|
||||||
switch (getItemViewType(position)) {
|
switch (getItemViewType(position)) {
|
||||||
case VIEW_ROUTE:
|
case VIEW_ROUTE:
|
||||||
|
return ((RouteInfo) mItems.get(position)).isEnabled();
|
||||||
case VIEW_GROUPING_ROUTE:
|
case VIEW_GROUPING_ROUTE:
|
||||||
case VIEW_GROUPING_DONE:
|
case VIEW_GROUPING_DONE:
|
||||||
return true;
|
return true;
|
||||||
@@ -434,6 +451,7 @@ public class MediaRouteChooserDialogFragment extends DialogFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
convertView.setActivated(position == mSelectedItemPosition);
|
convertView.setActivated(position == mSelectedItemPosition);
|
||||||
|
convertView.setEnabled(isEnabled(position));
|
||||||
|
|
||||||
return convertView;
|
return convertView;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,8 @@
|
|||||||
android:layout_height="56dp"
|
android:layout_height="56dp"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
android:id="@+id/icon"
|
android:id="@+id/icon"
|
||||||
android:visibility="gone" />
|
android:visibility="gone"
|
||||||
|
android:duplicateParentState="true" />
|
||||||
|
|
||||||
<LinearLayout android:layout_width="0dp"
|
<LinearLayout android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@@ -32,21 +33,24 @@
|
|||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:gravity="start|center_vertical"
|
android:gravity="start|center_vertical"
|
||||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
|
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||||
|
android:duplicateParentState="true">
|
||||||
|
|
||||||
<TextView android:id="@android:id/text1"
|
<TextView android:id="@android:id/text1"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:ellipsize="marquee"
|
android:ellipsize="marquee"
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:duplicateParentState="true" />
|
||||||
|
|
||||||
<TextView android:id="@android:id/text2"
|
<TextView android:id="@android:id/text2"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:ellipsize="marquee"
|
android:ellipsize="marquee"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:duplicateParentState="true" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
@@ -56,6 +60,7 @@
|
|||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:src="@drawable/ic_media_group_expand"
|
android:src="@drawable/ic_media_group_expand"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
android:visibility="gone" />
|
android:visibility="gone"
|
||||||
|
android:duplicateParentState="true" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -3783,6 +3783,18 @@
|
|||||||
<!-- Content description of a MediaRouteButton for accessibility support -->
|
<!-- Content description of a MediaRouteButton for accessibility support -->
|
||||||
<string name="media_route_button_content_description">Media output</string>
|
<string name="media_route_button_content_description">Media output</string>
|
||||||
|
|
||||||
|
<!-- Status message for remote routes attempting to scan/determine availability -->
|
||||||
|
<string name="media_route_status_scanning">Scanning...</string>
|
||||||
|
|
||||||
|
<!-- Status message for a remote route attempting to connect -->
|
||||||
|
<string name="media_route_status_connecting">Connecting...</string>
|
||||||
|
|
||||||
|
<!-- Status message for a remote route that is confirmed to be available for connection -->
|
||||||
|
<string name="media_route_status_available">Available</string>
|
||||||
|
|
||||||
|
<!-- Status message for remote routes that are not available for connection right now -->
|
||||||
|
<string name="media_route_status_not_available">Not available</string>
|
||||||
|
|
||||||
<!-- Display manager service -->
|
<!-- Display manager service -->
|
||||||
|
|
||||||
<!-- Name of the built-in display. [CHAR LIMIT=50] -->
|
<!-- Name of the built-in display. [CHAR LIMIT=50] -->
|
||||||
|
|||||||
@@ -826,6 +826,10 @@
|
|||||||
<java-symbol type="string" name="default_audio_route_name_hdmi" />
|
<java-symbol type="string" name="default_audio_route_name_hdmi" />
|
||||||
<java-symbol type="string" name="default_audio_route_category_name" />
|
<java-symbol type="string" name="default_audio_route_category_name" />
|
||||||
<java-symbol type="string" name="safe_media_volume_warning" />
|
<java-symbol type="string" name="safe_media_volume_warning" />
|
||||||
|
<java-symbol type="string" name="media_route_status_scanning" />
|
||||||
|
<java-symbol type="string" name="media_route_status_connecting" />
|
||||||
|
<java-symbol type="string" name="media_route_status_available" />
|
||||||
|
<java-symbol type="string" name="media_route_status_not_available" />
|
||||||
|
|
||||||
<java-symbol type="plurals" name="abbrev_in_num_days" />
|
<java-symbol type="plurals" name="abbrev_in_num_days" />
|
||||||
<java-symbol type="plurals" name="abbrev_in_num_hours" />
|
<java-symbol type="plurals" name="abbrev_in_num_hours" />
|
||||||
|
|||||||
@@ -22,12 +22,17 @@ import android.content.Intent;
|
|||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.hardware.display.DisplayManager;
|
||||||
|
import android.hardware.display.WifiDisplay;
|
||||||
|
import android.hardware.display.WifiDisplayStatus;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.Display;
|
||||||
|
import android.view.DisplayInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -51,6 +56,7 @@ public class MediaRouter {
|
|||||||
static class Static {
|
static class Static {
|
||||||
final Resources mResources;
|
final Resources mResources;
|
||||||
final IAudioService mAudioService;
|
final IAudioService mAudioService;
|
||||||
|
final DisplayManager mDisplayService;
|
||||||
final Handler mHandler;
|
final Handler mHandler;
|
||||||
final CopyOnWriteArrayList<CallbackInfo> mCallbacks =
|
final CopyOnWriteArrayList<CallbackInfo> mCallbacks =
|
||||||
new CopyOnWriteArrayList<CallbackInfo>();
|
new CopyOnWriteArrayList<CallbackInfo>();
|
||||||
@@ -60,18 +66,20 @@ public class MediaRouter {
|
|||||||
|
|
||||||
final RouteCategory mSystemCategory;
|
final RouteCategory mSystemCategory;
|
||||||
|
|
||||||
final AudioRoutesInfo mCurRoutesInfo = new AudioRoutesInfo();
|
final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo();
|
||||||
|
|
||||||
RouteInfo mDefaultAudio;
|
RouteInfo mDefaultAudioVideo;
|
||||||
RouteInfo mBluetoothA2dpRoute;
|
RouteInfo mBluetoothA2dpRoute;
|
||||||
|
|
||||||
RouteInfo mSelectedRoute;
|
RouteInfo mSelectedRoute;
|
||||||
|
|
||||||
final IAudioRoutesObserver.Stub mRoutesObserver = new IAudioRoutesObserver.Stub() {
|
WifiDisplayStatus mLastKnownWifiDisplayStatus;
|
||||||
|
|
||||||
|
final IAudioRoutesObserver.Stub mAudioRoutesObserver = new IAudioRoutesObserver.Stub() {
|
||||||
public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) {
|
public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) {
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
updateRoutes(newRoutes);
|
updateAudioRoutes(newRoutes);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -84,34 +92,42 @@ public class MediaRouter {
|
|||||||
IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
|
IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
|
||||||
mAudioService = IAudioService.Stub.asInterface(b);
|
mAudioService = IAudioService.Stub.asInterface(b);
|
||||||
|
|
||||||
|
mDisplayService = (DisplayManager) appContext.getSystemService(Context.DISPLAY_SERVICE);
|
||||||
|
|
||||||
mSystemCategory = new RouteCategory(
|
mSystemCategory = new RouteCategory(
|
||||||
com.android.internal.R.string.default_audio_route_category_name,
|
com.android.internal.R.string.default_audio_route_category_name,
|
||||||
ROUTE_TYPE_LIVE_AUDIO, false);
|
ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO, false);
|
||||||
|
mSystemCategory.mIsSystem = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called after sStatic is initialized
|
// Called after sStatic is initialized
|
||||||
void startMonitoringRoutes(Context appContext) {
|
void startMonitoringRoutes(Context appContext) {
|
||||||
mDefaultAudio = new RouteInfo(mSystemCategory);
|
mDefaultAudioVideo = new RouteInfo(mSystemCategory);
|
||||||
mDefaultAudio.mNameResId = com.android.internal.R.string.default_audio_route_name;
|
mDefaultAudioVideo.mNameResId = com.android.internal.R.string.default_audio_route_name;
|
||||||
mDefaultAudio.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
|
mDefaultAudioVideo.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO;
|
||||||
addRoute(mDefaultAudio);
|
addRoute(mDefaultAudioVideo);
|
||||||
|
|
||||||
appContext.registerReceiver(new VolumeChangeReceiver(),
|
appContext.registerReceiver(new VolumeChangeReceiver(),
|
||||||
new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION));
|
new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION));
|
||||||
|
|
||||||
AudioRoutesInfo newRoutes = null;
|
AudioRoutesInfo newAudioRoutes = null;
|
||||||
try {
|
try {
|
||||||
newRoutes = mAudioService.startWatchingRoutes(mRoutesObserver);
|
newAudioRoutes = mAudioService.startWatchingRoutes(mAudioRoutesObserver);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
}
|
}
|
||||||
if (newRoutes != null) {
|
if (newAudioRoutes != null) {
|
||||||
updateRoutes(newRoutes);
|
updateAudioRoutes(newAudioRoutes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateWifiDisplayStatus(mDisplayService.getWifiDisplayStatus());
|
||||||
|
|
||||||
|
appContext.registerReceiver(new WifiDisplayStatusChangedReceiver(),
|
||||||
|
new IntentFilter(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED));
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateRoutes(AudioRoutesInfo newRoutes) {
|
void updateAudioRoutes(AudioRoutesInfo newRoutes) {
|
||||||
if (newRoutes.mMainType != mCurRoutesInfo.mMainType) {
|
if (newRoutes.mMainType != mCurAudioRoutesInfo.mMainType) {
|
||||||
mCurRoutesInfo.mMainType = newRoutes.mMainType;
|
mCurAudioRoutesInfo.mMainType = newRoutes.mMainType;
|
||||||
int name;
|
int name;
|
||||||
if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_HEADPHONES) != 0
|
if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_HEADPHONES) != 0
|
||||||
|| (newRoutes.mMainType&AudioRoutesInfo.MAIN_HEADSET) != 0) {
|
|| (newRoutes.mMainType&AudioRoutesInfo.MAIN_HEADSET) != 0) {
|
||||||
@@ -123,8 +139,8 @@ public class MediaRouter {
|
|||||||
} else {
|
} else {
|
||||||
name = com.android.internal.R.string.default_audio_route_name;
|
name = com.android.internal.R.string.default_audio_route_name;
|
||||||
}
|
}
|
||||||
sStatic.mDefaultAudio.mNameResId = name;
|
sStatic.mDefaultAudioVideo.mNameResId = name;
|
||||||
dispatchRouteChanged(sStatic.mDefaultAudio);
|
dispatchRouteChanged(sStatic.mDefaultAudioVideo);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean a2dpEnabled;
|
boolean a2dpEnabled;
|
||||||
@@ -135,17 +151,17 @@ public class MediaRouter {
|
|||||||
a2dpEnabled = false;
|
a2dpEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TextUtils.equals(newRoutes.mBluetoothName, mCurRoutesInfo.mBluetoothName)) {
|
if (!TextUtils.equals(newRoutes.mBluetoothName, mCurAudioRoutesInfo.mBluetoothName)) {
|
||||||
mCurRoutesInfo.mBluetoothName = newRoutes.mBluetoothName;
|
mCurAudioRoutesInfo.mBluetoothName = newRoutes.mBluetoothName;
|
||||||
if (mCurRoutesInfo.mBluetoothName != null) {
|
if (mCurAudioRoutesInfo.mBluetoothName != null) {
|
||||||
if (sStatic.mBluetoothA2dpRoute == null) {
|
if (sStatic.mBluetoothA2dpRoute == null) {
|
||||||
final RouteInfo info = new RouteInfo(sStatic.mSystemCategory);
|
final RouteInfo info = new RouteInfo(sStatic.mSystemCategory);
|
||||||
info.mName = mCurRoutesInfo.mBluetoothName;
|
info.mName = mCurAudioRoutesInfo.mBluetoothName;
|
||||||
info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
|
info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
|
||||||
sStatic.mBluetoothA2dpRoute = info;
|
sStatic.mBluetoothA2dpRoute = info;
|
||||||
addRoute(sStatic.mBluetoothA2dpRoute);
|
addRoute(sStatic.mBluetoothA2dpRoute);
|
||||||
} else {
|
} else {
|
||||||
sStatic.mBluetoothA2dpRoute.mName = mCurRoutesInfo.mBluetoothName;
|
sStatic.mBluetoothA2dpRoute.mName = mCurAudioRoutesInfo.mBluetoothName;
|
||||||
dispatchRouteChanged(sStatic.mBluetoothA2dpRoute);
|
dispatchRouteChanged(sStatic.mBluetoothA2dpRoute);
|
||||||
}
|
}
|
||||||
} else if (sStatic.mBluetoothA2dpRoute != null) {
|
} else if (sStatic.mBluetoothA2dpRoute != null) {
|
||||||
@@ -155,11 +171,11 @@ public class MediaRouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mBluetoothA2dpRoute != null) {
|
if (mBluetoothA2dpRoute != null) {
|
||||||
if (mCurRoutesInfo.mMainType != AudioRoutesInfo.MAIN_SPEAKER &&
|
if (mCurAudioRoutesInfo.mMainType != AudioRoutesInfo.MAIN_SPEAKER &&
|
||||||
mSelectedRoute == mBluetoothA2dpRoute) {
|
mSelectedRoute == mBluetoothA2dpRoute) {
|
||||||
selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudio);
|
selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo);
|
||||||
} else if (mCurRoutesInfo.mMainType == AudioRoutesInfo.MAIN_SPEAKER &&
|
} else if (mCurAudioRoutesInfo.mMainType == AudioRoutesInfo.MAIN_SPEAKER &&
|
||||||
mSelectedRoute == mDefaultAudio && a2dpEnabled) {
|
mSelectedRoute == mDefaultAudioVideo && a2dpEnabled) {
|
||||||
selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute);
|
selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,6 +196,20 @@ public class MediaRouter {
|
|||||||
*/
|
*/
|
||||||
public static final int ROUTE_TYPE_LIVE_AUDIO = 0x1;
|
public static final int ROUTE_TYPE_LIVE_AUDIO = 0x1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route type flag for live video.
|
||||||
|
*
|
||||||
|
* <p>A device that supports live video routing will allow a mirrored version
|
||||||
|
* of the device's primary display or a customized
|
||||||
|
* {@link android.app.Presentation Presentation} to be routed to supported destinations.</p>
|
||||||
|
*
|
||||||
|
* <p>Once initiated, display mirroring is transparent to the application.
|
||||||
|
* While remote routing is active the application may use a
|
||||||
|
* {@link android.app.Presentation Presentation} to replace the mirrored view
|
||||||
|
* on the external display with different content.</p>
|
||||||
|
*/
|
||||||
|
public static final int ROUTE_TYPE_LIVE_VIDEO = 0x2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Route type flag for application-specific usage.
|
* Route type flag for application-specific usage.
|
||||||
*
|
*
|
||||||
@@ -219,7 +249,7 @@ public class MediaRouter {
|
|||||||
* @hide for use by framework routing UI
|
* @hide for use by framework routing UI
|
||||||
*/
|
*/
|
||||||
public RouteInfo getSystemAudioRoute() {
|
public RouteInfo getSystemAudioRoute() {
|
||||||
return sStatic.mDefaultAudio;
|
return sStatic.mDefaultAudioVideo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -296,7 +326,8 @@ public class MediaRouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void selectRouteStatic(int types, RouteInfo route) {
|
static void selectRouteStatic(int types, RouteInfo route) {
|
||||||
if (sStatic.mSelectedRoute == route) return;
|
final RouteInfo oldRoute = sStatic.mSelectedRoute;
|
||||||
|
if (oldRoute == route) return;
|
||||||
if ((route.getSupportedTypes() & types) == 0) {
|
if ((route.getSupportedTypes() & types) == 0) {
|
||||||
Log.w(TAG, "selectRoute ignored; cannot select route with supported types " +
|
Log.w(TAG, "selectRoute ignored; cannot select route with supported types " +
|
||||||
typesToString(route.getSupportedTypes()) + " into route types " +
|
typesToString(route.getSupportedTypes()) + " into route types " +
|
||||||
@@ -306,7 +337,7 @@ public class MediaRouter {
|
|||||||
|
|
||||||
final RouteInfo btRoute = sStatic.mBluetoothA2dpRoute;
|
final RouteInfo btRoute = sStatic.mBluetoothA2dpRoute;
|
||||||
if (btRoute != null && (types & ROUTE_TYPE_LIVE_AUDIO) != 0 &&
|
if (btRoute != null && (types & ROUTE_TYPE_LIVE_AUDIO) != 0 &&
|
||||||
(route == btRoute || route == sStatic.mDefaultAudio)) {
|
(route == btRoute || route == sStatic.mDefaultAudioVideo)) {
|
||||||
try {
|
try {
|
||||||
sStatic.mAudioService.setBluetoothA2dpOn(route == btRoute);
|
sStatic.mAudioService.setBluetoothA2dpOn(route == btRoute);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -314,10 +345,21 @@ public class MediaRouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sStatic.mSelectedRoute != null) {
|
final WifiDisplay activeDisplay =
|
||||||
|
sStatic.mDisplayService.getWifiDisplayStatus().getActiveDisplay();
|
||||||
|
final boolean oldRouteHasAddress = oldRoute != null && oldRoute.mDeviceAddress != null;
|
||||||
|
final boolean newRouteHasAddress = route != null && route.mDeviceAddress != null;
|
||||||
|
if (activeDisplay != null || oldRouteHasAddress || newRouteHasAddress) {
|
||||||
|
if (newRouteHasAddress && !matchesDeviceAddress(activeDisplay, route)) {
|
||||||
|
sStatic.mDisplayService.connectWifiDisplay(route.mDeviceAddress);
|
||||||
|
} else if (activeDisplay != null && !newRouteHasAddress) {
|
||||||
|
sStatic.mDisplayService.disconnectWifiDisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldRoute != null) {
|
||||||
// TODO filter types properly
|
// TODO filter types properly
|
||||||
dispatchRouteUnselected(types & sStatic.mSelectedRoute.getSupportedTypes(),
|
dispatchRouteUnselected(types & oldRoute.getSupportedTypes(), oldRoute);
|
||||||
sStatic.mSelectedRoute);
|
|
||||||
}
|
}
|
||||||
sStatic.mSelectedRoute = route;
|
sStatic.mSelectedRoute = route;
|
||||||
if (route != null) {
|
if (route != null) {
|
||||||
@@ -326,6 +368,22 @@ public class MediaRouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the device address of a display and a route.
|
||||||
|
* Nulls/no device address will match another null/no address.
|
||||||
|
*/
|
||||||
|
static boolean matchesDeviceAddress(WifiDisplay display, RouteInfo info) {
|
||||||
|
final boolean routeHasAddress = info != null && info.mDeviceAddress != null;
|
||||||
|
if (display == null && !routeHasAddress) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (display != null && routeHasAddress) {
|
||||||
|
return display.getDeviceAddress().equals(info.mDeviceAddress);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an app-specified route for media to the MediaRouter.
|
* Add an app-specified route for media to the MediaRouter.
|
||||||
* App-specified route definitions are created using {@link #createUserRoute(RouteCategory)}
|
* App-specified route definitions are created using {@link #createUserRoute(RouteCategory)}
|
||||||
@@ -419,7 +477,7 @@ public class MediaRouter {
|
|||||||
if (info == sStatic.mSelectedRoute) {
|
if (info == sStatic.mSelectedRoute) {
|
||||||
// Removing the currently selected route? Select the default before we remove it.
|
// Removing the currently selected route? Select the default before we remove it.
|
||||||
// TODO: Be smarter about the route types here; this selects for all valid.
|
// TODO: Be smarter about the route types here; this selects for all valid.
|
||||||
selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_USER, sStatic.mDefaultAudio);
|
selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_USER, sStatic.mDefaultAudioVideo);
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
sStatic.mCategories.remove(removingCat);
|
sStatic.mCategories.remove(removingCat);
|
||||||
@@ -444,7 +502,8 @@ public class MediaRouter {
|
|||||||
if (info == sStatic.mSelectedRoute) {
|
if (info == sStatic.mSelectedRoute) {
|
||||||
// Removing the currently selected route? Select the default before we remove it.
|
// Removing the currently selected route? Select the default before we remove it.
|
||||||
// TODO: Be smarter about the route types here; this selects for all valid.
|
// TODO: Be smarter about the route types here; this selects for all valid.
|
||||||
selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_USER, sStatic.mDefaultAudio);
|
selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO | ROUTE_TYPE_USER,
|
||||||
|
sStatic.mDefaultAudioVideo);
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
sStatic.mCategories.remove(removingCat);
|
sStatic.mCategories.remove(removingCat);
|
||||||
@@ -611,20 +670,151 @@ public class MediaRouter {
|
|||||||
if (selectedRoute == null) return;
|
if (selectedRoute == null) return;
|
||||||
|
|
||||||
if (selectedRoute == sStatic.mBluetoothA2dpRoute ||
|
if (selectedRoute == sStatic.mBluetoothA2dpRoute ||
|
||||||
selectedRoute == sStatic.mDefaultAudio) {
|
selectedRoute == sStatic.mDefaultAudioVideo) {
|
||||||
dispatchRouteVolumeChanged(selectedRoute);
|
dispatchRouteVolumeChanged(selectedRoute);
|
||||||
} else if (sStatic.mBluetoothA2dpRoute != null) {
|
} else if (sStatic.mBluetoothA2dpRoute != null) {
|
||||||
try {
|
try {
|
||||||
dispatchRouteVolumeChanged(sStatic.mAudioService.isBluetoothA2dpOn() ?
|
dispatchRouteVolumeChanged(sStatic.mAudioService.isBluetoothA2dpOn() ?
|
||||||
sStatic.mBluetoothA2dpRoute : sStatic.mDefaultAudio);
|
sStatic.mBluetoothA2dpRoute : sStatic.mDefaultAudioVideo);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Error checking Bluetooth A2DP state to report volume change", e);
|
Log.e(TAG, "Error checking Bluetooth A2DP state to report volume change", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dispatchRouteVolumeChanged(sStatic.mDefaultAudio);
|
dispatchRouteVolumeChanged(sStatic.mDefaultAudioVideo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void updateWifiDisplayStatus(WifiDisplayStatus newStatus) {
|
||||||
|
final WifiDisplayStatus oldStatus = sStatic.mLastKnownWifiDisplayStatus;
|
||||||
|
|
||||||
|
// TODO Naive implementation. Make this smarter later.
|
||||||
|
boolean needScan = false;
|
||||||
|
WifiDisplay[] oldDisplays = oldStatus != null ?
|
||||||
|
oldStatus.getRememberedDisplays() : new WifiDisplay[0];
|
||||||
|
WifiDisplay[] newDisplays = newStatus.getRememberedDisplays();
|
||||||
|
WifiDisplay[] availableDisplays = newStatus.getAvailableDisplays();
|
||||||
|
|
||||||
|
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));
|
||||||
|
needScan = true;
|
||||||
|
} else {
|
||||||
|
final boolean available = findMatchingDisplay(d, availableDisplays) != null;
|
||||||
|
final RouteInfo route = findWifiDisplayRoute(d);
|
||||||
|
updateWifiDisplayRoute(route, d, available, newStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < oldDisplays.length; i++) {
|
||||||
|
final WifiDisplay d = oldDisplays[i];
|
||||||
|
final WifiDisplay newDisplay = findMatchingDisplay(d, newDisplays);
|
||||||
|
if (newDisplay == null) {
|
||||||
|
removeRoute(findWifiDisplayRoute(d));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needScan) {
|
||||||
|
sStatic.mDisplayService.scanWifiDisplays();
|
||||||
|
}
|
||||||
|
|
||||||
|
sStatic.mLastKnownWifiDisplayStatus = newStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RouteInfo makeWifiDisplayRoute(WifiDisplay display) {
|
||||||
|
final RouteInfo newRoute = new RouteInfo(sStatic.mSystemCategory);
|
||||||
|
newRoute.mDeviceAddress = display.getDeviceAddress();
|
||||||
|
newRoute.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO;
|
||||||
|
newRoute.mVolumeHandling = RouteInfo.PLAYBACK_VOLUME_FIXED;
|
||||||
|
newRoute.mPlaybackType = RouteInfo.PLAYBACK_TYPE_REMOTE;
|
||||||
|
newRoute.mStatus = sStatic.mResources.getText(
|
||||||
|
com.android.internal.R.string.media_route_status_connecting);
|
||||||
|
newRoute.mEnabled = false;
|
||||||
|
|
||||||
|
newRoute.mName = makeWifiDisplayName(display);
|
||||||
|
return newRoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String makeWifiDisplayName(WifiDisplay display) {
|
||||||
|
String name = display.getDeviceAlias();
|
||||||
|
if (TextUtils.isEmpty(name)) {
|
||||||
|
name = display.getDeviceName();
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateWifiDisplayRoute(RouteInfo route, WifiDisplay display,
|
||||||
|
boolean available, WifiDisplayStatus wifiDisplayStatus) {
|
||||||
|
final boolean isScanning =
|
||||||
|
wifiDisplayStatus.getScanState() == WifiDisplayStatus.SCAN_STATE_SCANNING;
|
||||||
|
|
||||||
|
boolean changed = false;
|
||||||
|
int newStatus = RouteInfo.STATUS_NONE;
|
||||||
|
|
||||||
|
if (available) {
|
||||||
|
newStatus = isScanning ? RouteInfo.STATUS_SCANNING : RouteInfo.STATUS_AVAILABLE;
|
||||||
|
} else {
|
||||||
|
newStatus = RouteInfo.STATUS_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (display.equals(wifiDisplayStatus.getActiveDisplay())) {
|
||||||
|
final int activeState = wifiDisplayStatus.getActiveDisplayState();
|
||||||
|
switch (activeState) {
|
||||||
|
case WifiDisplayStatus.DISPLAY_STATE_CONNECTED:
|
||||||
|
newStatus = RouteInfo.STATUS_NONE;
|
||||||
|
break;
|
||||||
|
case WifiDisplayStatus.DISPLAY_STATE_CONNECTING:
|
||||||
|
newStatus = RouteInfo.STATUS_CONNECTING;
|
||||||
|
break;
|
||||||
|
case WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED:
|
||||||
|
Log.e(TAG, "Active display is not connected!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final String newName = makeWifiDisplayName(display);
|
||||||
|
if (route.getName().equals(newName)) {
|
||||||
|
route.mName = newName;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
changed |= route.mEnabled != available;
|
||||||
|
route.mEnabled = available;
|
||||||
|
|
||||||
|
changed |= route.setStatusCode(newStatus);
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
dispatchRouteChanged(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!available && route == sStatic.mSelectedRoute) {
|
||||||
|
// Oops, no longer available. Reselect the default.
|
||||||
|
final RouteInfo defaultRoute = sStatic.mDefaultAudioVideo;
|
||||||
|
selectRouteStatic(defaultRoute.getSupportedTypes(), defaultRoute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static WifiDisplay findMatchingDisplay(WifiDisplay address, WifiDisplay[] displays) {
|
||||||
|
for (int i = 0; i < displays.length; i++) {
|
||||||
|
final WifiDisplay d = displays[i];
|
||||||
|
if (d.equals(address)) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RouteInfo findWifiDisplayRoute(WifiDisplay d) {
|
||||||
|
final int count = sStatic.mRoutes.size();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
final RouteInfo info = sStatic.mRoutes.get(i);
|
||||||
|
if (d.getDeviceAddress().equals(info.mDeviceAddress)) {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about a media route.
|
* Information about a media route.
|
||||||
*/
|
*/
|
||||||
@@ -644,6 +834,18 @@ public class MediaRouter {
|
|||||||
int mPlaybackStream = AudioManager.STREAM_MUSIC;
|
int mPlaybackStream = AudioManager.STREAM_MUSIC;
|
||||||
VolumeCallbackInfo mVcb;
|
VolumeCallbackInfo mVcb;
|
||||||
|
|
||||||
|
String mDeviceAddress;
|
||||||
|
boolean mEnabled = true;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
private Object mTag;
|
private Object mTag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -710,6 +912,34 @@ public class MediaRouter {
|
|||||||
return mStatus;
|
return mStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this route's status by predetermined status code. If the caller
|
||||||
|
* should dispatch a route changed event this call will return true;
|
||||||
|
*/
|
||||||
|
boolean setStatusCode(int statusCode) {
|
||||||
|
if (statusCode != mStatusCode) {
|
||||||
|
mStatusCode = statusCode;
|
||||||
|
int resId = 0;
|
||||||
|
switch (statusCode) {
|
||||||
|
case STATUS_SCANNING:
|
||||||
|
resId = com.android.internal.R.string.media_route_status_scanning;
|
||||||
|
break;
|
||||||
|
case STATUS_CONNECTING:
|
||||||
|
resId = com.android.internal.R.string.media_route_status_connecting;
|
||||||
|
break;
|
||||||
|
case STATUS_AVAILABLE:
|
||||||
|
resId = com.android.internal.R.string.media_route_status_available;
|
||||||
|
break;
|
||||||
|
case STATUS_NOT_AVAILABLE:
|
||||||
|
resId = com.android.internal.R.string.media_route_status_not_available;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mStatus = resId != 0 ? sStatic.mResources.getText(resId) : null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return A media type flag set describing which types this route supports.
|
* @return A media type flag set describing which types this route supports.
|
||||||
*/
|
*/
|
||||||
@@ -866,6 +1096,13 @@ public class MediaRouter {
|
|||||||
return mVolumeHandling;
|
return mVolumeHandling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this route is enabled and may be selected
|
||||||
|
*/
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return mEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
void setStatusInt(CharSequence status) {
|
void setStatusInt(CharSequence status) {
|
||||||
if (!status.equals(mStatus)) {
|
if (!status.equals(mStatus)) {
|
||||||
mStatus = status;
|
mStatus = status;
|
||||||
@@ -881,7 +1118,6 @@ public class MediaRouter {
|
|||||||
sStatic.mHandler.post(new Runnable() {
|
sStatic.mHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
//Log.d(TAG, "dispatchRemoteVolumeUpdate dir=" + direction + " val=" + value);
|
|
||||||
if (mVcb != null) {
|
if (mVcb != null) {
|
||||||
if (direction != 0) {
|
if (direction != 0) {
|
||||||
mVcb.vcb.onVolumeUpdateRequest(mVcb.route, direction);
|
mVcb.vcb.onVolumeUpdateRequest(mVcb.route, direction);
|
||||||
@@ -1400,6 +1636,7 @@ public class MediaRouter {
|
|||||||
int mNameResId;
|
int mNameResId;
|
||||||
int mTypes;
|
int mTypes;
|
||||||
final boolean mGroupable;
|
final boolean mGroupable;
|
||||||
|
boolean mIsSystem;
|
||||||
|
|
||||||
RouteCategory(CharSequence name, int types, boolean groupable) {
|
RouteCategory(CharSequence name, int types, boolean groupable) {
|
||||||
mName = name;
|
mName = name;
|
||||||
@@ -1486,6 +1723,14 @@ public class MediaRouter {
|
|||||||
return mGroupable;
|
return mGroupable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this is the category reserved for system routes.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public boolean isSystem() {
|
||||||
|
return mIsSystem;
|
||||||
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "RouteCategory{ name=" + mName + " types=" + typesToString(mTypes) +
|
return "RouteCategory{ name=" + mName + " types=" + typesToString(mTypes) +
|
||||||
" groupable=" + mGroupable + " }";
|
" groupable=" + mGroupable + " }";
|
||||||
@@ -1671,7 +1916,6 @@ public class MediaRouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static class VolumeChangeReceiver extends BroadcastReceiver {
|
static class VolumeChangeReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
if (intent.getAction().equals(AudioManager.VOLUME_CHANGED_ACTION)) {
|
if (intent.getAction().equals(AudioManager.VOLUME_CHANGED_ACTION)) {
|
||||||
@@ -1689,6 +1933,15 @@ public class MediaRouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class WifiDisplayStatusChangedReceiver extends BroadcastReceiver {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
if (intent.getAction().equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) {
|
||||||
|
updateWifiDisplayStatus((WifiDisplayStatus) intent.getParcelableExtra(
|
||||||
|
DisplayManager.EXTRA_WIFI_DISPLAY_STATUS));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user