UI tweaks.
Hide disabled routes from the chooser. Fix layout of chooser dialog when the settings button is visible and the list is very long to prevent truncation of the settings button. Fix an issue when we fake the route connecting status when a route is selected. The route changed notification needs to be propagated to apps. Fake it better. Immediately disconnect from a route when the connection is lost or a connection attempt fails. Added a few new test displays for this case. Bug: 11257292 Change-Id: I360ab5dc937ad60d97592eab54b19f034519645e
This commit is contained in:
@ -106,8 +106,8 @@ public class MediaRouteChooserDialog extends Dialog {
|
|||||||
/**
|
/**
|
||||||
* Returns true if the route should be included in the list.
|
* Returns true if the route should be included in the list.
|
||||||
* <p>
|
* <p>
|
||||||
* The default implementation returns true for non-default routes that
|
* The default implementation returns true for enabled non-default routes that
|
||||||
* match the selector. Subclasses can override this method to filter routes
|
* match the route types. Subclasses can override this method to filter routes
|
||||||
* differently.
|
* differently.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
@ -115,7 +115,7 @@ public class MediaRouteChooserDialog extends Dialog {
|
|||||||
* @return True if the route should be included in the chooser dialog.
|
* @return True if the route should be included in the chooser dialog.
|
||||||
*/
|
*/
|
||||||
public boolean onFilterRoute(MediaRouter.RouteInfo route) {
|
public boolean onFilterRoute(MediaRouter.RouteInfo route) {
|
||||||
return !route.isDefault() && route.matchesTypes(mRouteTypes);
|
return !route.isDefault() && route.isEnabled() && route.matchesTypes(mRouteTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -23,7 +23,8 @@
|
|||||||
<!-- List of routes. -->
|
<!-- List of routes. -->
|
||||||
<ListView android:id="@+id/media_route_list"
|
<ListView android:id="@+id/media_route_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
<!-- Content to show when list is empty. -->
|
<!-- Content to show when list is empty. -->
|
||||||
<LinearLayout android:id="@android:id/empty"
|
<LinearLayout android:id="@android:id/empty"
|
||||||
|
@ -469,7 +469,7 @@ public class MediaRouter {
|
|||||||
route.mDescription = globalRoute.description;
|
route.mDescription = globalRoute.description;
|
||||||
route.mSupportedTypes = globalRoute.supportedTypes;
|
route.mSupportedTypes = globalRoute.supportedTypes;
|
||||||
route.mEnabled = globalRoute.enabled;
|
route.mEnabled = globalRoute.enabled;
|
||||||
route.setStatusCode(globalRoute.statusCode);
|
route.setRealStatusCode(globalRoute.statusCode);
|
||||||
route.mPlaybackType = globalRoute.playbackType;
|
route.mPlaybackType = globalRoute.playbackType;
|
||||||
route.mPlaybackStream = globalRoute.playbackStream;
|
route.mPlaybackStream = globalRoute.playbackStream;
|
||||||
route.mVolume = globalRoute.volume;
|
route.mVolume = globalRoute.volume;
|
||||||
@ -501,8 +501,8 @@ public class MediaRouter {
|
|||||||
route.mEnabled = globalRoute.enabled;
|
route.mEnabled = globalRoute.enabled;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
if (route.mStatusCode != globalRoute.statusCode) {
|
if (route.mRealStatusCode != globalRoute.statusCode) {
|
||||||
route.setStatusCode(globalRoute.statusCode);
|
route.setRealStatusCode(globalRoute.statusCode);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
if (route.mPlaybackType != globalRoute.playbackType) {
|
if (route.mPlaybackType != globalRoute.playbackType) {
|
||||||
@ -918,8 +918,14 @@ public class MediaRouter {
|
|||||||
|
|
||||||
if (oldRoute != null) {
|
if (oldRoute != null) {
|
||||||
dispatchRouteUnselected(types & oldRoute.getSupportedTypes(), oldRoute);
|
dispatchRouteUnselected(types & oldRoute.getSupportedTypes(), oldRoute);
|
||||||
|
if (oldRoute.resolveStatusCode()) {
|
||||||
|
dispatchRouteChanged(oldRoute);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (route != null) {
|
if (route != null) {
|
||||||
|
if (route.resolveStatusCode()) {
|
||||||
|
dispatchRouteChanged(route);
|
||||||
|
}
|
||||||
dispatchRouteSelected(types & route.getSupportedTypes(), route);
|
dispatchRouteSelected(types & route.getSupportedTypes(), route);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1337,7 +1343,7 @@ public class MediaRouter {
|
|||||||
newRoute.mVolumeHandling = RouteInfo.PLAYBACK_VOLUME_FIXED;
|
newRoute.mVolumeHandling = RouteInfo.PLAYBACK_VOLUME_FIXED;
|
||||||
newRoute.mPlaybackType = RouteInfo.PLAYBACK_TYPE_REMOTE;
|
newRoute.mPlaybackType = RouteInfo.PLAYBACK_TYPE_REMOTE;
|
||||||
|
|
||||||
newRoute.setStatusCode(getWifiDisplayStatusCode(display, wfdStatus));
|
newRoute.setRealStatusCode(getWifiDisplayStatusCode(display, wfdStatus));
|
||||||
newRoute.mEnabled = isWifiDisplayEnabled(display, wfdStatus);
|
newRoute.mEnabled = isWifiDisplayEnabled(display, wfdStatus);
|
||||||
newRoute.mName = display.getFriendlyDisplayName();
|
newRoute.mName = display.getFriendlyDisplayName();
|
||||||
newRoute.mDescription = sStatic.mResources.getText(
|
newRoute.mDescription = sStatic.mResources.getText(
|
||||||
@ -1359,7 +1365,7 @@ public class MediaRouter {
|
|||||||
changed |= route.mEnabled != enabled;
|
changed |= route.mEnabled != enabled;
|
||||||
route.mEnabled = enabled;
|
route.mEnabled = enabled;
|
||||||
|
|
||||||
changed |= route.setStatusCode(getWifiDisplayStatusCode(display, wfdStatus));
|
changed |= route.setRealStatusCode(getWifiDisplayStatusCode(display, wfdStatus));
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
dispatchRouteChanged(route);
|
dispatchRouteChanged(route);
|
||||||
@ -1422,7 +1428,8 @@ public class MediaRouter {
|
|||||||
String mGlobalRouteId;
|
String mGlobalRouteId;
|
||||||
|
|
||||||
// A predetermined connection status that can override mStatus
|
// A predetermined connection status that can override mStatus
|
||||||
private int mStatusCode;
|
private int mRealStatusCode;
|
||||||
|
private int mResolvedStatusCode;
|
||||||
|
|
||||||
/** @hide */ public static final int STATUS_NONE = 0;
|
/** @hide */ public static final int STATUS_NONE = 0;
|
||||||
/** @hide */ public static final int STATUS_SCANNING = 1;
|
/** @hide */ public static final int STATUS_SCANNING = 1;
|
||||||
@ -1526,43 +1533,71 @@ public class MediaRouter {
|
|||||||
* Set this route's status by predetermined status code. If the caller
|
* Set this route's status by predetermined status code. If the caller
|
||||||
* should dispatch a route changed event this call will return true;
|
* should dispatch a route changed event this call will return true;
|
||||||
*/
|
*/
|
||||||
boolean setStatusCode(int statusCode) {
|
boolean setRealStatusCode(int statusCode) {
|
||||||
if (statusCode != mStatusCode) {
|
if (mRealStatusCode != statusCode) {
|
||||||
mStatusCode = statusCode;
|
mRealStatusCode = statusCode;
|
||||||
int resId;
|
return resolveStatusCode();
|
||||||
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;
|
|
||||||
case STATUS_IN_USE:
|
|
||||||
resId = com.android.internal.R.string.media_route_status_in_use;
|
|
||||||
break;
|
|
||||||
case STATUS_CONNECTED:
|
|
||||||
case STATUS_NONE:
|
|
||||||
default:
|
|
||||||
resId = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mStatus = resId != 0 ? sStatic.mResources.getText(resId) : null;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves the status code whenever the real status code or selection state
|
||||||
|
* changes.
|
||||||
|
*/
|
||||||
|
boolean resolveStatusCode() {
|
||||||
|
int statusCode = mRealStatusCode;
|
||||||
|
if (isSelected()) {
|
||||||
|
switch (statusCode) {
|
||||||
|
// If the route is selected and its status appears to be between states
|
||||||
|
// then report it as connecting even though it has not yet had a chance
|
||||||
|
// to officially move into the CONNECTING state. Note that routes in
|
||||||
|
// the NONE state are assumed to not require an explicit connection
|
||||||
|
// lifecycle whereas those that are AVAILABLE are assumed to have
|
||||||
|
// to eventually proceed to CONNECTED.
|
||||||
|
case STATUS_AVAILABLE:
|
||||||
|
case STATUS_SCANNING:
|
||||||
|
statusCode = STATUS_CONNECTING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mResolvedStatusCode == statusCode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mResolvedStatusCode = statusCode;
|
||||||
|
int resId;
|
||||||
|
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;
|
||||||
|
case STATUS_IN_USE:
|
||||||
|
resId = com.android.internal.R.string.media_route_status_in_use;
|
||||||
|
break;
|
||||||
|
case STATUS_CONNECTED:
|
||||||
|
case STATUS_NONE:
|
||||||
|
default:
|
||||||
|
resId = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mStatus = resId != 0 ? sStatic.mResources.getText(resId) : null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public int getStatusCode() {
|
public int getStatusCode() {
|
||||||
return mStatusCode;
|
return mResolvedStatusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1821,19 +1856,7 @@ public class MediaRouter {
|
|||||||
* @return True if this route is in the process of connecting.
|
* @return True if this route is in the process of connecting.
|
||||||
*/
|
*/
|
||||||
public boolean isConnecting() {
|
public boolean isConnecting() {
|
||||||
// If the route is selected and its status appears to be between states
|
return mResolvedStatusCode == STATUS_CONNECTING;
|
||||||
// then report it as connecting even though it has not yet had a chance
|
|
||||||
// to move into the CONNECTING state. Note that routes in the NONE state
|
|
||||||
// are assumed to not require an explicit connection lifecycle.
|
|
||||||
if (isSelected()) {
|
|
||||||
switch (mStatusCode) {
|
|
||||||
case STATUS_AVAILABLE:
|
|
||||||
case STATUS_SCANNING:
|
|
||||||
case STATUS_CONNECTING:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.media.remotedisplay;
|
package com.android.media.remotedisplay;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -27,6 +28,7 @@ import android.os.IBinder;
|
|||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
import android.provider.Settings;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -95,6 +97,7 @@ public abstract class RemoteDisplayProvider {
|
|||||||
private static final int MSG_SET_VOLUME = 5;
|
private static final int MSG_SET_VOLUME = 5;
|
||||||
private static final int MSG_ADJUST_VOLUME = 6;
|
private static final int MSG_ADJUST_VOLUME = 6;
|
||||||
|
|
||||||
|
private final Context mContext;
|
||||||
private final ProviderStub mStub;
|
private final ProviderStub mStub;
|
||||||
private final ProviderHandler mHandler;
|
private final ProviderHandler mHandler;
|
||||||
private final ArrayMap<String, RemoteDisplay> mDisplays =
|
private final ArrayMap<String, RemoteDisplay> mDisplays =
|
||||||
@ -102,6 +105,8 @@ public abstract class RemoteDisplayProvider {
|
|||||||
private IRemoteDisplayCallback mCallback;
|
private IRemoteDisplayCallback mCallback;
|
||||||
private int mDiscoveryMode = DISCOVERY_MODE_NONE;
|
private int mDiscoveryMode = DISCOVERY_MODE_NONE;
|
||||||
|
|
||||||
|
private PendingIntent mSettingsPendingIntent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link Intent} that must be declared as handled by the service.
|
* The {@link Intent} that must be declared as handled by the service.
|
||||||
* Put this in your manifest.
|
* Put this in your manifest.
|
||||||
@ -140,10 +145,18 @@ public abstract class RemoteDisplayProvider {
|
|||||||
* @param context The application context for the remote display provider.
|
* @param context The application context for the remote display provider.
|
||||||
*/
|
*/
|
||||||
public RemoteDisplayProvider(Context context) {
|
public RemoteDisplayProvider(Context context) {
|
||||||
|
mContext = context;
|
||||||
mStub = new ProviderStub();
|
mStub = new ProviderStub();
|
||||||
mHandler = new ProviderHandler(context.getMainLooper());
|
mHandler = new ProviderHandler(context.getMainLooper());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the context of the remote display provider.
|
||||||
|
*/
|
||||||
|
public final Context getContext() {
|
||||||
|
return mContext;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Binder associated with the provider.
|
* Gets the Binder associated with the provider.
|
||||||
* <p>
|
* <p>
|
||||||
@ -261,11 +274,29 @@ public abstract class RemoteDisplayProvider {
|
|||||||
* Finds the remote display with the specified id, returns null if not found.
|
* Finds the remote display with the specified id, returns null if not found.
|
||||||
*
|
*
|
||||||
* @param id Id of the remote display.
|
* @param id Id of the remote display.
|
||||||
|
* @return The display, or null if none.
|
||||||
*/
|
*/
|
||||||
public RemoteDisplay findRemoteDisplay(String id) {
|
public RemoteDisplay findRemoteDisplay(String id) {
|
||||||
return mDisplays.get(id);
|
return mDisplays.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a pending intent to launch the remote display settings activity.
|
||||||
|
*
|
||||||
|
* @return A pending intent to launch the settings activity.
|
||||||
|
*/
|
||||||
|
public PendingIntent getSettingsPendingIntent() {
|
||||||
|
if (mSettingsPendingIntent == null) {
|
||||||
|
Intent settingsIntent = new Intent(Settings.ACTION_WIFI_DISPLAY_SETTINGS);
|
||||||
|
settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
|
||||||
|
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
|
mSettingsPendingIntent = PendingIntent.getActivity(
|
||||||
|
mContext, 0, settingsIntent, 0, null);
|
||||||
|
}
|
||||||
|
return mSettingsPendingIntent;
|
||||||
|
}
|
||||||
|
|
||||||
void setCallback(IRemoteDisplayCallback callback) {
|
void setCallback(IRemoteDisplayCallback callback) {
|
||||||
mCallback = callback;
|
mCallback = callback;
|
||||||
publishState();
|
publishState();
|
||||||
|
@ -600,8 +600,16 @@ public final class MediaRouterService extends IMediaRouterService.Stub
|
|||||||
private static final int MSG_CONNECTION_TIMED_OUT = 9;
|
private static final int MSG_CONNECTION_TIMED_OUT = 9;
|
||||||
|
|
||||||
private static final int TIMEOUT_REASON_NOT_AVAILABLE = 1;
|
private static final int TIMEOUT_REASON_NOT_AVAILABLE = 1;
|
||||||
private static final int TIMEOUT_REASON_WAITING_FOR_CONNECTING = 2;
|
private static final int TIMEOUT_REASON_CONNECTION_LOST = 2;
|
||||||
private static final int TIMEOUT_REASON_WAITING_FOR_CONNECTED = 3;
|
private static final int TIMEOUT_REASON_WAITING_FOR_CONNECTING = 3;
|
||||||
|
private static final int TIMEOUT_REASON_WAITING_FOR_CONNECTED = 4;
|
||||||
|
|
||||||
|
// The relative order of these constants is important and expresses progress
|
||||||
|
// through the process of connecting to a route.
|
||||||
|
private static final int PHASE_NOT_AVAILABLE = -1;
|
||||||
|
private static final int PHASE_NOT_CONNECTED = 0;
|
||||||
|
private static final int PHASE_CONNECTING = 1;
|
||||||
|
private static final int PHASE_CONNECTED = 2;
|
||||||
|
|
||||||
private final MediaRouterService mService;
|
private final MediaRouterService mService;
|
||||||
private final UserRecord mUserRecord;
|
private final UserRecord mUserRecord;
|
||||||
@ -614,6 +622,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub
|
|||||||
private boolean mRunning;
|
private boolean mRunning;
|
||||||
private int mDiscoveryMode = RemoteDisplayState.DISCOVERY_MODE_NONE;
|
private int mDiscoveryMode = RemoteDisplayState.DISCOVERY_MODE_NONE;
|
||||||
private RouteRecord mGloballySelectedRouteRecord;
|
private RouteRecord mGloballySelectedRouteRecord;
|
||||||
|
private int mConnectionPhase = PHASE_NOT_AVAILABLE;
|
||||||
private int mConnectionTimeoutReason;
|
private int mConnectionTimeoutReason;
|
||||||
private long mConnectionTimeoutStartTime;
|
private long mConnectionTimeoutStartTime;
|
||||||
private boolean mClientStateUpdateScheduled;
|
private boolean mClientStateUpdateScheduled;
|
||||||
@ -675,6 +684,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub
|
|||||||
pw.println(indent + "mRunning=" + mRunning);
|
pw.println(indent + "mRunning=" + mRunning);
|
||||||
pw.println(indent + "mDiscoveryMode=" + mDiscoveryMode);
|
pw.println(indent + "mDiscoveryMode=" + mDiscoveryMode);
|
||||||
pw.println(indent + "mGloballySelectedRouteRecord=" + mGloballySelectedRouteRecord);
|
pw.println(indent + "mGloballySelectedRouteRecord=" + mGloballySelectedRouteRecord);
|
||||||
|
pw.println(indent + "mConnectionPhase=" + mConnectionPhase);
|
||||||
pw.println(indent + "mConnectionTimeoutReason=" + mConnectionTimeoutReason);
|
pw.println(indent + "mConnectionTimeoutReason=" + mConnectionTimeoutReason);
|
||||||
pw.println(indent + "mConnectionTimeoutStartTime=" + (mConnectionTimeoutReason != 0 ?
|
pw.println(indent + "mConnectionTimeoutStartTime=" + (mConnectionTimeoutReason != 0 ?
|
||||||
TimeUtils.formatUptime(mConnectionTimeoutStartTime) : "<n/a>"));
|
TimeUtils.formatUptime(mConnectionTimeoutStartTime) : "<n/a>"));
|
||||||
@ -843,6 +853,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub
|
|||||||
private void checkGloballySelectedRouteState() {
|
private void checkGloballySelectedRouteState() {
|
||||||
// Unschedule timeouts when the route is unselected.
|
// Unschedule timeouts when the route is unselected.
|
||||||
if (mGloballySelectedRouteRecord == null) {
|
if (mGloballySelectedRouteRecord == null) {
|
||||||
|
mConnectionPhase = PHASE_NOT_AVAILABLE;
|
||||||
updateConnectionTimeout(0);
|
updateConnectionTimeout(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -854,29 +865,34 @@ public final class MediaRouterService extends IMediaRouterService.Stub
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure we haven't lost our connection.
|
||||||
|
final int oldPhase = mConnectionPhase;
|
||||||
|
mConnectionPhase = getConnectionPhase(mGloballySelectedRouteRecord.getStatus());
|
||||||
|
if (oldPhase >= PHASE_CONNECTING && mConnectionPhase < PHASE_CONNECTING) {
|
||||||
|
updateConnectionTimeout(TIMEOUT_REASON_CONNECTION_LOST);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check the route status.
|
// Check the route status.
|
||||||
switch (mGloballySelectedRouteRecord.getStatus()) {
|
switch (mConnectionPhase) {
|
||||||
case MediaRouter.RouteInfo.STATUS_NONE:
|
case PHASE_CONNECTED:
|
||||||
case MediaRouter.RouteInfo.STATUS_CONNECTED:
|
if (oldPhase != PHASE_CONNECTED) {
|
||||||
if (mConnectionTimeoutReason != 0) {
|
|
||||||
Slog.i(TAG, "Connected to global route: "
|
Slog.i(TAG, "Connected to global route: "
|
||||||
+ mGloballySelectedRouteRecord);
|
+ mGloballySelectedRouteRecord);
|
||||||
}
|
}
|
||||||
updateConnectionTimeout(0);
|
updateConnectionTimeout(0);
|
||||||
break;
|
break;
|
||||||
case MediaRouter.RouteInfo.STATUS_CONNECTING:
|
case PHASE_CONNECTING:
|
||||||
if (mConnectionTimeoutReason != 0) {
|
if (oldPhase != PHASE_CONNECTING) {
|
||||||
Slog.i(TAG, "Connecting to global route: "
|
Slog.i(TAG, "Connecting to global route: "
|
||||||
+ mGloballySelectedRouteRecord);
|
+ mGloballySelectedRouteRecord);
|
||||||
}
|
}
|
||||||
updateConnectionTimeout(TIMEOUT_REASON_WAITING_FOR_CONNECTED);
|
updateConnectionTimeout(TIMEOUT_REASON_WAITING_FOR_CONNECTED);
|
||||||
break;
|
break;
|
||||||
case MediaRouter.RouteInfo.STATUS_SCANNING:
|
case PHASE_NOT_CONNECTED:
|
||||||
case MediaRouter.RouteInfo.STATUS_AVAILABLE:
|
|
||||||
updateConnectionTimeout(TIMEOUT_REASON_WAITING_FOR_CONNECTING);
|
updateConnectionTimeout(TIMEOUT_REASON_WAITING_FOR_CONNECTING);
|
||||||
break;
|
break;
|
||||||
case MediaRouter.RouteInfo.STATUS_NOT_AVAILABLE:
|
case PHASE_NOT_AVAILABLE:
|
||||||
case MediaRouter.RouteInfo.STATUS_IN_USE:
|
|
||||||
default:
|
default:
|
||||||
updateConnectionTimeout(TIMEOUT_REASON_NOT_AVAILABLE);
|
updateConnectionTimeout(TIMEOUT_REASON_NOT_AVAILABLE);
|
||||||
break;
|
break;
|
||||||
@ -892,7 +908,9 @@ public final class MediaRouterService extends IMediaRouterService.Stub
|
|||||||
mConnectionTimeoutStartTime = SystemClock.uptimeMillis();
|
mConnectionTimeoutStartTime = SystemClock.uptimeMillis();
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case TIMEOUT_REASON_NOT_AVAILABLE:
|
case TIMEOUT_REASON_NOT_AVAILABLE:
|
||||||
// Route became unavailable. Unselect it immediately.
|
case TIMEOUT_REASON_CONNECTION_LOST:
|
||||||
|
// Route became unavailable or connection lost.
|
||||||
|
// Unselect it immediately.
|
||||||
sendEmptyMessage(MSG_CONNECTION_TIMED_OUT);
|
sendEmptyMessage(MSG_CONNECTION_TIMED_OUT);
|
||||||
break;
|
break;
|
||||||
case TIMEOUT_REASON_WAITING_FOR_CONNECTING:
|
case TIMEOUT_REASON_WAITING_FOR_CONNECTING:
|
||||||
@ -919,6 +937,10 @@ public final class MediaRouterService extends IMediaRouterService.Stub
|
|||||||
Slog.i(TAG, "Global route no longer available: "
|
Slog.i(TAG, "Global route no longer available: "
|
||||||
+ mGloballySelectedRouteRecord);
|
+ mGloballySelectedRouteRecord);
|
||||||
break;
|
break;
|
||||||
|
case TIMEOUT_REASON_CONNECTION_LOST:
|
||||||
|
Slog.i(TAG, "Global route connection lost: "
|
||||||
|
+ mGloballySelectedRouteRecord);
|
||||||
|
break;
|
||||||
case TIMEOUT_REASON_WAITING_FOR_CONNECTING:
|
case TIMEOUT_REASON_WAITING_FOR_CONNECTING:
|
||||||
Slog.i(TAG, "Global route timed out while waiting for "
|
Slog.i(TAG, "Global route timed out while waiting for "
|
||||||
+ "connection attempt to begin after "
|
+ "connection attempt to begin after "
|
||||||
@ -1004,6 +1026,23 @@ public final class MediaRouterService extends IMediaRouterService.Stub
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int getConnectionPhase(int status) {
|
||||||
|
switch (status) {
|
||||||
|
case MediaRouter.RouteInfo.STATUS_NONE:
|
||||||
|
case MediaRouter.RouteInfo.STATUS_CONNECTED:
|
||||||
|
return PHASE_CONNECTED;
|
||||||
|
case MediaRouter.RouteInfo.STATUS_CONNECTING:
|
||||||
|
return PHASE_CONNECTING;
|
||||||
|
case MediaRouter.RouteInfo.STATUS_SCANNING:
|
||||||
|
case MediaRouter.RouteInfo.STATUS_AVAILABLE:
|
||||||
|
return PHASE_NOT_CONNECTED;
|
||||||
|
case MediaRouter.RouteInfo.STATUS_NOT_AVAILABLE:
|
||||||
|
case MediaRouter.RouteInfo.STATUS_IN_USE:
|
||||||
|
default:
|
||||||
|
return PHASE_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static final class ProviderRecord {
|
static final class ProviderRecord {
|
||||||
private final RemoteDisplayProviderProxy mProvider;
|
private final RemoteDisplayProviderProxy mProvider;
|
||||||
private final String mUniquePrefix;
|
private final String mUniquePrefix;
|
||||||
|
@ -52,6 +52,9 @@ public class RemoteDisplayProviderService extends Service {
|
|||||||
private RemoteDisplay mTestDisplay5; // available but ignores request to connect
|
private RemoteDisplay mTestDisplay5; // available but ignores request to connect
|
||||||
private RemoteDisplay mTestDisplay6; // available but never finishes connecting
|
private RemoteDisplay mTestDisplay6; // available but never finishes connecting
|
||||||
private RemoteDisplay mTestDisplay7; // blinks in and out of existence
|
private RemoteDisplay mTestDisplay7; // blinks in and out of existence
|
||||||
|
private RemoteDisplay mTestDisplay8; // available but connecting attempt flakes out
|
||||||
|
private RemoteDisplay mTestDisplay9; // available but connection flakes out
|
||||||
|
private RemoteDisplay mTestDisplay10; // available and reconnects periodically
|
||||||
|
|
||||||
private final Handler mHandler;
|
private final Handler mHandler;
|
||||||
private boolean mBlinking;
|
private boolean mBlinking;
|
||||||
@ -112,6 +115,27 @@ public class RemoteDisplayProviderService extends Service {
|
|||||||
mTestDisplay6.setStatus(RemoteDisplay.STATUS_AVAILABLE);
|
mTestDisplay6.setStatus(RemoteDisplay.STATUS_AVAILABLE);
|
||||||
addDisplay(mTestDisplay6);
|
addDisplay(mTestDisplay6);
|
||||||
}
|
}
|
||||||
|
if (mTestDisplay8 == null) {
|
||||||
|
mTestDisplay8 = new RemoteDisplay("testDisplay8",
|
||||||
|
"Test Display 8 (flaky when connecting)");
|
||||||
|
mTestDisplay8.setDescription("Aborts spontaneously while connecting");
|
||||||
|
mTestDisplay8.setStatus(RemoteDisplay.STATUS_AVAILABLE);
|
||||||
|
addDisplay(mTestDisplay8);
|
||||||
|
}
|
||||||
|
if (mTestDisplay9 == null) {
|
||||||
|
mTestDisplay9 = new RemoteDisplay("testDisplay9",
|
||||||
|
"Test Display 9 (flaky when connected)");
|
||||||
|
mTestDisplay9.setDescription("Aborts spontaneously while connected");
|
||||||
|
mTestDisplay9.setStatus(RemoteDisplay.STATUS_AVAILABLE);
|
||||||
|
addDisplay(mTestDisplay9);
|
||||||
|
}
|
||||||
|
if (mTestDisplay10 == null) {
|
||||||
|
mTestDisplay10 = new RemoteDisplay("testDisplay10",
|
||||||
|
"Test Display 10 (reconnects periodically)");
|
||||||
|
mTestDisplay10.setDescription("Reconnects spontaneously");
|
||||||
|
mTestDisplay10.setStatus(RemoteDisplay.STATUS_AVAILABLE);
|
||||||
|
addDisplay(mTestDisplay10);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// When discovery ends, go hide some of the routes we can't actually use.
|
// When discovery ends, go hide some of the routes we can't actually use.
|
||||||
// This isn't something a normal route provider would do though.
|
// This isn't something a normal route provider would do though.
|
||||||
@ -144,6 +168,7 @@ public class RemoteDisplayProviderService extends Service {
|
|||||||
|
|
||||||
if (display == mTestDisplay1 || display == mTestDisplay2) {
|
if (display == mTestDisplay1 || display == mTestDisplay2) {
|
||||||
display.setStatus(RemoteDisplay.STATUS_CONNECTING);
|
display.setStatus(RemoteDisplay.STATUS_CONNECTING);
|
||||||
|
updateDisplay(display);
|
||||||
mHandler.postDelayed(new Runnable() {
|
mHandler.postDelayed(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -154,12 +179,67 @@ public class RemoteDisplayProviderService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 2000);
|
}, 2000);
|
||||||
updateDisplay(display);
|
} else if (display == mTestDisplay6 || display == mTestDisplay7) {
|
||||||
}
|
|
||||||
if (display == mTestDisplay6 || display == mTestDisplay7) {
|
|
||||||
// never finishes connecting
|
// never finishes connecting
|
||||||
display.setStatus(RemoteDisplay.STATUS_CONNECTING);
|
display.setStatus(RemoteDisplay.STATUS_CONNECTING);
|
||||||
updateDisplay(display);
|
updateDisplay(display);
|
||||||
|
} else if (display == mTestDisplay8) {
|
||||||
|
// flakes out while connecting
|
||||||
|
display.setStatus(RemoteDisplay.STATUS_CONNECTING);
|
||||||
|
updateDisplay(display);
|
||||||
|
mHandler.postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if ((display == mTestDisplay8)
|
||||||
|
&& display.getStatus() == RemoteDisplay.STATUS_CONNECTING) {
|
||||||
|
display.setStatus(RemoteDisplay.STATUS_AVAILABLE);
|
||||||
|
updateDisplay(display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
} else if (display == mTestDisplay9) {
|
||||||
|
// flakes out when connected
|
||||||
|
display.setStatus(RemoteDisplay.STATUS_CONNECTING);
|
||||||
|
updateDisplay(display);
|
||||||
|
mHandler.postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if ((display == mTestDisplay9)
|
||||||
|
&& display.getStatus() == RemoteDisplay.STATUS_CONNECTING) {
|
||||||
|
display.setStatus(RemoteDisplay.STATUS_CONNECTED);
|
||||||
|
updateDisplay(display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
mHandler.postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if ((display == mTestDisplay9)
|
||||||
|
&& display.getStatus() == RemoteDisplay.STATUS_CONNECTED) {
|
||||||
|
display.setStatus(RemoteDisplay.STATUS_AVAILABLE);
|
||||||
|
updateDisplay(display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
} else if (display == mTestDisplay10) {
|
||||||
|
display.setStatus(RemoteDisplay.STATUS_CONNECTING);
|
||||||
|
updateDisplay(display);
|
||||||
|
mHandler.postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (display == mTestDisplay10) {
|
||||||
|
if (display.getStatus() == RemoteDisplay.STATUS_CONNECTING) {
|
||||||
|
display.setStatus(RemoteDisplay.STATUS_CONNECTED);
|
||||||
|
updateDisplay(display);
|
||||||
|
mHandler.postDelayed(this, 7000);
|
||||||
|
} else if (display.getStatus() == RemoteDisplay.STATUS_CONNECTED) {
|
||||||
|
display.setStatus(RemoteDisplay.STATUS_CONNECTING);
|
||||||
|
updateDisplay(display);
|
||||||
|
mHandler.postDelayed(this, 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,7 +248,8 @@ public class RemoteDisplayProviderService extends Service {
|
|||||||
Log.d(TAG, "onDisconnect: display.getId()=" + display.getId());
|
Log.d(TAG, "onDisconnect: display.getId()=" + display.getId());
|
||||||
|
|
||||||
if (display == mTestDisplay1 || display == mTestDisplay2
|
if (display == mTestDisplay1 || display == mTestDisplay2
|
||||||
|| display == mTestDisplay6) {
|
|| display == mTestDisplay6 || display == mTestDisplay8
|
||||||
|
|| display == mTestDisplay9 || display == mTestDisplay10) {
|
||||||
display.setStatus(RemoteDisplay.STATUS_AVAILABLE);
|
display.setStatus(RemoteDisplay.STATUS_AVAILABLE);
|
||||||
updateDisplay(display);
|
updateDisplay(display);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user