Merge "CEC: Hook up device select API to MHL device RAP" into lmp-dev
diff --git a/Android.mk b/Android.mk
index 1cdc709..80b860b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -330,12 +330,6 @@
media/java/android/media/projection/IMediaProjectionCallback.aidl \
media/java/android/media/projection/IMediaProjectionManager.aidl \
media/java/android/media/projection/IMediaProjectionWatcherCallback.aidl \
- media/java/android/media/routing/IMediaRouteService.aidl \
- media/java/android/media/routing/IMediaRouteClientCallback.aidl \
- media/java/android/media/routing/IMediaRouter.aidl \
- media/java/android/media/routing/IMediaRouterDelegate.aidl \
- media/java/android/media/routing/IMediaRouterRoutingCallback.aidl \
- media/java/android/media/routing/IMediaRouterStateCallback.aidl \
media/java/android/media/session/IActiveSessionsListener.aidl \
media/java/android/media/session/ISessionController.aidl \
media/java/android/media/session/ISessionControllerCallback.aidl \
@@ -497,7 +491,6 @@
frameworks/base/location/java/com/android/internal/location/ProviderRequest.aidl \
frameworks/base/media/java/android/media/MediaMetadata.aidl \
frameworks/base/media/java/android/media/Rating.aidl \
- frameworks/base/media/java/android/media/routing/MediaRouteSelector.aidl \
frameworks/base/media/java/android/media/session/MediaSession.aidl \
frameworks/base/media/java/android/media/session/PlaybackState.aidl \
frameworks/base/telephony/java/android/telephony/ServiceState.aidl \
diff --git a/api/current.txt b/api/current.txt
index 368dcef..516a2b6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23,7 +23,6 @@
field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE";
field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
- field public static final java.lang.String BIND_MEDIA_ROUTE_SERVICE = "android.permission.BIND_MEDIA_ROUTE_SERVICE";
field public static final java.lang.String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE";
field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
@@ -16380,242 +16379,6 @@
}
-package android.media.routing {
-
- public final class MediaRouteSelector implements android.os.Parcelable {
- method public boolean containsProtocol(java.lang.Class<?>);
- method public boolean containsProtocol(java.lang.String);
- method public int describeContents();
- method public android.os.Bundle getExtras();
- method public int getOptionalFeatures();
- method public java.util.List<java.lang.String> getOptionalProtocols();
- method public int getRequiredFeatures();
- method public java.util.List<java.lang.String> getRequiredProtocols();
- method public java.lang.String getServicePackageName();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator CREATOR;
- }
-
- public static final class MediaRouteSelector.Builder {
- ctor public MediaRouteSelector.Builder();
- method public android.media.routing.MediaRouteSelector.Builder addOptionalProtocol(java.lang.Class<?>);
- method public android.media.routing.MediaRouteSelector.Builder addOptionalProtocol(java.lang.String);
- method public android.media.routing.MediaRouteSelector.Builder addRequiredProtocol(java.lang.Class<?>);
- method public android.media.routing.MediaRouteSelector.Builder addRequiredProtocol(java.lang.String);
- method public android.media.routing.MediaRouteSelector build();
- method public android.media.routing.MediaRouteSelector.Builder setExtras(android.os.Bundle);
- method public android.media.routing.MediaRouteSelector.Builder setOptionalFeatures(int);
- method public android.media.routing.MediaRouteSelector.Builder setRequiredFeatures(int);
- method public android.media.routing.MediaRouteSelector.Builder setServicePackageName(java.lang.String);
- }
-
- public abstract class MediaRouteService extends android.app.Service {
- ctor public MediaRouteService();
- method public android.media.routing.MediaRouter.ServiceMetadata getServiceMetadata();
- method public android.os.IBinder onBind(android.content.Intent);
- method public abstract android.media.routing.MediaRouteService.ClientSession onCreateClientSession(android.media.routing.MediaRouteService.ClientInfo);
- field public static final java.lang.String SERVICE_INTERFACE = "android.media.routing.MediaRouteService";
- }
-
- public static final class MediaRouteService.ClientInfo {
- method public java.lang.String getPackageName();
- method public int getUid();
- }
-
- public static abstract class MediaRouteService.ClientSession {
- ctor public MediaRouteService.ClientSession();
- method public abstract boolean onConnect(android.media.routing.MediaRouter.ConnectionRequest, android.media.routing.MediaRouteService.ConnectionCallback);
- method public abstract void onDisconnect();
- method public void onPauseStream();
- method public void onRelease();
- method public void onResumeStream();
- method public abstract boolean onStartDiscovery(android.media.routing.MediaRouter.DiscoveryRequest, android.media.routing.MediaRouteService.DiscoveryCallback);
- method public abstract void onStopDiscovery();
- }
-
- public final class MediaRouteService.ConnectionCallback {
- method public void onConnected(android.media.routing.MediaRouter.ConnectionInfo);
- method public void onConnectionFailed(int, java.lang.CharSequence, android.os.Bundle);
- method public void onDisconnected();
- }
-
- public final class MediaRouteService.DiscoveryCallback {
- method public void onDestinationFound(android.media.routing.MediaRouter.DestinationInfo, java.util.List<android.media.routing.MediaRouter.RouteInfo>);
- method public void onDestinationLost(android.media.routing.MediaRouter.DestinationInfo);
- method public void onDiscoveryFailed(int, java.lang.CharSequence, android.os.Bundle);
- }
-
- public final class MediaRouter {
- ctor public MediaRouter(android.content.Context);
- method public void addSelector(android.media.routing.MediaRouteSelector);
- method public void clearSelectors();
- method public android.media.routing.MediaRouter.Delegate createDelegate();
- method public android.media.routing.MediaRouter.ConnectionInfo getConnection();
- method public int getConnectionState();
- method public java.util.List<android.media.routing.MediaRouter.DestinationInfo> getDiscoveredDestinations();
- method public java.util.List<android.media.routing.MediaRouter.RouteInfo> getDiscoveredRoutes(android.media.routing.MediaRouter.DestinationInfo);
- method public int getDiscoveryState();
- method public android.media.AudioAttributes getPreferredAudioAttributes();
- method public android.view.Display getPreferredPresentationDisplay();
- method public android.media.VolumeProvider getPreferredVolumeProvider();
- method public android.media.routing.MediaRouter.DestinationInfo getSelectedDestination();
- method public android.media.routing.MediaRouter.RouteInfo getSelectedRoute();
- method public java.util.List<android.media.routing.MediaRouteSelector> getSelectors();
- method public boolean isReleased();
- method public void pauseStream();
- method public void release();
- method public void removeSelector(android.media.routing.MediaRouteSelector);
- method public void resumeStream();
- method public void setRoutingCallback(android.media.routing.MediaRouter.RoutingCallback, android.os.Handler);
- field public static final int CONNECTION_ERROR_ABORTED = 1; // 0x1
- field public static final int CONNECTION_ERROR_BARGED = 7; // 0x7
- field public static final int CONNECTION_ERROR_BROKEN = 6; // 0x6
- field public static final int CONNECTION_ERROR_BUSY = 4; // 0x4
- field public static final int CONNECTION_ERROR_TIMEOUT = 5; // 0x5
- field public static final int CONNECTION_ERROR_UNAUTHORIZED = 2; // 0x2
- field public static final int CONNECTION_ERROR_UNKNOWN = 0; // 0x0
- field public static final int CONNECTION_ERROR_UNREACHABLE = 3; // 0x3
- field public static final int CONNECTION_FLAG_BARGE = 1; // 0x1
- field public static final int CONNECTION_STATE_CONNECTED = 2; // 0x2
- field public static final int CONNECTION_STATE_CONNECTING = 1; // 0x1
- field public static final int CONNECTION_STATE_DISCONNECTED = 0; // 0x0
- field public static final int DISCONNECTION_REASON_APPLICATION_REQUEST = 0; // 0x0
- field public static final int DISCONNECTION_REASON_ERROR = 2; // 0x2
- field public static final int DISCONNECTION_REASON_USER_REQUEST = 1; // 0x1
- field public static final int DISCOVERY_ERROR_ABORTED = 1; // 0x1
- field public static final int DISCOVERY_ERROR_NO_CONNECTIVITY = 2; // 0x2
- field public static final int DISCOVERY_ERROR_UNKNOWN = 0; // 0x0
- field public static final int DISCOVERY_FLAG_BACKGROUND = 1; // 0x1
- field public static final int DISCOVERY_STATE_STARTED = 1; // 0x1
- field public static final int DISCOVERY_STATE_STOPPED = 0; // 0x0
- field public static final int ROUTE_FEATURE_LIVE_AUDIO = 1; // 0x1
- field public static final int ROUTE_FEATURE_LIVE_VIDEO = 2; // 0x2
- }
-
- public static final class MediaRouter.ConnectionInfo {
- method public android.media.AudioAttributes getAudioAttributes();
- method public android.os.Bundle getExtras();
- method public int getFeatures();
- method public android.view.Display getPresentationDisplay();
- method public android.os.IBinder getProtocolBinder(java.lang.String);
- method public android.os.IBinder getProtocolBinder(int);
- method public T getProtocolObject(java.lang.Class<T>);
- method public java.util.List<java.lang.String> getProtocols();
- method public android.media.routing.MediaRouter.RouteInfo getRoute();
- method public android.media.VolumeProvider getVolumeProvider();
- }
-
- public static final class MediaRouter.ConnectionInfo.Builder {
- ctor public MediaRouter.ConnectionInfo.Builder(android.media.routing.MediaRouter.RouteInfo);
- method public android.media.routing.MediaRouter.ConnectionInfo build();
- method public android.media.routing.MediaRouter.ConnectionInfo.Builder setAudioAttributes(android.media.AudioAttributes);
- method public android.media.routing.MediaRouter.ConnectionInfo.Builder setExtras(android.os.Bundle);
- method public android.media.routing.MediaRouter.ConnectionInfo.Builder setPresentationDisplay(android.view.Display);
- method public android.media.routing.MediaRouter.ConnectionInfo.Builder setProtocolBinder(java.lang.String, android.os.IBinder);
- method public android.media.routing.MediaRouter.ConnectionInfo.Builder setProtocolStub(java.lang.Class<?>, android.os.IInterface);
- method public android.media.routing.MediaRouter.ConnectionInfo.Builder setVolumeProvider(android.media.VolumeProvider);
- }
-
- public static final class MediaRouter.ConnectionRequest {
- method public android.os.Bundle getExtras();
- method public int getFlags();
- method public android.media.routing.MediaRouter.RouteInfo getRoute();
- method public void setExtras(android.os.Bundle);
- method public void setFlags(int);
- method public void setRoute(android.media.routing.MediaRouter.RouteInfo);
- }
-
- public static final class MediaRouter.Delegate {
- ctor public MediaRouter.Delegate();
- method public void addStateCallback(android.media.routing.MediaRouter.StateCallback, android.os.Handler);
- method public void connect(android.media.routing.MediaRouter.DestinationInfo, int);
- method public void disconnect(int);
- method public int getConnectionState();
- method public java.util.List<android.media.routing.MediaRouter.DestinationInfo> getDiscoveredDestinations();
- method public int getDiscoveryState();
- method public android.media.routing.MediaRouter.DestinationInfo getSelectedDestination();
- method public boolean isReleased();
- method public void removeStateCallback(android.media.routing.MediaRouter.StateCallback);
- method public void startDiscovery(int);
- method public void stopDiscovery();
- }
-
- public static final class MediaRouter.DestinationInfo {
- method public java.lang.CharSequence getDescription();
- method public android.os.Bundle getExtras();
- method public int getIconResourceId();
- method public java.lang.String getId();
- method public java.lang.CharSequence getName();
- method public android.media.routing.MediaRouter.ServiceMetadata getServiceMetadata();
- method public android.graphics.drawable.Drawable loadIcon(android.content.pm.PackageManager);
- }
-
- public static final class MediaRouter.DestinationInfo.Builder {
- ctor public MediaRouter.DestinationInfo.Builder(java.lang.String, android.media.routing.MediaRouter.ServiceMetadata, java.lang.CharSequence);
- method public android.media.routing.MediaRouter.DestinationInfo build();
- method public android.media.routing.MediaRouter.DestinationInfo.Builder setDescription(java.lang.CharSequence);
- method public android.media.routing.MediaRouter.DestinationInfo.Builder setExtras(android.os.Bundle);
- method public android.media.routing.MediaRouter.DestinationInfo.Builder setIconResourceId(int);
- }
-
- public static final class MediaRouter.DiscoveryRequest {
- method public int getFlags();
- method public java.util.List<android.media.routing.MediaRouteSelector> getSelectors();
- method public void setFlags(int);
- method public void setSelectors(java.util.List<android.media.routing.MediaRouteSelector>);
- }
-
- public static final class MediaRouter.RouteInfo {
- method public android.media.routing.MediaRouter.DestinationInfo getDestination();
- method public android.os.Bundle getExtras();
- method public int getFeatures();
- method public java.lang.String getId();
- method public java.util.List<java.lang.String> getProtocols();
- method public android.media.routing.MediaRouteSelector getSelector();
- }
-
- public static final class MediaRouter.RouteInfo.Builder {
- ctor public MediaRouter.RouteInfo.Builder(java.lang.String, android.media.routing.MediaRouter.DestinationInfo, android.media.routing.MediaRouteSelector);
- method public android.media.routing.MediaRouter.RouteInfo.Builder addProtocol(java.lang.Class<T>);
- method public android.media.routing.MediaRouter.RouteInfo.Builder addProtocol(java.lang.String);
- method public android.media.routing.MediaRouter.RouteInfo build();
- method public android.media.routing.MediaRouter.RouteInfo.Builder setExtras(android.os.Bundle);
- method public android.media.routing.MediaRouter.RouteInfo.Builder setFeatures(int);
- }
-
- public static abstract class MediaRouter.RoutingCallback extends android.media.routing.MediaRouter.StateCallback {
- ctor public MediaRouter.RoutingCallback();
- method public boolean onPrepareConnectionRequest(android.media.routing.MediaRouter.ConnectionRequest, android.media.routing.MediaRouter.DestinationInfo, java.util.List<android.media.routing.MediaRouter.RouteInfo>);
- method public boolean onPrepareDiscoveryRequest(android.media.routing.MediaRouter.DiscoveryRequest, java.util.List<android.media.routing.MediaRouteSelector>);
- }
-
- public static final class MediaRouter.ServiceMetadata {
- method public android.content.ComponentName getComponentName();
- method public android.graphics.drawable.Drawable getIcon(android.content.pm.PackageManager);
- method public java.lang.CharSequence getLabel(android.content.pm.PackageManager);
- method public java.lang.String getPackageName();
- method public android.content.pm.ServiceInfo getService();
- }
-
- public static abstract class MediaRouter.StateCallback {
- ctor public MediaRouter.StateCallback();
- method public void onConnected();
- method public void onConnecting();
- method public void onConnectionFailed(int, java.lang.CharSequence, android.os.Bundle);
- method public void onConnectionStateChanged(int);
- method public void onDestinationFound(android.media.routing.MediaRouter.DestinationInfo);
- method public void onDestinationLost(android.media.routing.MediaRouter.DestinationInfo);
- method public void onDisconnected();
- method public void onDiscoveryFailed(int, java.lang.CharSequence, android.os.Bundle);
- method public void onDiscoveryStarted();
- method public void onDiscoveryStateChanged(int);
- method public void onDiscoveryStopped();
- method public void onReleased();
- method public void onSelectedDestinationChanged(android.media.routing.MediaRouter.DestinationInfo);
- }
-
-}
-
package android.media.session {
public final class MediaController {
@@ -16623,7 +16386,6 @@
method public void addCallback(android.media.session.MediaController.Callback);
method public void addCallback(android.media.session.MediaController.Callback, android.os.Handler);
method public void adjustVolume(int, int);
- method public android.media.routing.MediaRouter.Delegate createMediaRouterDelegate();
method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
method public android.media.session.MediaController.AudioInfo getAudioInfo();
method public android.os.Bundle getExtras();
@@ -16693,7 +16455,6 @@
method public void setFlags(int);
method public void setLaunchActivity(android.app.PendingIntent);
method public void setMediaButtonReceiver(android.app.PendingIntent);
- method public void setMediaRouter(android.media.routing.MediaRouter);
method public void setMetadata(android.media.MediaMetadata);
method public void setPlaybackState(android.media.session.PlaybackState);
method public void setPlaybackToLocal(android.media.AudioAttributes);
@@ -17072,6 +16833,7 @@
method public final java.lang.String getId();
method public final java.lang.String getLanguage();
method public final int getType();
+ method public final float getVideoFrameRate();
method public final int getVideoHeight();
method public final int getVideoWidth();
method public void writeToParcel(android.os.Parcel, int);
@@ -17088,6 +16850,7 @@
method public final android.media.tv.TvTrackInfo.Builder setAudioSampleRate(int);
method public final android.media.tv.TvTrackInfo.Builder setExtra(android.os.Bundle);
method public final android.media.tv.TvTrackInfo.Builder setLanguage(java.lang.String);
+ method public final android.media.tv.TvTrackInfo.Builder setVideoFrameRate(float);
method public final android.media.tv.TvTrackInfo.Builder setVideoHeight(int);
method public final android.media.tv.TvTrackInfo.Builder setVideoWidth(int);
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 5e77d28..52f1dd9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -305,7 +305,7 @@
/**
* Activity Action: Show settings to allow configuration of
- * {@link android.media.routing.MediaRouteService media route providers}.
+ * cast endpoints.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
* safeguard against this.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index cec7e63..3adc41a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -13831,6 +13831,7 @@
} else {
draw(canvas);
}
+ drawAccessibilityFocus(canvas);
}
} finally {
renderNode.end(canvas);
@@ -14125,6 +14126,7 @@
} else {
draw(canvas);
}
+ drawAccessibilityFocus(canvas);
canvas.restoreToCount(restoreCount);
canvas.setBitmap(null);
@@ -14199,6 +14201,7 @@
} else {
draw(canvas);
}
+ drawAccessibilityFocus(canvas);
mPrivateFlags = flags;
@@ -14792,9 +14795,13 @@
if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
mPrivateFlags &= ~PFLAG_DIRTY_MASK;
dispatchDraw(canvas);
+ if (mOverlay != null && !mOverlay.isEmpty()) {
+ mOverlay.getOverlayView().draw(canvas);
+ }
} else {
draw(canvas);
}
+ drawAccessibilityFocus(canvas);
} else {
mPrivateFlags &= ~PFLAG_DIRTY_MASK;
((HardwareCanvas) canvas).drawRenderNode(renderNode, null, flags);
@@ -15046,6 +15053,45 @@
}
/**
+ * Draws the accessibility focus rect onto the specified canvas.
+ *
+ * @param canvas Canvas on which to draw the focus rect
+ */
+ private void drawAccessibilityFocus(Canvas canvas) {
+ if (mAttachInfo == null) {
+ return;
+ }
+
+ final Rect bounds = mAttachInfo.mTmpInvalRect;
+ final ViewRootImpl viewRoot = getViewRootImpl();
+ if (viewRoot == null || viewRoot.getAccessibilityFocusedHost() != this) {
+ return;
+ }
+
+ final AccessibilityManager manager = AccessibilityManager.getInstance(mContext);
+ if (!manager.isEnabled() || !manager.isTouchExplorationEnabled()) {
+ return;
+ }
+
+ final Drawable drawable = viewRoot.getAccessibilityFocusedDrawable();
+ if (drawable == null) {
+ return;
+ }
+
+ final AccessibilityNodeInfo virtualView = viewRoot.getAccessibilityFocusedVirtualView();
+ if (virtualView != null) {
+ virtualView.getBoundsInParent(bounds);
+ } else {
+ bounds.set(0, 0, mRight - mLeft, mBottom - mTop);
+ }
+
+ canvas.translate(mScrollX, mScrollY);
+ drawable.setBounds(bounds);
+ drawable.draw(canvas);
+ canvas.translate(-mScrollX, -mScrollY);
+ }
+
+ /**
* Draws the background onto the specified canvas.
*
* @param canvas Canvas on which to draw the background
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 92e0245..bb469a3 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2244,7 +2244,6 @@
canvas.drawHardwareLayer(mResizeBuffer, mHardwareXOffset, mHardwareYOffset,
mResizePaint);
}
- drawAccessibilityFocusedDrawableIfNeeded(canvas);
}
/**
@@ -2462,25 +2461,9 @@
if (mHardwareYOffset != yOffset || mHardwareXOffset != xOffset) {
mHardwareYOffset = yOffset;
mHardwareXOffset = xOffset;
- invalidateRoot = true;
- }
- mResizeAlpha = resizeAlpha;
-
- if (!invalidateRoot) {
- // If accessibility focus moved, invalidate the root.
- final Drawable drawable = mAttachInfo.mAccessibilityFocusDrawable;
- if (drawable != null) {
- final Rect bounds = mAttachInfo.mTmpInvalRect;
- if (getAccessibilityFocusedRect(bounds)
- && !bounds.equals(drawable.getBounds())) {
- invalidateRoot = true;
- }
- }
- }
-
- if (invalidateRoot) {
mAttachInfo.mHardwareRenderer.invalidateRoot();
}
+ mResizeAlpha = resizeAlpha;
dirty.setEmpty();
@@ -2600,8 +2583,6 @@
attachInfo.mSetIgnoreDirtyState = false;
mView.draw(canvas);
-
- drawAccessibilityFocusedDrawableIfNeeded(canvas);
} finally {
if (!attachInfo.mSetIgnoreDirtyState) {
// Only clear the flag if it was not set during the mView.draw() call
@@ -2625,54 +2606,7 @@
return true;
}
- /**
- * We want to draw a highlight around the current accessibility focused.
- * Since adding a style for all possible view is not a viable option we
- * have this specialized drawing method.
- *
- * Note: We are doing this here to be able to draw the highlight for
- * virtual views in addition to real ones.
- *
- * @param canvas The canvas on which to draw.
- */
- private void drawAccessibilityFocusedDrawableIfNeeded(Canvas canvas) {
- final Rect bounds = mAttachInfo.mTmpInvalRect;
- if (getAccessibilityFocusedRect(bounds)) {
- final Drawable drawable = getAccessibilityFocusedDrawable();
- if (drawable != null) {
- drawable.setBounds(bounds);
- drawable.draw(canvas);
- }
- }
- }
-
- private boolean getAccessibilityFocusedRect(Rect bounds) {
- final AccessibilityManager manager = AccessibilityManager.getInstance(mView.mContext);
- if (!manager.isEnabled() || !manager.isTouchExplorationEnabled()) {
- return false;
- }
-
- final View host = mAccessibilityFocusedHost;
- if (host == null || host.mAttachInfo == null) {
- return false;
- }
-
- final AccessibilityNodeProvider provider = host.getAccessibilityNodeProvider();
- if (provider == null) {
- host.getBoundsOnScreen(bounds);
- } else if (mAccessibilityFocusedVirtualView != null) {
- mAccessibilityFocusedVirtualView.getBoundsInScreen(bounds);
- } else {
- return false;
- }
-
- final AttachInfo attachInfo = mAttachInfo;
- bounds.offset(-attachInfo.mWindowLeft, -attachInfo.mWindowTop);
- bounds.intersect(0, 0, attachInfo.mViewRootImpl.mWidth, attachInfo.mViewRootImpl.mHeight);
- return true;
- }
-
- private Drawable getAccessibilityFocusedDrawable() {
+ Drawable getAccessibilityFocusedDrawable() {
// Lazily load the accessibility focus drawable.
if (mAttachInfo.mAccessibilityFocusDrawable == null) {
final TypedValue value = new TypedValue();
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index b37ee06..3f5f045 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3158,6 +3158,7 @@
// Offset from touch position to mPosition
private float mTouchToWindowOffsetX, mTouchToWindowOffsetY;
protected int mHotspotX;
+ protected int mHorizontalGravity;
// Offsets the hotspot point up, so that cursor is not hidden by the finger when moving up
private float mTouchOffsetY;
// Where the touch position should be on the handle to ensure a maximum cursor visibility
@@ -3172,6 +3173,8 @@
private boolean mPositionHasChanged = true;
// Used to delay the appearance of the action popup window
private Runnable mActionPopupShower;
+ // Minimum touch target size for handles
+ private int mMinSize;
public HandleView(Drawable drawableLtr, Drawable drawableRtl) {
super(mTextView.getContext());
@@ -3184,10 +3187,12 @@
mDrawableLtr = drawableLtr;
mDrawableRtl = drawableRtl;
+ mMinSize = mTextView.getContext().getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.text_handle_min_size);
updateDrawable();
- final int handleHeight = mDrawable.getIntrinsicHeight();
+ final int handleHeight = getPreferredHeight();
mTouchOffsetY = -0.3f * handleHeight;
mIdealVerticalOffset = 0.7f * handleHeight;
}
@@ -3197,9 +3202,11 @@
final boolean isRtlCharAtOffset = mTextView.getLayout().isRtlCharAt(offset);
mDrawable = isRtlCharAtOffset ? mDrawableRtl : mDrawableLtr;
mHotspotX = getHotspotX(mDrawable, isRtlCharAtOffset);
+ mHorizontalGravity = getHorizontalGravity(isRtlCharAtOffset);
}
protected abstract int getHotspotX(Drawable drawable, boolean isRtlRun);
+ protected abstract int getHorizontalGravity(boolean isRtlRun);
// Touch-up filter: number of previous positions remembered
private static final int HISTORY_SIZE = 5;
@@ -3244,7 +3251,15 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- setMeasuredDimension(mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());
+ setMeasuredDimension(getPreferredWidth(), getPreferredHeight());
+ }
+
+ private int getPreferredWidth() {
+ return Math.max(mDrawable.getIntrinsicWidth(), mMinSize);
+ }
+
+ private int getPreferredHeight() {
+ return Math.max(mDrawable.getIntrinsicHeight(), mMinSize);
}
public void show() {
@@ -3336,7 +3351,8 @@
}
final int line = layout.getLineForOffset(offset);
- mPositionX = (int) (layout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX);
+ mPositionX = (int) (layout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX -
+ getHorizontalOffset() + getCursorOffset());
mPositionY = layout.getLineBottom(line);
// Take TextView's padding and scroll into account.
@@ -3385,10 +3401,36 @@
@Override
protected void onDraw(Canvas c) {
- mDrawable.setBounds(0, 0, mRight - mLeft, mBottom - mTop);
+ final int drawWidth = mDrawable.getIntrinsicWidth();
+ final int left = getHorizontalOffset();
+
+ mDrawable.setBounds(left, 0, left + drawWidth, mDrawable.getIntrinsicHeight());
mDrawable.draw(c);
}
+ private int getHorizontalOffset() {
+ final int width = getPreferredWidth();
+ final int drawWidth = mDrawable.getIntrinsicWidth();
+ final int left;
+ switch (mHorizontalGravity) {
+ case Gravity.LEFT:
+ left = 0;
+ break;
+ default:
+ case Gravity.CENTER:
+ left = (width - drawWidth) / 2;
+ break;
+ case Gravity.RIGHT:
+ left = width - drawWidth;
+ break;
+ }
+ return left;
+ }
+
+ protected int getCursorOffset() {
+ return 0;
+ }
+
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getActionMasked()) {
@@ -3508,6 +3550,22 @@
}
@Override
+ protected int getHorizontalGravity(boolean isRtlRun) {
+ return Gravity.CENTER_HORIZONTAL;
+ }
+
+ @Override
+ protected int getCursorOffset() {
+ int offset = super.getCursorOffset();
+ final Drawable cursor = mCursorCount > 0 ? mCursorDrawable[0] : null;
+ if (cursor != null) {
+ cursor.getPadding(mTempRect);
+ offset += (cursor.getIntrinsicWidth() - mTempRect.left - mTempRect.right) / 2;
+ }
+ return offset;
+ }
+
+ @Override
public boolean onTouchEvent(MotionEvent ev) {
final boolean result = super.onTouchEvent(ev);
@@ -3594,6 +3652,11 @@
}
@Override
+ protected int getHorizontalGravity(boolean isRtlRun) {
+ return isRtlRun ? Gravity.RIGHT : Gravity.LEFT;
+ }
+
+ @Override
public int getCurrentCursorOffset() {
return mTextView.getSelectionStart();
}
@@ -3637,6 +3700,11 @@
}
@Override
+ protected int getHorizontalGravity(boolean isRtlRun) {
+ return isRtlRun ? Gravity.LEFT : Gravity.RIGHT;
+ }
+
+ @Override
public int getCurrentCursorOffset() {
return mTextView.getSelectionEnd();
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 157147e..7809c71 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2210,14 +2210,6 @@
android:description="@string/permdesc_modifyParentalControls"
android:protectionLevel="signature" />
- <!-- Must be required by a {@link android.media.routing.MediaRouteService}
- to ensure that only the system can interact with it.
- @hide -->
- <permission android:name="android.permission.BIND_ROUTE_PROVIDER"
- android:label="@string/permlab_bindRouteProvider"
- android:description="@string/permdesc_bindRouteProvider"
- android:protectionLevel="signature" />
-
<!-- Must be required by device administration receiver, to ensure that only the
system can interact with it. -->
<permission android:name="android.permission.BIND_DEVICE_ADMIN"
@@ -2783,13 +2775,6 @@
android:description="@string/permdesc_bindConditionProviderService"
android:protectionLevel="signature" />
- <!-- Must be required by a {@link android.media.routing.MediaRouteService},
- to ensure that only the system can bind to it. -->
- <permission android:name="android.permission.BIND_MEDIA_ROUTE_SERVICE"
- android:label="@string/permlab_bindMediaRouteService"
- android:description="@string/permdesc_bindMediaRouteService"
- android:protectionLevel="signature" />
-
<!-- Must be required by an {@link android.service.dreams.DreamService},
to ensure that only the system can bind to it. -->
<permission android:name="android.permission.BIND_DREAM_SERVICE"
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00001.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00001.9.png
index 9076900..c31194e 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00001.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00002.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00002.9.png
index 3c72bf8..52ed6b2 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00002.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00003.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00003.9.png
index d31e113..7b7cde586 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00003.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00004.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00004.9.png
index d0c693e..859642a 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00004.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00005.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00005.9.png
index dfa19b4..5b71dda 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00005.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00006.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00006.9.png
index 151f205..378d82d 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00006.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00007.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00007.9.png
index ad3ee2c..43c995a 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00007.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00008.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00008.9.png
index 43d66d7..c937837 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00008.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00009.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00009.9.png
index 13e4f8b..a60a127 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00009.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00010.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00010.9.png
index a09b6b2..db0bf2d 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00010.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00011.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00011.9.png
index be02e53..4a6adbe 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00011.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00012.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00012.9.png
index 655d387..98983ef 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00012.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00001.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00001.9.png
index e870a0a..8e7b62f 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00001.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00002.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00002.9.png
index 1d8f805..479a26e 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00002.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00003.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00003.9.png
index d348871..77d3130 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00003.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00004.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00004.9.png
index 941e91e..cfe684f 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00004.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00005.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00005.9.png
index adee78d..4a64a36 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00005.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00006.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00006.9.png
index e6b4ca3..29591ff 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00006.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00007.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00007.9.png
index 6c2bc0d..cf7cf49 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00007.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00008.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00008.9.png
index 763833c..2a2a9af 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00008.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00009.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00009.9.png
index 9a87fbc..1f7fe5f 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00009.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00010.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00010.9.png
index 6ccf70b..f5d7093 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00010.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00011.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00011.9.png
index d1c14a5..3878386 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00011.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00012.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00012.9.png
index c2290f0..adcb9e9 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00012.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00001.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00001.9.png
index 0238898..36ed954 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00001.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00002.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00002.9.png
index ada1be9..863eee1 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00002.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00003.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00003.9.png
index 82aec64..63e93a8 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00003.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00004.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00004.9.png
index 1c6ea9f..85c851d 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00004.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00005.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00005.9.png
index ac11400..8637636 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00005.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00006.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00006.9.png
index 2025972..2945c29 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00006.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00007.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00007.9.png
index 7420fd8..678a6c8 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00007.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00008.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00008.9.png
index 1f40832..238a6f1 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00008.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00009.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00009.9.png
index cf58e44..4a342a6 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00009.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00010.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00010.9.png
index 930a280..5842b19 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00010.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00011.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00011.9.png
index ed9bc37..3e1bd2d 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00011.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00012.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00012.9.png
index cddb5b0..73ed10b 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00012.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00001.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00001.9.png
index bc1f979..03d3dfb 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00001.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00002.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00002.9.png
index e6fdbcc..25085ce 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00002.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00003.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00003.9.png
index 3d60b43..9e4d2f3 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00003.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00004.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00004.9.png
index b9afdc2..ab5bd1e 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00004.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00005.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00005.9.png
index c3c8bf2..f5297ce 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00005.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00006.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00006.9.png
index 1c7e5e1..1ad56e9 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00006.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00007.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00007.9.png
index 6329b73..4bad055 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00007.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00008.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00008.9.png
index 424202c..d908034 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00008.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00009.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00009.9.png
index 313beca..8ed4fb4 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00009.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00010.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00010.9.png
index f18d86a..61d3ced 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00010.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00011.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00011.9.png
index 8ab48c0..dec2a82 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00011.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00012.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00012.9.png
index fbc2c16..6635830 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00012.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00001.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00001.9.png
index 265aeb7..df73ef7 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00001.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00002.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00002.9.png
index 2f036ad..baf52ed 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00002.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00003.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00003.9.png
index bb26440..c8f3b1c 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00003.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00004.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00004.9.png
index 1b70047..fe715cf 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00004.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00005.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00005.9.png
index b544b98..8e66e11 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00005.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00006.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00006.9.png
index c461f3d..537496e 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00006.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00007.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00007.9.png
index f57da14..2722a98 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00007.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00008.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00008.9.png
index 22c6fbc..81fad09 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00008.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00009.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00009.9.png
index cd21ac9..cda20c8 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00009.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00010.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00010.9.png
index a38dc87..a61ad4b 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00010.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00011.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00011.9.png
index d84a342..d6e8e4c 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00011.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00012.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00012.9.png
index b82a2eb..785168e 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00012.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00001.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00001.9.png
index 6a33ebf..8a648b8 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00001.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00002.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00002.9.png
index dafc250..03063d4 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00002.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00003.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00003.9.png
index 27df6ff..6159dec 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00003.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00004.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00004.9.png
index cb4121c..6f1c96c 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00004.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00005.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00005.9.png
index c5cbb75..2eaff46 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00005.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00006.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00006.9.png
index c69ef41..c4d9db8 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00006.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00007.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00007.9.png
index aff03d1..f276f16 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00007.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00008.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00008.9.png
index fb56ae6..cf9133e 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00008.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00009.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00009.9.png
index 88b9d28..8f1a6a8 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00009.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00010.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00010.9.png
index 8451958..5080c46 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00010.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00011.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00011.9.png
index 6f57654..5e39408 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00011.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00012.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00012.9.png
index 21bfc28..435ce21 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00012.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00001.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00001.9.png
index c30cb5a..1eca9a9 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00001.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00002.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00002.9.png
index eaba558..5427211 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00002.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00003.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00003.9.png
index 17c18c9..43c06ab 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00003.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00004.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00004.9.png
index 0fce07a..6db3f1e 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00004.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00005.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00005.9.png
index c29b837..53b3a62 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00005.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00006.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00006.9.png
index ae56a41..7add520 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00006.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00007.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00007.9.png
index 85290ac..a4d57de 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00007.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00008.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00008.9.png
index 1e8513b..4b3a023 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00008.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00009.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00009.9.png
index 8810a12..a4caa65 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00009.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00010.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00010.9.png
index 717207f..2ab46c0 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00010.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00011.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00011.9.png
index db046f3..5c06e44 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00011.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00012.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00012.9.png
index c5c07a4..60d8c11 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00012.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00001.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00001.9.png
index c9bdf1f..b149e47 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00001.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00002.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00002.9.png
index 6bfd943..6a12a1f 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00002.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00003.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00003.9.png
index a1d3fbb..2803c7c 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00003.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00004.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00004.9.png
index 40c3a5b..032f6ea 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00004.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00005.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00005.9.png
index 26b8736..ea83c35 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00005.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00006.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00006.9.png
index 88c027e..2801f29 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00006.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00007.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00007.9.png
index 02567c6..66b89b3 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00007.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00008.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00008.9.png
index 037d3bf..1f8770c 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00008.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00009.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00009.9.png
index 0252769..0d6a95b 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00009.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00010.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00010.9.png
index 3ae501d..8e602db 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00010.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00011.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00011.9.png
index ecf2831..3143c1f 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00011.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00012.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00012.9.png
index 0877749..00fb83e 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00012.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00001.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00001.9.png
index bc21279..786f493 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00001.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00002.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00002.9.png
index b57b592..c6e1ac1 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00002.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00003.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00003.9.png
index 0fb9277..2a65baa 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00003.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00004.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00004.9.png
index 340722d..efce521 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00004.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00005.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00005.9.png
index 8554a76..5566524 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00005.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00006.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00006.9.png
index a05e335..ee676a6 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00006.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00007.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00007.9.png
index a5ded14..e0bb175 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00007.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00008.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00008.9.png
index 0300a49..de9eada 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00008.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00009.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00009.9.png
index 37dd7ce..3c59ad8 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00009.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00010.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00010.9.png
index 6bc549a..d524098 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00010.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00011.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00011.9.png
index b026d5d..7c08d71 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00011.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00012.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00012.9.png
index 89238dc..017c2e1 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00012.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00001.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00001.9.png
index 1d309fe..d3f2a9a 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00001.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00002.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00002.9.png
index 2e58fa9..cb75295 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00002.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00003.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00003.9.png
index 2ebe7a7..445644e 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00003.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00004.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00004.9.png
index 04bab76..5819f90 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00004.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00005.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00005.9.png
index 3497e48..91cb90f 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00005.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00006.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00006.9.png
index 42333b4..cf6147c 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00006.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00007.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00007.9.png
index 732e175..75fca7c 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00007.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00008.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00008.9.png
index 12eddd8..b71a0b4 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00008.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00009.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00009.9.png
index 95cbc61..edb7671 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00009.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00010.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00010.9.png
index 105ec07..5e0be17 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00010.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00011.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00011.9.png
index fac253a..b727eda 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00011.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00012.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00012.9.png
index 1b8d11c..a3caefb 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00012.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/values-mcc311-mnc480/config.xml b/core/res/res/values-mcc311-mnc480/config.xml
index e3d8420..1c83644 100644
--- a/core/res/res/values-mcc311-mnc480/config.xml
+++ b/core/res/res/values-mcc311-mnc480/config.xml
@@ -38,4 +38,9 @@
be disabled) but individual Features can be disabled using ImsConfig.setFeatureValue() -->
<bool name="imsServiceAllowTurnOff">false</bool>
+ <!-- Flag specifying whether VoLTE & VT should be allowed on device: independent of the
+ carrier provisioning. If false: hard disabled. If true: then depends on carrier
+ provisioning, availability etc -->
+ <bool name="config_mobile_allow_volte_vt">false</bool>
+
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f702b95..a59a489 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1641,6 +1641,11 @@
be disabled) but individual Features can be disabled using ImsConfig.setFeatureValue() -->
<bool name="imsServiceAllowTurnOff">true</bool>
+ <!-- Flag specifying whether VoLTE & VT should be allowed on device: independent of the
+ carrier provisioning. If false: hard disabled. If true: then depends on carrier
+ provisioning, availability etc -->
+ <bool name="config_mobile_allow_volte_vt">true</bool>
+
<bool name="config_networkSamplingWakesDevice">true</bool>
<string-array translatable="false" name="config_cdma_home_system" />
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index a29a34c..d170fd4 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -394,4 +394,7 @@
<dimen name="lock_pattern_dot_line_width">3dp</dimen>
<dimen name="lock_pattern_dot_size">12dp</dimen>
<dimen name="lock_pattern_dot_size_activated">28dp</dimen>
+
+ <dimen name="text_handle_min_size">40dp</dimen>
+
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2936e2b..78ba738 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1160,12 +1160,6 @@
interface of a widget service. Should never be needed for normal apps.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_bindRouteProvider">bind to a route provider service</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_bindRouteProvider">Allows the holder to bind to any registered
- route providers. Should never be needed for normal apps.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_bindDeviceAdmin">interact with a device admin</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_bindDeviceAdmin">Allows the holder to send intents to
@@ -2157,11 +2151,6 @@
<string name="permdesc_bindConditionProviderService">Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_bindMediaRouteService">bind to a media route service</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_bindMediaRouteService">Allows the holder to bind to the top-level interface of a media route service. Should never be needed for normal apps.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_bindDreamService">bind to a dream service</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_bindDreamService">Allows the holder to bind to the top-level interface of a dream service. Should never be needed for normal apps.</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1cb7b17..11e292e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1956,6 +1956,7 @@
<java-symbol type="attr" name="preferenceFragmentStyle" />
<java-symbol type="bool" name="skipHoldBeforeMerge" />
<java-symbol type="bool" name="imsServiceAllowTurnOff" />
+ <java-symbol type="bool" name="config_mobile_allow_volte_vt" />
<java-symbol type="bool" name="useImsAlwaysForEmergencyCall" />
<java-symbol type="attr" name="touchscreenBlocksFocus" />
<java-symbol type="layout" name="resolver_list_with_default" />
@@ -1983,4 +1984,5 @@
<java-symbol type="layout" name="select_dialog_singlechoice_material" />
<java-symbol type="layout" name="select_dialog_multichoice_material" />
<java-symbol type="array" name="no_ems_support_sim_operators" />
+ <java-symbol type="dimen" name="text_handle_min_size" />
</resources>
diff --git a/data/fonts/AndroidClock.ttf b/data/fonts/AndroidClock.ttf
index 4781ccd..a955442 100644
--- a/data/fonts/AndroidClock.ttf
+++ b/data/fonts/AndroidClock.ttf
Binary files differ
diff --git a/data/fonts/AndroidClock_Highlight.ttf b/data/fonts/AndroidClock_Highlight.ttf
index 3fa6d88..923bb30 100644
--- a/data/fonts/AndroidClock_Highlight.ttf
+++ b/data/fonts/AndroidClock_Highlight.ttf
Binary files differ
diff --git a/data/fonts/AndroidClock_Solid.ttf b/data/fonts/AndroidClock_Solid.ttf
index 3fa6d88..923bb30 100644
--- a/data/fonts/AndroidClock_Solid.ttf
+++ b/data/fonts/AndroidClock_Solid.ttf
Binary files differ
diff --git a/data/fonts/Clockopia.ttf b/data/fonts/Clockopia.ttf
index 123ea4f..3f7b6aa 100644
--- a/data/fonts/Clockopia.ttf
+++ b/data/fonts/Clockopia.ttf
Binary files differ
diff --git a/data/fonts/DroidSansFallback.ttf b/data/fonts/DroidSansFallback.ttf
index 03f49a8..96b16bb 100644
--- a/data/fonts/DroidSansFallback.ttf
+++ b/data/fonts/DroidSansFallback.ttf
Binary files differ
diff --git a/data/fonts/DroidSansFallbackFull.ttf b/data/fonts/DroidSansFallbackFull.ttf
index 1dfcc33..89959f5 100644
--- a/data/fonts/DroidSansFallbackFull.ttf
+++ b/data/fonts/DroidSansFallbackFull.ttf
Binary files differ
diff --git a/data/fonts/DroidSansMono.ttf b/data/fonts/DroidSansMono.ttf
index a007071..4085cee 100644
--- a/data/fonts/DroidSansMono.ttf
+++ b/data/fonts/DroidSansMono.ttf
Binary files differ
diff --git a/data/fonts/MTLc3m.ttf b/data/fonts/MTLc3m.ttf
index 86bdcc7..e9018f6 100644
--- a/data/fonts/MTLc3m.ttf
+++ b/data/fonts/MTLc3m.ttf
Binary files differ
diff --git a/data/fonts/MTLmr3m.ttf b/data/fonts/MTLmr3m.ttf
index 91dd47f..14f27d4 100644
--- a/data/fonts/MTLmr3m.ttf
+++ b/data/fonts/MTLmr3m.ttf
Binary files differ
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 0aa1b0d..c185a9e 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -446,19 +446,8 @@
": <nine-patch> requires a valid 9-patch source image");
}
- // Hey, now might be a good time to actually load optical bounds!
bitmap.getOpticalInsets(opticalInsets);
- // Sanity check for valid padding when we have optical insets.
- if (padding.left < opticalInsets.left) {
- padding.left = opticalInsets.left;
- padding.right = opticalInsets.right;
- }
- if (padding.top < opticalInsets.top) {
- padding.top = opticalInsets.top;
- padding.bottom = opticalInsets.bottom;
- }
-
state.mNinePatch = new NinePatch(bitmap, bitmap.getNinePatchChunk());
state.mPadding = padding;
state.mOpticalInsets = Insets.of(opticalInsets);
@@ -626,21 +615,6 @@
mOpticalInsets = Insets.of(opticalInsets);
mDither = dither;
mAutoMirrored = autoMirror;
-
- // Sanity check for valid padding when we have optical insets.
- if (opticalInsets != null && !opticalInsets.isEmpty()) {
- if (mPadding == null) {
- mPadding = new Rect();
- }
- if (mPadding.left < opticalInsets.left) {
- mPadding.left = opticalInsets.left;
- mPadding.right = opticalInsets.right;
- }
- if (mPadding.top < opticalInsets.top) {
- mPadding.top = opticalInsets.top;
- mPadding.bottom = opticalInsets.bottom;
- }
- }
}
// Copy constructor
diff --git a/media/java/android/media/routing/IMediaRouteClientCallback.aidl b/media/java/android/media/routing/IMediaRouteClientCallback.aidl
deleted file mode 100644
index d90ea3b..0000000
--- a/media/java/android/media/routing/IMediaRouteClientCallback.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.routing;
-
-import android.media.routing.MediaRouteSelector;
-import android.media.routing.ParcelableConnectionInfo;
-import android.media.routing.ParcelableDestinationInfo;
-import android.media.routing.ParcelableRouteInfo;
-import android.os.IBinder;
-import android.os.Bundle;
-
-/**
- * @hide
- */
-oneway interface IMediaRouteClientCallback {
- void onDestinationFound(int seq, in ParcelableDestinationInfo destination,
- in ParcelableRouteInfo[] routes);
-
- void onDestinationLost(int seq, String id);
-
- void onDiscoveryFailed(int seq, int error, in CharSequence message, in Bundle extras);
-
- void onConnected(int seq, in ParcelableConnectionInfo connection);
-
- void onDisconnected(int seq);
-
- void onConnectionFailed(int seq, int error, in CharSequence message, in Bundle extras);
-}
diff --git a/media/java/android/media/routing/IMediaRouteService.aidl b/media/java/android/media/routing/IMediaRouteService.aidl
deleted file mode 100644
index 493ab6d..0000000
--- a/media/java/android/media/routing/IMediaRouteService.aidl
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.routing;
-
-import android.media.routing.IMediaRouteClientCallback;
-import android.media.routing.MediaRouteSelector;
-import android.os.Bundle;
-
-/**
- * Interface to an app's MediaRouteService.
- * @hide
- */
-oneway interface IMediaRouteService {
- void registerClient(int clientUid, String clientPackageName,
- in IMediaRouteClientCallback callback);
-
- void unregisterClient(in IMediaRouteClientCallback callback);
-
- void startDiscovery(in IMediaRouteClientCallback callback, int seq,
- in List<MediaRouteSelector> selectors, int flags);
-
- void stopDiscovery(in IMediaRouteClientCallback callback);
-
- void connect(in IMediaRouteClientCallback callback, int seq,
- String destinationId, String routeId, int flags, in Bundle extras);
-
- void disconnect(in IMediaRouteClientCallback callback);
-
- void pauseStream(in IMediaRouteClientCallback callback);
-
- void resumeStream(in IMediaRouteClientCallback callback);
-}
-
diff --git a/media/java/android/media/routing/IMediaRouter.aidl b/media/java/android/media/routing/IMediaRouter.aidl
deleted file mode 100644
index 0abb258..0000000
--- a/media/java/android/media/routing/IMediaRouter.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.routing;
-
-/** @hide */
-interface IMediaRouter {
-
-}
-
diff --git a/media/java/android/media/routing/IMediaRouterDelegate.aidl b/media/java/android/media/routing/IMediaRouterDelegate.aidl
deleted file mode 100644
index 35f84c8..0000000
--- a/media/java/android/media/routing/IMediaRouterDelegate.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.routing;
-
-/** @hide */
-interface IMediaRouterDelegate {
-
-}
-
diff --git a/media/java/android/media/routing/IMediaRouterRoutingCallback.aidl b/media/java/android/media/routing/IMediaRouterRoutingCallback.aidl
deleted file mode 100644
index 173ae55..0000000
--- a/media/java/android/media/routing/IMediaRouterRoutingCallback.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.routing;
-
-/** @hide */
-interface IMediaRouterRoutingCallback {
-
-}
-
diff --git a/media/java/android/media/routing/IMediaRouterStateCallback.aidl b/media/java/android/media/routing/IMediaRouterStateCallback.aidl
deleted file mode 100644
index 0299904..0000000
--- a/media/java/android/media/routing/IMediaRouterStateCallback.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.routing;
-
-/** @hide */
-interface IMediaRouterStateCallback {
-
-}
-
diff --git a/media/java/android/media/routing/MediaRouteSelector.aidl b/media/java/android/media/routing/MediaRouteSelector.aidl
deleted file mode 100644
index 37bfa4a..0000000
--- a/media/java/android/media/routing/MediaRouteSelector.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 2014, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.media.routing;
-
-parcelable MediaRouteSelector;
diff --git a/media/java/android/media/routing/MediaRouteSelector.java b/media/java/android/media/routing/MediaRouteSelector.java
deleted file mode 100644
index 26a9b1c..0000000
--- a/media/java/android/media/routing/MediaRouteSelector.java
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.media.routing;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.media.routing.MediaRouter.RouteFeatures;
-import android.os.Bundle;
-import android.os.IInterface;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A media route selector consists of a set of constraints that are used to select
- * the routes to which an application would like to connect. The constraints consist
- * of a set of required or optional features and protocols. The constraints may also
- * require the use of a specific media route service package or additional characteristics
- * that are described by a bundle of extra parameters.
- * <p>
- * The application will typically create several different selectors that express
- * various combinations of characteristics that it would like to use together when
- * it connects to a destination media device. For each destination that is discovered,
- * media route services will publish some number of routes and include information
- * about which selector each route matches. The application will then choose among
- * these routes to determine which best satisfies its desired purpose and connect to it.
- * </p>
- */
-public final class MediaRouteSelector implements Parcelable {
- private final int mRequiredFeatures;
- private final int mOptionalFeatures;
- private final List<String> mRequiredProtocols;
- private final List<String> mOptionalProtocols;
- private final String mServicePackageName;
- private final Bundle mExtras;
-
- MediaRouteSelector(int requiredFeatures, int optionalFeatures,
- List<String> requiredProtocols, List<String> optionalProtocols,
- String servicePackageName, Bundle extras) {
- mRequiredFeatures = requiredFeatures;
- mOptionalFeatures = optionalFeatures;
- mRequiredProtocols = requiredProtocols;
- mOptionalProtocols = optionalProtocols;
- mServicePackageName = servicePackageName;
- mExtras = extras;
- }
-
- /**
- * Gets the set of required route features.
- *
- * @return A set of required route feature flags.
- */
- public @RouteFeatures int getRequiredFeatures() {
- return mRequiredFeatures;
- }
-
- /**
- * Gets the set of optional route features.
- *
- * @return A set of optional route feature flags.
- */
- public @RouteFeatures int getOptionalFeatures() {
- return mOptionalFeatures;
- }
-
- /**
- * Gets the list of route protocols that a route must support in order to be selected.
- * <p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
- * for more information.
- * </p>
- *
- * @return The list of fully qualified route protocol names.
- */
- public @NonNull List<String> getRequiredProtocols() {
- return mRequiredProtocols;
- }
-
- /**
- * Gets the list of optional route protocols that a client may use if they are available.
- * <p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
- * for more information.
- * </p>
- *
- * @return The list of optional fully qualified route protocol names.
- */
- public @NonNull List<String> getOptionalProtocols() {
- return mOptionalProtocols;
- }
-
- /**
- * Returns true if the selector includes a required or optional request for
- * the specified protocol using its fully qualified class name.
- * <p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
- * for more information.
- * </p>
- *
- * @param clazz The protocol class.
- * @return True if the protocol was requested.
- */
- public boolean containsProtocol(@NonNull Class<?> clazz) {
- return containsProtocol(clazz.getName());
- }
-
- /**
- * Returns true if the selector includes a required or optional request for
- * the specified protocol.
- * <p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
- * for more information.
- * </p>
- *
- * @param name The name of the protocol.
- * @return True if the protocol was requested.
- */
- public boolean containsProtocol(@NonNull String name) {
- return mRequiredProtocols.contains(name)
- || mOptionalProtocols.contains(name);
- }
-
- /**
- * Gets the package name of a specific media route service that this route selector
- * requires.
- *
- * @return The required media route service package name, or null if none.
- */
- public @Nullable String getServicePackageName() {
- return mServicePackageName;
- }
-
- /**
- * Gets optional extras that may be used to select or configure routes for a
- * particular purpose. Some extras may be used by media route services to apply
- * additional constraints or parameters for the routes to be discovered.
- *
- * @return The optional extras, or null if none.
- */
- public @Nullable Bundle getExtras() {
- return mExtras;
- }
-
- @Override
- public String toString() {
- return "MediaRouteSelector{ "
- + ", requiredFeatures=0x" + Integer.toHexString(mRequiredFeatures)
- + ", optionalFeatures=0x" + Integer.toHexString(mOptionalFeatures)
- + ", requiredProtocols=" + mRequiredProtocols
- + ", optionalProtocols=" + mOptionalProtocols
- + ", servicePackageName=" + mServicePackageName
- + ", extras=" + mExtras + " }";
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mRequiredFeatures);
- dest.writeInt(mOptionalFeatures);
- dest.writeStringList(mRequiredProtocols);
- dest.writeStringList(mOptionalProtocols);
- dest.writeString(mServicePackageName);
- dest.writeBundle(mExtras);
- }
-
- public static final Parcelable.Creator<MediaRouteSelector> CREATOR =
- new Parcelable.Creator<MediaRouteSelector>() {
- @Override
- public MediaRouteSelector createFromParcel(Parcel source) {
- int requiredFeatures = source.readInt();
- int optionalFeatures = source.readInt();
- ArrayList<String> requiredProtocols = new ArrayList<String>();
- ArrayList<String> optionalProtocols = new ArrayList<String>();
- source.readStringList(requiredProtocols);
- source.readStringList(optionalProtocols);
- return new MediaRouteSelector(requiredFeatures, optionalFeatures,
- requiredProtocols, optionalProtocols,
- source.readString(), source.readBundle());
- }
-
- @Override
- public MediaRouteSelector[] newArray(int size) {
- return new MediaRouteSelector[size];
- }
- };
-
- /**
- * Builder for {@link MediaRouteSelector} objects.
- */
- public static final class Builder {
- private int mRequiredFeatures;
- private int mOptionalFeatures;
- private final ArrayList<String> mRequiredProtocols = new ArrayList<String>();
- private final ArrayList<String> mOptionalProtocols = new ArrayList<String>();
- private String mServicePackageName;
- private Bundle mExtras;
-
- /**
- * Creates an initially empty selector builder.
- */
- public Builder() {
- }
-
- /**
- * Sets the set of required route features.
- *
- * @param features A set of required route feature flags.
- */
- public @NonNull Builder setRequiredFeatures(@RouteFeatures int features) {
- mRequiredFeatures = features;
- return this;
- }
-
- /**
- * Sets the set of optional route features.
- *
- * @param features A set of optional route feature flags.
- */
- public @NonNull Builder setOptionalFeatures(@RouteFeatures int features) {
- mOptionalFeatures = features;
- return this;
- }
-
- /**
- * Adds a route protocol that a route must support in order to be selected
- * using its fully qualified class name.
- * <p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
- * for more information.
- * </p>
- *
- * @param clazz The protocol class.
- * @return this
- */
- public @NonNull Builder addRequiredProtocol(@NonNull Class<?> clazz) {
- if (clazz == null) {
- throw new IllegalArgumentException("clazz must not be null");
- }
- return addRequiredProtocol(clazz.getName());
- }
-
- /**
- * Adds a route protocol that a route must support in order to be selected.
- * <p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
- * for more information.
- * </p>
- *
- * @param name The fully qualified name of the required protocol.
- * @return this
- */
- public @NonNull Builder addRequiredProtocol(@NonNull String name) {
- if (TextUtils.isEmpty(name)) {
- throw new IllegalArgumentException("name must not be null or empty");
- }
- mRequiredProtocols.add(name);
- return this;
- }
-
- /**
- * Adds an optional route protocol that a client may use if available
- * using its fully qualified class name.
- * <p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
- * for more information.
- * </p>
- *
- * @param clazz The protocol class.
- * @return this
- */
- public @NonNull Builder addOptionalProtocol(@NonNull Class<?> clazz) {
- if (clazz == null) {
- throw new IllegalArgumentException("clazz must not be null");
- }
- return addOptionalProtocol(clazz.getName());
- }
-
- /**
- * Adds an optional route protocol that a client may use if available.
- * <p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
- * for more information.
- * </p>
- *
- * @param name The fully qualified name of the optional protocol.
- * @return this
- */
- public @NonNull Builder addOptionalProtocol(@NonNull String name) {
- if (TextUtils.isEmpty(name)) {
- throw new IllegalArgumentException("name must not be null or empty");
- }
- mOptionalProtocols.add(name);
- return this;
- }
-
- /**
- * Sets the package name of the media route service to which this selector
- * appertains.
- * <p>
- * If a package name is specified here then this selector will only be
- * passed to media route services from that package. This has the effect
- * of restricting the set of matching routes to just those that are offered
- * by that package.
- * </p>
- *
- * @param packageName The required service package name, or null if none.
- * @return this
- */
- public @NonNull Builder setServicePackageName(@Nullable String packageName) {
- mServicePackageName = packageName;
- return this;
- }
-
- /**
- * Sets optional extras that may be used to select or configure routes for a
- * particular purpose. Some extras may be used by route services to specify
- * additional constraints or parameters for the routes to be discovered.
- *
- * @param extras The optional extras, or null if none.
- * @return this
- */
- public @NonNull Builder setExtras(@Nullable Bundle extras) {
- mExtras = extras;
- return this;
- }
-
- /**
- * Builds the {@link MediaRouteSelector} object.
- *
- * @return The new media route selector instance.
- */
- public @NonNull MediaRouteSelector build() {
- return new MediaRouteSelector(mRequiredFeatures, mOptionalFeatures,
- mRequiredProtocols, mOptionalProtocols, mServicePackageName, mExtras);
- }
- }
-}
diff --git a/media/java/android/media/routing/MediaRouteService.java b/media/java/android/media/routing/MediaRouteService.java
deleted file mode 100644
index 4d5a8a9..0000000
--- a/media/java/android/media/routing/MediaRouteService.java
+++ /dev/null
@@ -1,1023 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.media.routing;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SdkConstant;
-import android.app.Service;
-import android.content.Intent;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.media.routing.MediaRouter.ConnectionError;
-import android.media.routing.MediaRouter.ConnectionInfo;
-import android.media.routing.MediaRouter.ConnectionRequest;
-import android.media.routing.MediaRouter.DestinationInfo;
-import android.media.routing.MediaRouter.DiscoveryError;
-import android.media.routing.MediaRouter.DiscoveryRequest;
-import android.media.routing.MediaRouter.RouteInfo;
-import android.media.routing.MediaRouter.ServiceMetadata;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Media route services implement strategies for discovering
- * and establishing connections to media devices and their routes. These services
- * are also known as media route providers.
- * <p>
- * Each media route service subclass is responsible for enabling applications
- * and the system to interact with media devices of some kind.
- * For example, one particular media route service implementation might
- * offer support for discovering nearby wireless display devices and streaming
- * video contents to them; another media route service implementation might
- * offer support for discovering nearby speakers and streaming media appliances
- * and sending commands to play content on request.
- * </p><p>
- * Subclasses must override the {@link #onCreateClientSession} method to return
- * a {@link ClientSession} object that implements the {@link ClientSession#onStartDiscovery},
- * {@link ClientSession#onStopDiscovery}, and {@link ClientSession#onConnect} methods
- * to allow clients to discover and connect to media devices.
- * </p><p>
- * This object is not thread-safe. All callbacks are invoked on the main looper.
- * </p>
- *
- * <h3>Clients</h3>
- * <p>
- * The clients of this API are media applications that would like to discover
- * and connect to media devices. The client may also be the system, such as
- * when the user initiates display mirroring via the Cast Screen function.
- * </p><p>
- * There may be multiple client sessions active at the same time. Each client
- * session can request discovery and connect to routes independently of any
- * other client. It is the responsibility of the media route service to maintain
- * separate state for each client session and to ensure that clients cannot interfere
- * with one another in harmful ways.
- * </p><p>
- * Notwithstanding the requirement to support any number of concurrent client
- * sessions, the media route service may impose constraints on how many clients
- * can connect to the same media device in a particular mode at the same time.
- * In some cases, media devices may support connections from an arbitrary number
- * of clients simultaneously but often it may be necessary to ensure that only
- * one client is in control. When this happens, the media route service should
- * report a connection error unless the connection request specifies that the
- * client should take control of the media device (and forcibly disconnect other
- * clients that may be using it).
- * </p>
- *
- * <h3>Destinations</h3>
- * <p>
- * The media devices to which an application may send media content are referred
- * to in the API as destinations. Each destination therefore represents a single
- * independent device such as a speaker or TV set. Destinations are given meaningful
- * names and descriptions to help the user associate them with devices in their
- * environment.
- * </p><p>
- * Destinations may be local or remote and may be accessed through various means,
- * often wirelessly. The user may install media route services to enable
- * media applications to connect to a variety of destinations with different
- * capabilities.
- * </p>
- *
- * <h3>Routes</h3>
- * <p>
- * Routes represent possible usages or means of reaching and interacting with
- * a destination. Since destinations may support many different features, they may
- * each offer multiple routes for applications to choose from based on their needs.
- * For example, one route might express the ability to stream locally rendered audio
- * and video to the device; another route might express the ability to send a URL for
- * the destination to download from the network and play all by itself.
- * </p><p>
- * Routes are discovered according to the set of capabilities that
- * an application or the system is seeking to use at a particular time. For example,
- * if an application wants to stream music to a destination then it will ask the
- * {@link MediaRouter} to find routes to destinations can stream music and ignore
- * all other destinations that cannot.
- * </p><p>
- * In general, the application will inspect the set of routes that have been
- * offered then connect to the most appropriate route for its desired purpose.
- * </p>
- *
- * <h3>Discovery</h3>
- * <p>
- * Discovery is the process of finding destinations based on a description of the
- * kinds of routes that an application or the system would like to use.
- * </p><p>
- * Discovery begins when {@link ClientSession#onStartDiscovery} is called and ends when
- * {@link ClientSession#onStopDiscovery} is called. There may be multiple simultaneous
- * discovery requests in progress at the same time from different clients. It is up to
- * the media route service to perform these requests in parallel or multiplex them
- * as required.
- * </p><p>
- * Media route services are <em>strongly encouraged</em> to use the information
- * in the discovery request to optimize discovery and avoid redundant work.
- * In the case where no media device supported by the media route service
- * could possibly offer the requested capabilities, the
- * {@link ClientSession#onStartDiscovery} method should return <code>false</code> to
- * let the system know that it can unbind from the media route service and
- * release its resources.
- * </p>
- *
- * <h3>Settings</h3>
- * <p>
- * Many kinds of devices can be discovered on demand simply by scanning the local network
- * or using wireless protocols such as Bluetooth to find them. However, in some cases
- * it may be necessary for the user to manually configure destinations before they
- * can be used (or to adjust settings later). Actual user configuration of destinations
- * is beyond the scope of this API but media route services may specify an activity
- * in their manifest that the user can launch to perform these tasks.
- * </p><p>
- * Note that media route services that are installed from the store must be enabled
- * by the user before they become available for applications to use.
- * The {@link android.provider.Settings#ACTION_CAST_SETTINGS Settings.ACTION_CAST_SETTINGS}
- * settings activity provides the ability for the user to configure media route services.
- * </p>
- *
- * <h3>Manifest Declaration</h3>
- * <p>
- * Media route services must be declared in the manifest along with meta-data
- * about the kinds of routes that they are capable of discovering. The system
- * uses this information to optimize the set of services to which it binds in
- * order to satisfy a particular discovery request.
- * </p><p>
- * To extend this class, you must declare the service in your manifest file with
- * the {@link android.Manifest.permission#BIND_MEDIA_ROUTE_SERVICE} permission
- * and include an intent filter with the {@link #SERVICE_INTERFACE} action. You must
- * also add meta-data to describe the kinds of routes that your service is capable
- * of discovering.
- * </p><p>
- * For example:
- * </p><pre>
- * <service android:name=".MediaRouteProvider"
- * android:label="@string/service_name"
- * android:permission="android.permission.BIND_MEDIA_ROUTE_SERVICE">
- * <intent-filter>
- * <action android:name="android.media.routing.MediaRouteService" />
- * </intent-filter>
- *
- * TODO: INSERT METADATA DECLARATIONS HERE
- *
- * </service>
- * </pre>
- */
-public abstract class MediaRouteService extends Service {
- private static final String TAG = "MediaRouteService";
-
- private static final boolean DEBUG = true;
-
- private final Handler mHandler;
- private final BinderService mService;
- private final ArrayMap<IBinder, ClientRecord> mClientRecords =
- new ArrayMap<IBinder, ClientRecord>();
-
- private ServiceMetadata mMetadata;
-
- /**
- * The {@link Intent} that must be declared as handled by the service.
- */
- @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
- public static final String SERVICE_INTERFACE =
- "android.media.routing.MediaRouteService";
-
- /**
- * Creates a media route service.
- */
- public MediaRouteService() {
- mHandler = new Handler(true);
- mService = new BinderService();
- }
-
- @Override
- public @Nullable IBinder onBind(Intent intent) {
- if (SERVICE_INTERFACE.equals(intent.getAction())) {
- return mService;
- }
- return null;
- }
-
- /**
- * Creates a new client session on behalf of a client.
- * <p>
- * The implementation should return a {@link ClientSession} for the client
- * to use. The media route service must take care to manage the state of
- * each client session independently from any others that might also be
- * in use at the same time.
- * </p>
- *
- * @param client Information about the client.
- * @return The client session object, or null if the client is not allowed
- * to interact with this media route service.
- */
- public abstract @Nullable ClientSession onCreateClientSession(@NonNull ClientInfo client);
-
- /**
- * Gets metadata about this service.
- * <p>
- * Use this method to obtain a {@link ServiceMetadata} object to provide when creating
- * a {@link android.media.routing.MediaRouter.DestinationInfo.Builder}.
- * </p>
- *
- * @return Metadata about this service.
- */
- public @NonNull ServiceMetadata getServiceMetadata() {
- if (mMetadata == null) {
- try {
- mMetadata = new ServiceMetadata(this);
- } catch (NameNotFoundException ex) {
- Log.wtf(TAG, "Could not retrieve own service metadata!");
- }
- }
- return mMetadata;
- }
-
- /**
- * Enables a single client to access the functionality of the media route service.
- */
- public static abstract class ClientSession {
- /**
- * Starts discovery.
- * <p>
- * If the media route service is capable of discovering routes that satisfy
- * the request then this method should start discovery and return true.
- * Otherwise, this method should return false. If false is returned,
- * then the framework will not call {@link #onStopDiscovery} since discovery
- * was never actually started.
- * </p><p>
- * There may already be other discovery requests in progress at the same time
- * for other clients; the media route service must keep track of them all.
- * </p>
- *
- * @param req The discovery request to start.
- * @param callback A callback to receive discovery events related to this
- * particular request. The events that the service sends to this callback
- * will be sent to the client that initiated the discovery request.
- * @return True if discovery has started. False if the media route service
- * is unable to discover routes that satisfy the request.
- */
- public abstract boolean onStartDiscovery(@NonNull DiscoveryRequest req,
- @NonNull DiscoveryCallback callback);
-
- /**
- * Stops discovery.
- * <p>
- * If {@link #onStartDiscovery} returned true, then this method will eventually
- * be called when the framework no longer requires this discovery request
- * to be performed.
- * </p><p>
- * There may still be other discovery requests in progress for other clients;
- * they must keep working until they have each been stopped by their client.
- * </p>
- */
- public abstract void onStopDiscovery();
-
- /**
- * Starts connecting to a route.
- *
- * @param req The connection request.
- * @param callback A callback to receive events connection events related
- * to this particular request. The events that the service sends to this callback
- * will be sent to the client that initiated the discovery request.
- * @return True if the connection is in progress, or false if the client
- * unable to connect to the requested route.
- */
- public abstract boolean onConnect(@NonNull ConnectionRequest req,
- @NonNull ConnectionCallback callback);
-
- /**
- * Called when the client requests to disconnect from the route
- * or abort a connection attempt in progress.
- */
- public abstract void onDisconnect();
-
- /**
- * Called when the client requests to pause streaming of content to
- * live audio/video routes such as when it goes into the background.
- * <p>
- * The default implementation does nothing.
- * </p>
- */
- public void onPauseStream() { }
-
- /**
- * Called when the application requests to resume streaming of content to
- * live audio/video routes such as when it returns to the foreground.
- * <p>
- * The default implementation does nothing.
- * </p>
- */
- public void onResumeStream() { }
-
- /**
- * Called when the client is releasing the session.
- * <p>
- * The framework automatically takes care of stopping discovery and
- * terminating the connection politely before calling this method to release
- * the session.
- * </p><p>
- * The default implementation does nothing.
- * </p>
- */
- public void onRelease() { }
- }
-
- /**
- * Provides events in response to a discovery request.
- */
- public final class DiscoveryCallback {
- private final ClientRecord mRecord;
-
- DiscoveryCallback(ClientRecord record) {
- mRecord = record;
- }
-
- /**
- * Called by the service when a destination is found that
- * offers one or more routes that satisfy the discovery request.
- * <p>
- * This method should be called whenever the list of available routes
- * at a destination changes or whenever the properties of the destination
- * itself change.
- * </p>
- *
- * @param destination The destination that was found.
- * @param routes The list of that destination's routes that satisfy the
- * discovery request.
- */
- public void onDestinationFound(final @NonNull DestinationInfo destination,
- final @NonNull List<RouteInfo> routes) {
- if (destination == null) {
- throw new IllegalArgumentException("destination must not be null");
- }
- if (routes == null) {
- throw new IllegalArgumentException("routes must not be null");
- }
- for (int i = 0; i < routes.size(); i++) {
- if (routes.get(i).getDestination() != destination) {
- throw new IllegalArgumentException("routes must refer to the "
- + "destination");
- }
- }
-
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mRecord.dispatchDestinationFound(DiscoveryCallback.this,
- destination, routes);
- }
- });
- }
-
- /**
- * Called by the service when a destination is no longer
- * reachable or is no longer offering any routes that satisfy
- * the discovery request.
- *
- * @param destination The destination that went away.
- */
- public void onDestinationLost(final @NonNull DestinationInfo destination) {
- if (destination == null) {
- throw new IllegalArgumentException("destination must not be null");
- }
-
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mRecord.dispatchDestinationLost(DiscoveryCallback.this, destination);
- }
- });
- }
-
- /**
- * Called by the service when a discovery has failed in a non-recoverable manner.
- *
- * @param error The error code: one of
- * {@link MediaRouter#DISCOVERY_ERROR_UNKNOWN},
- * {@link MediaRouter#DISCOVERY_ERROR_ABORTED},
- * or {@link MediaRouter#DISCOVERY_ERROR_NO_CONNECTIVITY}.
- * @param message The localized error message, or null if none. This message
- * may be shown to the user.
- * @param extras Additional information about the error which a client
- * may use, or null if none.
- */
- public void onDiscoveryFailed(final @DiscoveryError int error,
- final @Nullable CharSequence message, final @Nullable Bundle extras) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mRecord.dispatchDiscoveryFailed(DiscoveryCallback.this,
- error, message, extras);
- }
- });
- }
- }
-
- /**
- * Provides events in response to a connection request.
- */
- public final class ConnectionCallback {
- private final ClientRecord mRecord;
-
- ConnectionCallback(ClientRecord record) {
- mRecord = record;
- }
-
- /**
- * Called by the service when the connection succeeds.
- *
- * @param connection Immutable information about the connection.
- */
- public void onConnected(final @NonNull ConnectionInfo connection) {
- if (connection == null) {
- throw new IllegalArgumentException("connection must not be null");
- }
-
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mRecord.dispatchConnected(ConnectionCallback.this, connection);
- }
- });
- }
-
- /**
- * Called by the service when the connection is terminated normally.
- * <p>
- * Abnormal termination is reported via {@link #onConnectionFailed}.
- * </p>
- */
- public void onDisconnected() {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mRecord.dispatchDisconnected(ConnectionCallback.this);
- }
- });
- }
-
- /**
- * Called by the service when a connection attempt or connection in
- * progress has failed in a non-recoverable manner.
- *
- * @param error The error code: one of
- * {@link MediaRouter#CONNECTION_ERROR_ABORTED},
- * {@link MediaRouter#CONNECTION_ERROR_UNAUTHORIZED},
- * {@link MediaRouter#CONNECTION_ERROR_UNREACHABLE},
- * {@link MediaRouter#CONNECTION_ERROR_BUSY},
- * {@link MediaRouter#CONNECTION_ERROR_TIMEOUT},
- * {@link MediaRouter#CONNECTION_ERROR_BROKEN},
- * or {@link MediaRouter#CONNECTION_ERROR_BARGED}.
- * @param message The localized error message, or null if none. This message
- * may be shown to the user.
- * @param extras Additional information about the error which a client
- * may use, or null if none.
- */
- public void onConnectionFailed(final @ConnectionError int error,
- final @Nullable CharSequence message, final @Nullable Bundle extras) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mRecord.dispatchConnectionFailed(ConnectionCallback.this,
- error, message, extras);
- }
- });
- }
- }
-
- /**
- * Identifies a client of the media route service.
- */
- public static final class ClientInfo {
- private final int mUid;
- private final String mPackageName;
-
- ClientInfo(int uid, String packageName) {
- mUid = uid;
- mPackageName = packageName;
- }
-
- /**
- * Gets the UID of the client application.
- */
- public int getUid() {
- return mUid;
- }
-
- /**
- * Gets the package name of the client application.
- */
- public @NonNull String getPackageName() {
- return mPackageName;
- }
-
- @Override
- public @NonNull String toString() {
- return "ClientInfo{ uid=" + mUid + ", package=" + mPackageName + " }";
- }
- }
-
- private final class BinderService extends IMediaRouteService.Stub {
- @Override
- public void registerClient(final int clientUid, final String clientPackageName,
- final IMediaRouteClientCallback callback) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- ClientInfo client = new ClientInfo(clientUid, clientPackageName);
- if (DEBUG) {
- Log.d(TAG, "registerClient: client=" + client);
- }
-
- ClientSession session = onCreateClientSession(client);
- if (session == null) {
- // request refused by service
- Log.w(TAG, "Media route service refused to create session for client: "
- + "client=" + client);
- return;
- }
-
- ClientRecord record = new ClientRecord(callback, client, session);
- try {
- callback.asBinder().linkToDeath(record, 0);
- } catch (RemoteException ex) {
- // client died prematurely
- Log.w(TAG, "Client died prematurely while creating session: "
- + "client=" + client);
- record.release();
- return;
- }
-
- mClientRecords.put(callback.asBinder(), record);
- }
- });
- }
-
- @Override
- public void unregisterClient(IMediaRouteClientCallback callback) {
- unregisterClient(callback, false);
- }
-
- void unregisterClient(final IMediaRouteClientCallback callback,
- final boolean died) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- ClientRecord record = mClientRecords.remove(callback.asBinder());
- if (record == null) {
- return; // spurious
- }
-
- if (DEBUG) {
- Log.d(TAG, "unregisterClient: client=" + record.getClientInfo()
- + ", died=" + died);
- }
-
- record.release();
- callback.asBinder().unlinkToDeath(record, 0);
- }
- });
- }
-
- @Override
- public void startDiscovery(final IMediaRouteClientCallback callback,
- final int seq, final List<MediaRouteSelector> selectors,
- final int flags) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- ClientRecord record = mClientRecords.get(callback.asBinder());
- if (record == null) {
- return; // spurious
- }
-
- if (DEBUG) {
- Log.d(TAG, "startDiscovery: client=" + record.getClientInfo()
- + ", seq=" + seq + ", selectors=" + selectors
- + ", flags=0x" + Integer.toHexString(flags));
- }
- record.startDiscovery(seq, selectors, flags);
- }
- });
- }
-
- @Override
- public void stopDiscovery(final IMediaRouteClientCallback callback) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- ClientRecord record = mClientRecords.get(callback.asBinder());
- if (record == null) {
- return; // spurious
- }
-
- if (DEBUG) {
- Log.d(TAG, "stopDiscovery: client=" + record.getClientInfo());
- }
- record.stopDiscovery();
- }
- });
- }
-
- @Override
- public void connect(final IMediaRouteClientCallback callback,
- final int seq, final String destinationId, final String routeId,
- final int flags, final Bundle extras) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- ClientRecord record = mClientRecords.get(callback.asBinder());
- if (record == null) {
- return; // spurious
- }
-
- if (DEBUG) {
- Log.d(TAG, "connect: client=" + record.getClientInfo()
- + ", seq=" + seq + ", destinationId=" + destinationId
- + ", routeId=" + routeId
- + ", flags=0x" + Integer.toHexString(flags)
- + ", extras=" + extras);
- }
- record.connect(seq, destinationId, routeId, flags, extras);
- }
- });
- }
-
- @Override
- public void disconnect(final IMediaRouteClientCallback callback) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- ClientRecord record = mClientRecords.get(callback.asBinder());
- if (record == null) {
- return; // spurious
- }
-
- if (DEBUG) {
- Log.d(TAG, "disconnect: client=" + record.getClientInfo());
- }
- record.disconnect();
- }
- });
- }
-
- @Override
- public void pauseStream(final IMediaRouteClientCallback callback) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- ClientRecord record = mClientRecords.get(callback.asBinder());
- if (record == null) {
- return; // spurious
- }
-
- if (DEBUG) {
- Log.d(TAG, "pauseStream: client=" + record.getClientInfo());
- }
- record.pauseStream();
- }
- });
- }
-
- @Override
- public void resumeStream(final IMediaRouteClientCallback callback) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- ClientRecord record = mClientRecords.get(callback.asBinder());
- if (record == null) {
- return; // spurious
- }
-
- if (DEBUG) {
- Log.d(TAG, "resumeStream: client=" + record.getClientInfo());
- }
- record.resumeStream();
- }
- });
- }
- }
-
- // Must be accessed on handler
- private final class ClientRecord implements IBinder.DeathRecipient {
- private final IMediaRouteClientCallback mClientCallback;
- private final ClientInfo mClient;
- private final ClientSession mSession;
-
- private int mDiscoverySeq;
- private DiscoveryRequest mDiscoveryRequest;
- private DiscoveryCallback mDiscoveryCallback;
- private final ArrayMap<String, DestinationRecord> mDestinations =
- new ArrayMap<String, DestinationRecord>();
-
- private int mConnectionSeq;
- private ConnectionRequest mConnectionRequest;
- private ConnectionCallback mConnectionCallback;
- private ConnectionInfo mConnection;
- private boolean mConnectionPaused;
-
- public ClientRecord(IMediaRouteClientCallback callback,
- ClientInfo client, ClientSession session) {
- mClientCallback = callback;
- mClient = client;
- mSession = session;
- }
-
- // Invoked on binder thread unlike all other methods in this class.
- @Override
- public void binderDied() {
- mService.unregisterClient(mClientCallback, true);
- }
-
- public ClientInfo getClientInfo() {
- return mClient;
- }
-
- public void release() {
- stopDiscovery();
- disconnect();
- }
-
- public void startDiscovery(int seq, List<MediaRouteSelector> selectors,
- int flags) {
- stopDiscovery();
-
- mDiscoverySeq = seq;
- mDiscoveryRequest = new DiscoveryRequest(selectors);
- mDiscoveryRequest.setFlags(flags);
- mDiscoveryCallback = new DiscoveryCallback(this);
- boolean started = mSession.onStartDiscovery(mDiscoveryRequest, mDiscoveryCallback);
- if (!started) {
- dispatchDiscoveryFailed(mDiscoveryCallback,
- MediaRouter.DISCOVERY_ERROR_ABORTED, null, null);
- clearDiscovery();
- }
- }
-
- public void stopDiscovery() {
- if (mDiscoveryRequest != null) {
- mSession.onStopDiscovery();
- clearDiscovery();
- }
- }
-
- private void clearDiscovery() {
- mDestinations.clear();
- mDiscoveryRequest = null;
- mDiscoveryCallback = null;
- }
-
- public void connect(int seq, String destinationId, String routeId,
- int flags, Bundle extras) {
- disconnect();
-
- mConnectionSeq = seq;
- mConnectionCallback = new ConnectionCallback(this);
-
- DestinationRecord destinationRecord = mDestinations.get(destinationId);
- if (destinationRecord == null) {
- Log.w(TAG, "Aborting connection to route since no matching destination "
- + "was found in the list of known destinations: "
- + "destinationId=" + destinationId);
- dispatchConnectionFailed(mConnectionCallback,
- MediaRouter.CONNECTION_ERROR_ABORTED, null, null);
- clearConnection();
- return;
- }
-
- RouteInfo route = destinationRecord.getRoute(routeId);
- if (route == null) {
- Log.w(TAG, "Aborting connection to route since no matching route "
- + "was found in the list of known routes: "
- + "destination=" + destinationRecord.destination
- + ", routeId=" + routeId);
- dispatchConnectionFailed(mConnectionCallback,
- MediaRouter.CONNECTION_ERROR_ABORTED, null, null);
- clearConnection();
- return;
- }
-
- mConnectionRequest = new ConnectionRequest(route);
- mConnectionRequest.setFlags(flags);
- mConnectionRequest.setExtras(extras);
- boolean started = mSession.onConnect(mConnectionRequest, mConnectionCallback);
- if (!started) {
- dispatchConnectionFailed(mConnectionCallback,
- MediaRouter.CONNECTION_ERROR_ABORTED, null, null);
- clearConnection();
- }
- }
-
- public void disconnect() {
- if (mConnectionRequest != null) {
- mSession.onDisconnect();
- clearConnection();
- }
- }
-
- private void clearConnection() {
- mConnectionRequest = null;
- mConnectionCallback = null;
- if (mConnection != null) {
- mConnection.close();
- mConnection = null;
- }
- mConnectionPaused = false;
- }
-
- public void pauseStream() {
- if (mConnectionRequest != null && !mConnectionPaused) {
- mConnectionPaused = true;
- mSession.onPauseStream();
- }
- }
-
- public void resumeStream() {
- if (mConnectionRequest != null && mConnectionPaused) {
- mConnectionPaused = false;
- mSession.onResumeStream();
- }
- }
-
- public void dispatchDestinationFound(DiscoveryCallback callback,
- DestinationInfo destination, List<RouteInfo> routes) {
- if (callback == mDiscoveryCallback) {
- if (DEBUG) {
- Log.d(TAG, "destinationFound: destination=" + destination
- + ", routes=" + routes);
- }
- mDestinations.put(destination.getId(),
- new DestinationRecord(destination, routes));
-
- ParcelableDestinationInfo pdi = new ParcelableDestinationInfo();
- pdi.id = destination.getId();
- pdi.name = destination.getName();
- pdi.description = destination.getDescription();
- pdi.iconResourceId = destination.getIconResourceId();
- pdi.extras = destination.getExtras();
- ArrayList<ParcelableRouteInfo> pris = new ArrayList<ParcelableRouteInfo>();
- for (RouteInfo route : routes) {
- int selectorIndex = mDiscoveryRequest.getSelectors().indexOf(
- route.getSelector());
- if (selectorIndex < 0) {
- Log.w(TAG, "Ignoring route because the selector does not match "
- + "any of those that were originally supplied by the "
- + "client's discovery request: destination=" + destination
- + ", route=" + route);
- continue;
- }
-
- ParcelableRouteInfo pri = new ParcelableRouteInfo();
- pri.id = route.getId();
- pri.selectorIndex = selectorIndex;
- pri.features = route.getFeatures();
- pri.protocols = route.getProtocols().toArray(
- new String[route.getProtocols().size()]);
- pri.extras = route.getExtras();
- pris.add(pri);
- }
- try {
- mClientCallback.onDestinationFound(mDiscoverySeq, pdi,
- pris.toArray(new ParcelableRouteInfo[pris.size()]));
- } catch (RemoteException ex) {
- // binder death handled elsewhere
- }
- }
- }
-
- public void dispatchDestinationLost(DiscoveryCallback callback,
- DestinationInfo destination) {
- if (callback == mDiscoveryCallback) {
- if (DEBUG) {
- Log.d(TAG, "destinationLost: destination=" + destination);
- }
-
- if (mDestinations.get(destination.getId()).destination == destination) {
- mDestinations.remove(destination.getId());
- try {
- mClientCallback.onDestinationLost(mDiscoverySeq, destination.getId());
- } catch (RemoteException ex) {
- // binder death handled elsewhere
- }
- }
- }
- }
-
- public void dispatchDiscoveryFailed(DiscoveryCallback callback,
- int error, CharSequence message, Bundle extras) {
- if (callback == mDiscoveryCallback) {
- if (DEBUG) {
- Log.d(TAG, "discoveryFailed: error=" + error + ", message=" + message
- + ", extras=" + extras);
- }
-
- try {
- mClientCallback.onDiscoveryFailed(mDiscoverySeq, error, message, extras);
- } catch (RemoteException ex) {
- // binder death handled elsewhere
- }
- }
- }
-
- public void dispatchConnected(ConnectionCallback callback, ConnectionInfo connection) {
- if (callback == mConnectionCallback) {
- if (DEBUG) {
- Log.d(TAG, "connected: connection=" + connection);
- }
- if (mConnection == null) {
- mConnection = connection;
-
- ParcelableConnectionInfo pci = new ParcelableConnectionInfo();
- pci.audioAttributes = connection.getAudioAttributes();
- pci.presentationDisplayId = connection.getPresentationDisplay() != null ?
- connection.getPresentationDisplay().getDisplayId() : -1;
- pci.protocolBinders = new IBinder[connection.getProtocols().size()];
- for (int i = 0; i < pci.protocolBinders.length; i++) {
- pci.protocolBinders[i] = connection.getProtocolBinder(i);
- }
- pci.extras = connection.getExtras();
- try {
- mClientCallback.onConnected(mConnectionSeq, pci);
- } catch (RemoteException ex) {
- // binder death handled elsewhere
- }
- } else {
- Log.w(TAG, "Media route service called onConnected() while already "
- + "connected.");
- }
- }
- }
-
- public void dispatchDisconnected(ConnectionCallback callback) {
- if (callback == mConnectionCallback) {
- if (DEBUG) {
- Log.d(TAG, "disconnected");
- }
-
- if (mConnection != null) {
- mConnection.close();
- mConnection = null;
-
- try {
- mClientCallback.onDisconnected(mConnectionSeq);
- } catch (RemoteException ex) {
- // binder death handled elsewhere
- }
- }
- }
- }
-
- public void dispatchConnectionFailed(ConnectionCallback callback,
- int error, CharSequence message, Bundle extras) {
- if (callback == mConnectionCallback) {
- if (DEBUG) {
- Log.d(TAG, "connectionFailed: error=" + error + ", message=" + message
- + ", extras=" + extras);
- }
-
- try {
- mClientCallback.onConnectionFailed(mConnectionSeq, error, message, extras);
- } catch (RemoteException ex) {
- // binder death handled elsewhere
- }
- }
- }
- }
-
- private static final class DestinationRecord {
- public final DestinationInfo destination;
- public final List<RouteInfo> routes;
-
- public DestinationRecord(DestinationInfo destination, List<RouteInfo> routes) {
- this.destination = destination;
- this.routes = routes;
- }
-
- public RouteInfo getRoute(String routeId) {
- final int count = routes.size();
- for (int i = 0; i < count; i++) {
- RouteInfo route = routes.get(i);
- if (route.getId().equals(routeId)) {
- return route;
- }
- }
- return null;
- }
- }
-}
diff --git a/media/java/android/media/routing/MediaRouter.java b/media/java/android/media/routing/MediaRouter.java
deleted file mode 100644
index 4f6d324..0000000
--- a/media/java/android/media/routing/MediaRouter.java
+++ /dev/null
@@ -1,1886 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.media.routing;
-
-import android.annotation.DrawableRes;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Presentation;
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ServiceInfo;
-import android.graphics.drawable.Drawable;
-import android.hardware.display.DisplayManager;
-import android.media.AudioAttributes;
-import android.media.AudioManager;
-import android.media.AudioTrack;
-import android.media.VolumeProvider;
-import android.media.session.MediaController;
-import android.media.session.MediaSession;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.view.Display;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Media router allows applications to discover, connect to, control,
- * and send content to nearby media devices known as destinations.
- * <p>
- * There are generally two participants involved in media routing: an
- * application that wants to send media content to a destination and a
- * {@link MediaRouteService media route service} that provides the
- * service of transporting that content where it needs to go on behalf of the
- * application.
- * </p><p>
- * To send media content to a destination, the application must ask the system
- * to discover available routes to destinations that provide certain capabilities,
- * establish a connection to a route, then send messages through the connection to
- * control the routing of audio and video streams, launch remote applications,
- * and invoke other functions of the destination.
- * </p><p>
- * Media router objects are thread-safe.
- * </p>
- *
- * <h3>Destinations</h3>
- * <p>
- * The media devices to which an application may send media content are referred
- * to in the API as destinations. Each destination therefore represents a single
- * independent device such as a speaker or TV set. Destinations are given meaningful
- * names and descriptions to help the user associate them with devices in their
- * environment.
- * </p><p>
- * Destinations may be local or remote and may be accessed through various means,
- * often wirelessly. The user may install media route services to enable
- * media applications to connect to a variety of destinations with different
- * capabilities.
- * </p>
- *
- * <h3>Routes</h3>
- * <p>
- * Routes represent possible usages or means of reaching and interacting with
- * a destination. Since destinations may support many different features, they may
- * each offer multiple routes for applications to choose from based on their needs.
- * For example, one route might express the ability to stream locally rendered audio
- * and video to the device; another route might express the ability to send a URL for
- * the destination to download from the network and play all by itself.
- * </p><p>
- * Routes are discovered according to the set of capabilities that
- * an application or the system is seeking to use at a particular time. For example,
- * if an application wants to stream music to a destination then it will ask the
- * {@link MediaRouter} to find routes to destinations can stream music and ignore
- * all other destinations that cannot.
- * </p><p>
- * In general, the application will inspect the set of routes that have been
- * offered then connect to the most appropriate route for its desired purpose.
- * </p>
- *
- * <h3>Route Selection</h3>
- * <p>
- * When the user open the media route chooser activity, the system will display
- * a list of nearby media destinations which have been discovered. After the
- * choice is made the application may connect to one of the routes offered by
- * this destination and begin communicating with the destination.
- * </p><p>
- * Destinations are located through a process called discovery. During discovery,
- * the system will start installed {@link MediaRouteService media route services}
- * to scan the network for nearby devices that offer the kinds of capabilities that the
- * application is seeking to use. The application specifies the capabilities it requires by
- * adding {@link MediaRouteSelector media route selectors} to the media router
- * using the {@link #addSelector} method. Only destinations that provide routes
- * which satisfy at least one of these media route selectors will be discovered.
- * </p><p>
- * Once the user has selected a destination, the application will be given a chance
- * to choose one of the routes to which it would like to connect. The application
- * may switch to a different route from the same destination at a later time but
- * in order to connect to a new destination, the application must once again launch
- * the media route chooser activity to ask the user to choose a destination.
- * </p>
- *
- * <h3>Route Protocols</h3>
- * <p>
- * Route protocols express capabilities offered by routes. Each media route selector
- * must specify at least one required protocol by which the routes will be selected.
- * </p><p>
- * The framework provides several predefined <code>MediaRouteProtocols</code> which are
- * defined in the <code>android-support-media-protocols.jar</code> support library.
- * Applications must statically link this library to make use of these protocols.
- * </p><p>
- * The static library approach is used to enable ongoing extension and refinement
- * of protocols in the SDK and interoperability with the media router implementation
- * for older platform versions which is offered by the framework support library.
- * </p><p>
- * Media route services may also define custom media route protocols of their own
- * to enable applications to access specialized capabilities of certain destinations
- * assuming they have linked in the required protocol code.
- * </p><p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code> for more information.
- * </p>
- *
- * <h3>Connections</h3>
- * <p>
- * After connecting to a media route, the application can send commands to
- * the route using any of the protocols that it requested. If the route supports live
- * audio or video streaming then the application can create an {@link AudioTrack} or
- * {@link Presentation} to route locally generated content to the destination.
- * </p>
- *
- * <h3>Delegation</h3>
- * <p>
- * The creator of the media router is responsible for establishing the policy for
- * discovering and connecting to destinations. UI components may observe the state
- * of the media router by {@link #createDelegate creating} a {@link Delegate}.
- * </p><p>
- * The media router should also be attached to the {@link MediaSession media session}
- * that is handling media playback lifecycle. This will allow
- * authorized {@link MediaController media controllers}, possibly running in other
- * processes, to provide UI to examine and change the media destination by
- * {@link MediaController#createMediaRouterDelegate creating} a {@link Delegate}
- * for the media router associated with the session.
- * </p>
- */
-public final class MediaRouter {
- private final DisplayManager mDisplayManager;
-
- private final Object mLock = new Object();
-
- private RoutingCallback mRoutingCallback;
- private Handler mRoutingCallbackHandler;
-
- private boolean mReleased;
- private int mDiscoveryState;
- private int mConnectionState;
- private final ArrayList<MediaRouteSelector> mSelectors =
- new ArrayList<MediaRouteSelector>();
- private final ArrayMap<DestinationInfo, List<RouteInfo>> mDiscoveredDestinations =
- new ArrayMap<DestinationInfo, List<RouteInfo>>();
- private RouteInfo mSelectedRoute;
- private ConnectionInfo mConnection;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = { DISCOVERY_STATE_STOPPED, DISCOVERY_STATE_STARTED })
- public @interface DiscoveryState { }
-
- /**
- * Discovery state: Discovery is not currently in progress.
- */
- public static final int DISCOVERY_STATE_STOPPED = 0;
-
- /**
- * Discovery state: Discovery is being performed.
- */
- public static final int DISCOVERY_STATE_STARTED = 1;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, value = { DISCOVERY_FLAG_BACKGROUND })
- public @interface DiscoveryFlags { }
-
- /**
- * Discovery flag: Indicates that the client has requested passive discovery in
- * the background. The media route service should try to use less power and rely
- * more on its internal caches to minimize its impact.
- */
- public static final int DISCOVERY_FLAG_BACKGROUND = 1 << 0;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = { DISCOVERY_ERROR_UNKNOWN, DISCOVERY_ERROR_ABORTED,
- DISCOVERY_ERROR_NO_CONNECTIVITY })
- public @interface DiscoveryError { }
-
- /**
- * Discovery error: Unknown error; refer to the error message for details.
- */
- public static final int DISCOVERY_ERROR_UNKNOWN = 0;
-
- /**
- * Discovery error: The media router or media route service has decided not to
- * handle the discovery request for some reason.
- */
- public static final int DISCOVERY_ERROR_ABORTED = 1;
-
- /**
- * Discovery error: The media route service is unable to perform discovery
- * due to a lack of connectivity such as because the radio is disabled.
- */
- public static final int DISCOVERY_ERROR_NO_CONNECTIVITY = 2;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = { CONNECTION_STATE_DISCONNECTED, CONNECTION_STATE_CONNECTING,
- CONNECTION_STATE_CONNECTED })
- public @interface ConnectionState { }
-
- /**
- * Connection state: No destination has been selected. Media content should
- * be sent to the default output.
- */
- public static final int CONNECTION_STATE_DISCONNECTED = 0;
-
- /**
- * Connection state: The application is in the process of connecting to
- * a route offered by the selected destination.
- */
- public static final int CONNECTION_STATE_CONNECTING = 1;
-
- /**
- * Connection state: The application has connected to a route offered by
- * the selected destination.
- */
- public static final int CONNECTION_STATE_CONNECTED = 2;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, value = { CONNECTION_FLAG_BARGE })
- public @interface ConnectionFlags { }
-
- /**
- * Connection flag: Indicates that the client has requested to barge in and evict
- * other clients that might have already connected to the destination and that
- * would otherwise prevent this client from connecting. When this flag is not
- * set, the media route service should be polite and report
- * {@link MediaRouter#CONNECTION_ERROR_BUSY} in case the destination is
- * already occupied and cannot accept additional connections.
- */
- public static final int CONNECTION_FLAG_BARGE = 1 << 0;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = { CONNECTION_ERROR_UNKNOWN, CONNECTION_ERROR_ABORTED,
- CONNECTION_ERROR_UNAUTHORIZED, CONNECTION_ERROR_UNAUTHORIZED,
- CONNECTION_ERROR_BUSY, CONNECTION_ERROR_TIMEOUT, CONNECTION_ERROR_BROKEN })
- public @interface ConnectionError { }
-
- /**
- * Connection error: Unknown error; refer to the error message for details.
- */
- public static final int CONNECTION_ERROR_UNKNOWN = 0;
-
- /**
- * Connection error: The media router or media route service has decided not to
- * handle the connection request for some reason.
- */
- public static final int CONNECTION_ERROR_ABORTED = 1;
-
- /**
- * Connection error: The device has refused the connection from this client.
- * This error should be avoided because the media route service should attempt
- * to filter out devices that the client cannot access as it performs discovery
- * on behalf of that client.
- */
- public static final int CONNECTION_ERROR_UNAUTHORIZED = 2;
-
- /**
- * Connection error: The device is unreachable over the network.
- */
- public static final int CONNECTION_ERROR_UNREACHABLE = 3;
-
- /**
- * Connection error: The device is already busy serving another client and
- * the connection request did not ask to barge in.
- */
- public static final int CONNECTION_ERROR_BUSY = 4;
-
- /**
- * Connection error: A timeout occurred during connection.
- */
- public static final int CONNECTION_ERROR_TIMEOUT = 5;
-
- /**
- * Connection error: The connection to the device was severed unexpectedly.
- */
- public static final int CONNECTION_ERROR_BROKEN = 6;
-
- /**
- * Connection error: The connection was terminated because a different client barged
- * in and took control of the destination.
- */
- public static final int CONNECTION_ERROR_BARGED = 7;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = { DISCONNECTION_REASON_APPLICATION_REQUEST,
- DISCONNECTION_REASON_USER_REQUEST, DISCONNECTION_REASON_ERROR })
- public @interface DisconnectionReason { }
-
- /**
- * Disconnection reason: The application requested disconnection itself.
- */
- public static final int DISCONNECTION_REASON_APPLICATION_REQUEST = 0;
-
- /**
- * Disconnection reason: The user requested disconnection.
- */
- public static final int DISCONNECTION_REASON_USER_REQUEST = 1;
-
- /**
- * Disconnection reason: An error occurred.
- */
- public static final int DISCONNECTION_REASON_ERROR = 2;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, value = { ROUTE_FEATURE_LIVE_AUDIO, ROUTE_FEATURE_LIVE_VIDEO })
- public @interface RouteFeatures { }
-
- /**
- * Route feature: Live audio.
- * <p>
- * A route that supports live audio streams audio rendered by the application
- * to the destination.
- * </p><p>
- * To take advantage of live audio routing, the application must render its
- * media using the audio attributes specified by {@link #getPreferredAudioAttributes}.
- * </p>
- *
- * @see #getPreferredAudioAttributes
- * @see android.media.AudioAttributes
- */
- public static final int ROUTE_FEATURE_LIVE_AUDIO = 1 << 0;
-
- /**
- * Route feature: Live video.
- * <p>
- * A route that supports live video streams video rendered by the application
- * to the destination.
- * </p><p>
- * To take advantage of live video routing, the application must render its
- * media to a {@link android.app.Presentation presentation window} on the
- * display specified by {@link #getPreferredPresentationDisplay}.
- * </p>
- *
- * @see #getPreferredPresentationDisplay
- * @see android.app.Presentation
- */
- public static final int ROUTE_FEATURE_LIVE_VIDEO = 1 << 1;
-
- /**
- * Creates a media router.
- *
- * @param context The context with which the router is associated.
- */
- public MediaRouter(@NonNull Context context) {
- if (context == null) {
- throw new IllegalArgumentException("context must not be null");
- }
-
- mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
- }
-
- /** @hide */
- public IMediaRouter getBinder() {
- // todo
- return null;
- }
-
- /**
- * Disconnects from the selected destination and releases the media router.
- * <p>
- * This method should be called by the application when it no longer requires
- * the media router to ensure that all bound resources may be cleaned up.
- * </p>
- */
- public void release() {
- synchronized (mLock) {
- mReleased = true;
- // todo
- }
- }
-
- /**
- * Returns true if the media router has been released.
- */
- public boolean isReleased() {
- synchronized (mLock) {
- return mReleased;
- }
- }
-
- /**
- * Gets the current route discovery state.
- *
- * @return The current discovery state: one of {@link #DISCOVERY_STATE_STOPPED},
- * {@link #DISCOVERY_STATE_STARTED}.
- */
- public @DiscoveryState int getDiscoveryState() {
- synchronized (mLock) {
- return mDiscoveryState;
- }
- }
-
- /**
- * Gets the current route connection state.
- *
- * @return The current state: one of {@link #CONNECTION_STATE_DISCONNECTED},
- * {@link #CONNECTION_STATE_CONNECTING} or {@link #CONNECTION_STATE_CONNECTED}.
- */
- public @ConnectionState int getConnectionState() {
- synchronized (mLock) {
- return mConnectionState;
- }
- }
-
- /**
- * Creates a media router delegate through which the destination of the media
- * router may be controlled.
- * <p>
- * This is the point of entry for UI code that initiates discovery and
- * connection to routes.
- * </p>
- */
- public @NonNull Delegate createDelegate() {
- return null; // todo
- }
-
- /**
- * Sets a callback to participate in route discovery, filtering, and connection
- * establishment.
- *
- * @param callback The callback to set, or null if none.
- * @param handler The handler to receive callbacks, or null to use the current thread.
- */
- public void setRoutingCallback(@Nullable RoutingCallback callback,
- @Nullable Handler handler) {
- synchronized (mLock) {
- if (callback == null) {
- mRoutingCallback = null;
- mRoutingCallbackHandler = null;
- } else {
- mRoutingCallback = callback;
- mRoutingCallbackHandler = handler != null ? handler : new Handler();
- }
- }
- }
-
- /**
- * Adds a media route selector to use to find destinations that have
- * routes with the specified capabilities during route discovery.
- */
- public void addSelector(@NonNull MediaRouteSelector selector) {
- if (selector == null) {
- throw new IllegalArgumentException("selector must not be null");
- }
-
- synchronized (mLock) {
- if (!mSelectors.contains(selector)) {
- mSelectors.add(selector);
- // todo
- }
- }
- }
-
- /**
- * Removes a media route selector.
- */
- public void removeSelector(@NonNull MediaRouteSelector selector) {
- if (selector == null) {
- throw new IllegalArgumentException("selector must not be null");
- }
-
- synchronized (mLock) {
- if (mSelectors.remove(selector)) {
- // todo
- }
- }
- }
-
- /**
- * Removes all media route selectors.
- * <p>
- * Note that at least one selector must be added in order to perform discovery.
- * </p>
- */
- public void clearSelectors() {
- synchronized (mLock) {
- if (!mSelectors.isEmpty()) {
- mSelectors.clear();
- // todo
- }
- }
- }
-
- /**
- * Gets a list of all media route selectors to consider during discovery.
- */
- public @NonNull List<MediaRouteSelector> getSelectors() {
- synchronized (mLock) {
- return new ArrayList<MediaRouteSelector>(mSelectors);
- }
- }
-
- /**
- * Gets the connection to the currently selected route.
- *
- * @return The connection to the currently selected route, or null if not connected.
- */
- public @NonNull ConnectionInfo getConnection() {
- synchronized (mLock) {
- return mConnection;
- }
- }
-
- /**
- * Gets the list of discovered destinations.
- * <p>
- * This list is only valid while discovery is running and is null otherwise.
- * </p>
- *
- * @return The list of discovered destinations, or null if discovery is not running.
- */
- public @NonNull List<DestinationInfo> getDiscoveredDestinations() {
- synchronized (mLock) {
- if (mDiscoveryState == DISCOVERY_STATE_STARTED) {
- return new ArrayList<DestinationInfo>(mDiscoveredDestinations.keySet());
- }
- return null;
- }
- }
-
- /**
- * Gets the list of discovered routes for a particular destination.
- * <p>
- * This list is only valid while discovery is running and is null otherwise.
- * </p>
- *
- * @param destination The destination for which to get the list of discovered routes.
- * @return The list of discovered routes for the destination, or null if discovery
- * is not running.
- */
- public @NonNull List<RouteInfo> getDiscoveredRoutes(@NonNull DestinationInfo destination) {
- if (destination == null) {
- throw new IllegalArgumentException("destination must not be null");
- }
- synchronized (mLock) {
- if (mDiscoveryState == DISCOVERY_STATE_STARTED) {
- List<RouteInfo> routes = mDiscoveredDestinations.get(destination);
- if (routes != null) {
- return new ArrayList<RouteInfo>(routes);
- }
- }
- return null;
- }
- }
-
- /**
- * Gets the destination that has been selected.
- *
- * @return The selected destination, or null if disconnected.
- */
- public @Nullable DestinationInfo getSelectedDestination() {
- synchronized (mLock) {
- return mSelectedRoute != null ? mSelectedRoute.getDestination() : null;
- }
- }
-
- /**
- * Gets the route that has been selected.
- *
- * @return The selected destination, or null if disconnected.
- */
- public @Nullable RouteInfo getSelectedRoute() {
- synchronized (mLock) {
- return mSelectedRoute;
- }
- }
-
- /**
- * Gets the preferred audio attributes that should be used to stream live audio content
- * based on the connected route.
- * <p>
- * Use an {@link AudioTrack} to send audio content to the destination with these
- * audio attributes.
- * </p><p>
- * The preferred audio attributes may change when a connection is established but it
- * will remain constant until disconnected.
- * </p>
- *
- * @return The preferred audio attributes to use. When connected, returns the
- * route's audio attributes or null if it does not support live audio streaming.
- * Otherwise returns audio attributes associated with {@link AudioAttributes#USAGE_MEDIA}.
- */
- public @Nullable AudioAttributes getPreferredAudioAttributes() {
- synchronized (mLock) {
- if (mConnection != null) {
- return mConnection.getAudioAttributes();
- }
- return new AudioAttributes.Builder()
- .setLegacyStreamType(AudioManager.STREAM_MUSIC)
- .build();
- }
- }
-
- /**
- * Gets the preferred presentation display that should be used to stream live video content
- * based on the connected route.
- * <p>
- * Use a {@link Presentation} to send video content to the destination with this display.
- * </p><p>
- * The preferred presentation display may change when a connection is established but it
- * will remain constant until disconnected.
- * </p>
- *
- * @return The preferred presentation display to use. When connected, returns
- * the route's presentation display or null if it does not support live video
- * streaming. Otherwise returns the first available
- * {@link DisplayManager#DISPLAY_CATEGORY_PRESENTATION presentation display},
- * such as a mirrored wireless or HDMI display or null if none.
- */
- public @Nullable Display getPreferredPresentationDisplay() {
- synchronized (mLock) {
- if (mConnection != null) {
- return mConnection.getPresentationDisplay();
- }
- Display[] displays = mDisplayManager.getDisplays(
- DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
- return displays.length != 0 ? displays[0] : null;
- }
- }
-
- /**
- * Gets the preferred volume provider that should be used to control the volume
- * of content rendered on the currently selected route.
- * <p>
- * The preferred volume provider may change when a connection is established but it
- * will remain the same until disconnected.
- * </p>
- *
- * @return The preferred volume provider to use, or null if the currently
- * selected route does not support remote volume adjustment or if the connection
- * is not yet established. If no route is selected, returns null to indicate
- * that system volume control should be used.
- */
- public @Nullable VolumeProvider getPreferredVolumeProvider() {
- synchronized (mLock) {
- if (mConnection != null) {
- return mConnection.getVolumeProvider();
- }
- return null;
- }
- }
-
- /**
- * Requests to pause streaming of live audio or video routes.
- * Should be called when the application is going into the background and is
- * no longer rendering content locally.
- * <p>
- * This method does nothing unless a connection has been established.
- * </p>
- */
- public void pauseStream() {
- // todo
- }
-
- /**
- * Requests to resume streaming of live audio or video routes.
- * May be called when the application is returning to the foreground and is
- * about to resume rendering content locally.
- * <p>
- * This method does nothing unless a connection has been established.
- * </p>
- */
- public void resumeStream() {
- // todo
- }
-
- /**
- * This class is used by UI components to let the user discover and
- * select a destination to which the media router should connect.
- * <p>
- * This API has somewhat more limited functionality than the {@link MediaRouter}
- * itself because it is designed to allow applications to control
- * the destination of media router instances that belong to other processes.
- * </p><p>
- * To control the destination of your own media router, call
- * {@link #createDelegate} to obtain a local delegate object.
- * </p><p>
- * To control the destination of a media router that belongs to another process,
- * first obtain a {@link MediaController} that is associated with the media playback
- * that is occurring in that process, then call
- * {@link MediaController#createMediaRouterDelegate} to obtain an instance of
- * its destination controls. Note that special permissions may be required to
- * obtain the {@link MediaController} instance in the first place.
- * </p>
- */
- public static final class Delegate {
- /**
- * Returns true if the media router has been released.
- */
- public boolean isReleased() {
- // todo
- return false;
- }
-
- /**
- * Gets the current route discovery state.
- *
- * @return The current discovery state: one of {@link #DISCOVERY_STATE_STOPPED},
- * {@link #DISCOVERY_STATE_STARTED}.
- */
- public @DiscoveryState int getDiscoveryState() {
- // todo
- return -1;
- }
-
- /**
- * Gets the current route connection state.
- *
- * @return The current state: one of {@link #CONNECTION_STATE_DISCONNECTED},
- * {@link #CONNECTION_STATE_CONNECTING} or {@link #CONNECTION_STATE_CONNECTED}.
- */
- public @ConnectionState int getConnectionState() {
- // todo
- return -1;
- }
-
- /**
- * Gets the currently selected destination.
- *
- * @return The destination information, or null if none.
- */
- public @Nullable DestinationInfo getSelectedDestination() {
- return null;
- }
-
- /**
- * Gets the list of discovered destinations.
- * <p>
- * This list is only valid while discovery is running and is null otherwise.
- * </p>
- *
- * @return The list of discovered destinations, or null if discovery is not running.
- */
- public @NonNull List<DestinationInfo> getDiscoveredDestinations() {
- return null;
- }
-
- /**
- * Adds a callback to receive state changes.
- *
- * @param callback The callback to set, or null if none.
- * @param handler The handler to receive callbacks, or null to use the current thread.
- */
- public void addStateCallback(@Nullable StateCallback callback,
- @Nullable Handler handler) {
- if (callback == null) {
- throw new IllegalArgumentException("callback must not be null");
- }
- if (handler == null) {
- handler = new Handler();
- }
- // todo
- }
-
- /**
- * Removes a callback for state changes.
- *
- * @param callback The callback to set, or null if none.
- */
- public void removeStateCallback(@Nullable StateCallback callback) {
- // todo
- }
-
- /**
- * Starts performing discovery.
- * <p>
- * Performing discovery is expensive. Make sure to call {@link #stopDiscovery}
- * as soon as possible once a new destination has been selected to allow the system
- * to stop services associated with discovery.
- * </p>
- *
- * @param flags The discovery flags, such as {@link MediaRouter#DISCOVERY_FLAG_BACKGROUND}.
- */
- public void startDiscovery(@DiscoveryFlags int flags) {
- // todo
- }
-
- /**
- * Stops performing discovery.
- */
- public void stopDiscovery() {
- // todo
- }
-
- /**
- * Connects to a destination during route discovery.
- * <p>
- * This method may only be called while route discovery is active and the
- * destination appears in the
- * {@link #getDiscoveredDestinations list of discovered destinations}.
- * If the media router is already connected to a route then it will first disconnect
- * from the current route then connect to the new route.
- * </p>
- *
- * @param destination The destination to which the media router should connect.
- * @param flags The connection flags, such as {@link MediaRouter#CONNECTION_FLAG_BARGE}.
- */
- public void connect(@NonNull DestinationInfo destination, @DiscoveryFlags int flags) {
- // todo
- }
-
- /**
- * Disconnects from the currently selected destination.
- * <p>
- * Does nothing if not currently connected.
- * </p>
- *
- * @param reason The reason for the disconnection: one of
- * {@link #DISCONNECTION_REASON_APPLICATION_REQUEST},
- * {@link #DISCONNECTION_REASON_USER_REQUEST}, or {@link #DISCONNECTION_REASON_ERROR}.
- */
- public void disconnect(@DisconnectionReason int reason) {
- // todo
- }
- }
-
- /**
- * Describes immutable properties of a connection to a route.
- */
- public static final class ConnectionInfo {
- private final RouteInfo mRoute;
- private final AudioAttributes mAudioAttributes;
- private final Display mPresentationDisplay;
- private final VolumeProvider mVolumeProvider;
- private final IBinder[] mProtocolBinders;
- private final Object[] mProtocolInstances;
- private final Bundle mExtras;
- private final ArrayList<Closeable> mCloseables;
-
- private static final Class<?>[] MEDIA_ROUTE_PROTOCOL_CTOR_PARAMETERS =
- new Class<?>[] { IBinder.class };
-
- ConnectionInfo(RouteInfo route,
- AudioAttributes audioAttributes, Display display,
- VolumeProvider volumeProvider, IBinder[] protocolBinders,
- Bundle extras, ArrayList<Closeable> closeables) {
- mRoute = route;
- mAudioAttributes = audioAttributes;
- mPresentationDisplay = display;
- mVolumeProvider = volumeProvider;
- mProtocolBinders = protocolBinders;
- mProtocolInstances = new Object[mProtocolBinders.length];
- mExtras = extras;
- mCloseables = closeables;
- }
-
- /**
- * Gets the route that is connected.
- */
- public @NonNull RouteInfo getRoute() {
- return mRoute;
- }
-
- /**
- * Gets the audio attributes which the client should use to stream audio
- * to the destination, or null if the route does not support live audio streaming.
- */
- public @Nullable AudioAttributes getAudioAttributes() {
- return mAudioAttributes;
- }
-
- /**
- * Gets the display which the client should use to stream video to the
- * destination using a {@link Presentation}, or null if the route does not
- * support live video streaming.
- */
- public @Nullable Display getPresentationDisplay() {
- return mPresentationDisplay;
- }
-
- /**
- * Gets the route's volume provider, or null if none.
- */
- public @Nullable VolumeProvider getVolumeProvider() {
- return mVolumeProvider;
- }
-
- /**
- * Gets the set of supported route features.
- */
- public @RouteFeatures int getFeatures() {
- return mRoute.getFeatures();
- }
-
- /**
- * Gets the list of supported route protocols.
- * <p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
- * for more information.
- * </p>
- */
- public @NonNull List<String> getProtocols() {
- return mRoute.getProtocols();
- }
-
- /**
- * Gets an instance of a route protocol object that wraps the protocol binder
- * and provides easy access to the protocol's functionality.
- * <p>
- * This is a convenience method which invokes {@link #getProtocolBinder(String)}
- * using the name of the provided class then passes the resulting {@link IBinder}
- * to a single-argument constructor of that class.
- * </p><p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
- * for more information.
- * </p>
- */
- @SuppressWarnings("unchecked")
- public @Nullable <T> T getProtocolObject(Class<T> clazz) {
- int index = getProtocols().indexOf(clazz.getName());
- if (index < 0) {
- return null;
- }
- if (mProtocolInstances[index] == null && mProtocolBinders[index] != null) {
- final Constructor<T> ctor;
- try {
- ctor = clazz.getConstructor(MEDIA_ROUTE_PROTOCOL_CTOR_PARAMETERS);
- } catch (NoSuchMethodException ex) {
- throw new RuntimeException("Could not find public constructor "
- + "with IBinder argument in protocol class: " + clazz.getName(), ex);
- }
- try {
- mProtocolInstances[index] = ctor.newInstance(mProtocolBinders[index]);
- } catch (InstantiationException | IllegalAccessException
- | InvocationTargetException ex) {
- throw new RuntimeException("Could create instance of protocol class: "
- + clazz.getName(), ex);
- }
- }
- return (T)mProtocolInstances[index];
- }
-
- /**
- * Gets the {@link IBinder} that provides access to the specified route protocol
- * or null if the protocol is not supported.
- * <p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
- * for more information.
- * </p>
- */
- public @Nullable IBinder getProtocolBinder(@NonNull String name) {
- int index = getProtocols().indexOf(name);
- return index >= 0 ? mProtocolBinders[index] : null;
- }
-
- /**
- * Gets the {@link IBinder} that provides access to the specified route protocol
- * at the given index in the protocol list or null if the protocol is not supported.
- * <p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
- * for more information.
- * </p>
- */
- public @Nullable IBinder getProtocolBinder(int index) {
- return mProtocolBinders[index];
- }
-
- /**
- * Gets optional extra media route service or protocol specific information about
- * the connection. Use the service or protocol name as the prefix for
- * any extras to avoid namespace collisions.
- */
- public @Nullable Bundle getExtras() {
- return mExtras;
- }
-
- /**
- * Closes all closeables associated with the connection when the connection
- * is being torn down.
- */
- void close() {
- final int count = mCloseables.size();
- for (int i = 0; i < count; i++) {
- try {
- mCloseables.get(i).close();
- } catch (IOException ex) {
- }
- }
- }
-
- @Override
- public @NonNull String toString() {
- return "ConnectionInfo{ route=" + mRoute
- + ", audioAttributes=" + mAudioAttributes
- + ", presentationDisplay=" + mPresentationDisplay
- + ", volumeProvider=" + mVolumeProvider
- + ", protocolBinders=" + mProtocolBinders + " }";
- }
-
- /**
- * Builds {@link ConnectionInfo} objects.
- */
- public static final class Builder {
- private final RouteInfo mRoute;
- private AudioAttributes mAudioAttributes;
- private Display mPresentationDisplay;
- private VolumeProvider mVolumeProvider;
- private final IBinder[] mProtocols;
- private Bundle mExtras;
- private final ArrayList<Closeable> mCloseables = new ArrayList<Closeable>();
-
- /**
- * Creates a builder for connection information.
- *
- * @param route The route that is connected.
- */
- public Builder(@NonNull RouteInfo route) {
- if (route == null) {
- throw new IllegalArgumentException("route");
- }
- mRoute = route;
- mProtocols = new IBinder[route.getProtocols().size()];
- }
-
- /**
- * Sets the audio attributes which the client should use to stream audio
- * to the destination, or null if the route does not support live audio streaming.
- */
- public @NonNull Builder setAudioAttributes(
- @Nullable AudioAttributes audioAttributes) {
- mAudioAttributes = audioAttributes;
- return this;
- }
-
- /**
- * Sets the display which the client should use to stream video to the
- * destination using a {@link Presentation}, or null if the route does not
- * support live video streaming.
- */
- public @NonNull Builder setPresentationDisplay(@Nullable Display display) {
- mPresentationDisplay = display;
- return this;
- }
-
- /**
- * Sets the route's volume provider, or null if none.
- */
- public @NonNull Builder setVolumeProvider(@Nullable VolumeProvider provider) {
- mVolumeProvider = provider;
- return this;
- }
-
- /**
- * Sets the binder stub of a supported route protocol using
- * the protocol's fully qualified class name. The protocol must be one
- * of those that was indicated as being supported by the route.
- * <p>
- * If the stub implements {@link Closeable} then it will automatically
- * be closed when the client disconnects from the route.
- * </p><p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
- * for more information.
- * </p>
- */
- public @NonNull Builder setProtocolStub(@NonNull Class<?> clazz,
- @NonNull IInterface stub) {
- if (clazz == null) {
- throw new IllegalArgumentException("clazz must not be null");
- }
- if (stub == null) {
- throw new IllegalArgumentException("stub must not be null");
- }
- if (stub instanceof Closeable) {
- mCloseables.add((Closeable)stub);
- }
- return setProtocolBinder(clazz.getName(), stub.asBinder());
- }
-
- /**
- * Sets the binder interface of a supported route protocol by name.
- * The protocol must be one of those that was indicated as being supported
- * by the route.
- * <p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
- * for more information.
- * </p>
- */
- public @NonNull Builder setProtocolBinder(@NonNull String name,
- @NonNull IBinder binder) {
- if (TextUtils.isEmpty(name)) {
- throw new IllegalArgumentException("name must not be null or empty");
- }
- if (binder == null) {
- throw new IllegalArgumentException("binder must not be null");
- }
- int index = mRoute.getProtocols().indexOf(name);
- if (index < 0) {
- throw new IllegalArgumentException("name must specify a protocol that "
- + "the route actually declared that it supports: "
- + "name=" + name + ", protocols=" + mRoute.getProtocols());
- }
- mProtocols[index] = binder;
- return this;
- }
-
- /**
- * Sets optional extra media route service or protocol specific information about
- * the connection. Use the service or protocol name as the prefix for
- * any extras to avoid namespace collisions.
- */
- public @NonNull Builder setExtras(@Nullable Bundle extras) {
- mExtras = extras;
- return this;
- }
-
- /**
- * Builds the {@link ConnectionInfo} object.
- */
- public @NonNull ConnectionInfo build() {
- return new ConnectionInfo(mRoute,
- mAudioAttributes, mPresentationDisplay,
- mVolumeProvider, mProtocols, mExtras, mCloseables);
- }
- }
- }
-
- /**
- * Describes one particular way of routing media content to a destination
- * according to the capabilities specified by a media route selector on behalf
- * of an application.
- */
- public static final class RouteInfo {
- private final String mId;
- private final DestinationInfo mDestination;
- private final MediaRouteSelector mSelector;
- private final int mFeatures;
- private final ArrayList<String> mProtocols;
- private final Bundle mExtras;
-
- RouteInfo(String id, DestinationInfo destination, MediaRouteSelector selector,
- int features, ArrayList<String> protocols, Bundle extras) {
- mId = id;
- mDestination = destination;
- mSelector = selector;
- mFeatures = features;
- mProtocols = protocols;
- mExtras = extras;
- }
-
- /**
- * Gets the route's stable identifier.
- * <p>
- * The id is intended to uniquely identify the route among all routes that
- * are offered by a particular destination in such a way that the client can
- * refer to it at a later time.
- * </p>
- */
- public @NonNull String getId() {
- return mId;
- }
-
- /**
- * Gets the destination that is offering this route.
- */
- public @NonNull DestinationInfo getDestination() {
- return mDestination;
- }
-
- /**
- * Gets the media route selector provided by the client for which this
- * route was created.
- * <p>
- * It is implied that this route supports all of the required capabilities
- * that were expressed in the selector.
- * </p>
- */
- public @NonNull MediaRouteSelector getSelector() {
- return mSelector;
- }
-
- /**
- * Gets the set of supported route features.
- */
- public @RouteFeatures int getFeatures() {
- return mFeatures;
- }
-
- /**
- * Gets the list of supported route protocols.
- * <p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
- * for more information.
- * </p>
- */
- public @NonNull List<String> getProtocols() {
- return mProtocols;
- }
-
- /**
- * Gets optional extra information about the route, or null if none.
- */
- public @Nullable Bundle getExtras() {
- return mExtras;
- }
-
- @Override
- public @NonNull String toString() {
- return "RouteInfo{ id=" + mId + ", destination=" + mDestination
- + ", features=0x" + Integer.toHexString(mFeatures)
- + ", selector=" + mSelector + ", protocols=" + mProtocols
- + ", extras=" + mExtras + " }";
- }
-
- /**
- * Builds {@link RouteInfo} objects.
- */
- public static final class Builder {
- private final DestinationInfo mDestination;
- private final String mId;
- private final MediaRouteSelector mSelector;
- private int mFeatures;
- private final ArrayList<String> mProtocols = new ArrayList<String>();
- private Bundle mExtras;
-
- /**
- * Creates a builder for route information.
- *
- * @param id The route's stable identifier.
- * @param destination The destination of this route.
- * @param selector The media route selector provided by the client for which
- * this route was created. This must be one of the selectors that was
- * included in the discovery request.
- */
- public Builder(@NonNull String id, @NonNull DestinationInfo destination,
- @NonNull MediaRouteSelector selector) {
- if (TextUtils.isEmpty(id)) {
- throw new IllegalArgumentException("id must not be null or empty");
- }
- if (destination == null) {
- throw new IllegalArgumentException("destination must not be null");
- }
- if (selector == null) {
- throw new IllegalArgumentException("selector must not be null");
- }
- mDestination = destination;
- mId = id;
- mSelector = selector;
- }
-
- /**
- * Sets the set of supported route features.
- */
- public @NonNull Builder setFeatures(@RouteFeatures int features) {
- mFeatures = features;
- return this;
- }
-
- /**
- * Adds a supported route protocol using its fully qualified class name.
- * <p>
- * If the protocol was not requested by the client in its selector
- * then it will be silently discarded.
- * </p>
- */
- public @NonNull <T extends IInterface> Builder addProtocol(@NonNull Class<T> clazz) {
- if (clazz == null) {
- throw new IllegalArgumentException("clazz must not be null");
- }
- return addProtocol(clazz.getName());
- }
-
- /**
- * Adds a supported route protocol by name.
- * <p>
- * If the protocol was not requested by the client in its selector
- * then it will be silently discarded.
- * </p>
- */
- public @NonNull Builder addProtocol(@NonNull String name) {
- if (TextUtils.isEmpty(name)) {
- throw new IllegalArgumentException("name must not be null");
- }
- if (mSelector.containsProtocol(name)) {
- mProtocols.add(name);
- }
- return this;
- }
-
- /**
- * Sets optional extra information about the route, or null if none.
- */
- public @NonNull Builder setExtras(@Nullable Bundle extras) {
- mExtras = extras;
- return this;
- }
-
- /**
- * Builds the {@link RouteInfo} object.
- * <p>
- * Ensures that all required protocols have been supplied.
- * </p>
- */
- public @NonNull RouteInfo build() {
- int missingFeatures = mSelector.getRequiredFeatures() & ~mFeatures;
- if (missingFeatures != 0) {
- throw new IllegalStateException("The media route selector "
- + "specified required features which this route does "
- + "not appear to support so it should not have been published: "
- + "missing 0x" + Integer.toHexString(missingFeatures));
- }
- for (String protocol : mSelector.getRequiredProtocols()) {
- if (!mProtocols.contains(protocol)) {
- throw new IllegalStateException("The media route selector "
- + "specified required protocols which this route "
- + "does not appear to support so it should not have "
- + "been published: missing " + protocol);
- }
- }
- return new RouteInfo(mId, mDestination, mSelector,
- mFeatures, mProtocols, mExtras);
- }
- }
- }
-
- /**
- * Describes a destination for media content such as a device,
- * an individual port on a device, or a group of devices.
- */
- public static final class DestinationInfo {
- private final String mId;
- private final ServiceMetadata mService;
- private final CharSequence mName;
- private final CharSequence mDescription;
- private final int mIconResourceId;
- private final Bundle mExtras;
-
- DestinationInfo(String id, ServiceMetadata service,
- CharSequence name, CharSequence description,
- int iconResourceId, Bundle extras) {
- mId = id;
- mService = service;
- mName = name;
- mDescription = description;
- mIconResourceId = iconResourceId;
- mExtras = extras;
- }
-
- /**
- * Gets the destination's stable identifier.
- * <p>
- * The id is intended to uniquely identify the destination among all destinations
- * provided by the media route service in such a way that the client can
- * refer to it at a later time. Ideally, the id should be resilient to
- * user-initiated actions such as changes to the name or description
- * of the destination.
- * </p>
- */
- public @NonNull String getId() {
- return mId;
- }
-
- /**
- * Gets metadata about the service that is providing access to this destination.
- */
- public @NonNull ServiceMetadata getServiceMetadata() {
- return mService;
- }
-
- /**
- * Gets the destination's name for display to the user.
- */
- public @NonNull CharSequence getName() {
- return mName;
- }
-
- /**
- * Gets the destination's description for display to the user, or null if none.
- */
- public @Nullable CharSequence getDescription() {
- return mDescription;
- }
-
- /**
- * Gets an icon resource from the service's package which is used
- * to identify the destination, or -1 if none.
- */
- public @DrawableRes int getIconResourceId() {
- return mIconResourceId;
- }
-
- /**
- * Loads the icon drawable, or null if none.
- */
- public @Nullable Drawable loadIcon(@NonNull PackageManager pm) {
- return mIconResourceId >= 0 ? mService.getDrawable(pm, mIconResourceId) : null;
- }
-
- /**
- * Gets optional extra information about the destination, or null if none.
- */
- public @Nullable Bundle getExtras() {
- return mExtras;
- }
-
- @Override
- public @NonNull String toString() {
- return "DestinationInfo{ id=" + mId + ", service=" + mService + ", name=" + mName
- + ", description=" + mDescription + ", iconResourceId=" + mIconResourceId
- + ", extras=" + mExtras + " }";
- }
-
- /**
- * Builds {@link DestinationInfo} objects.
- */
- public static final class Builder {
- private final String mId;
- private final ServiceMetadata mService;
- private final CharSequence mName;
- private CharSequence mDescription;
- private int mIconResourceId = -1;
- private Bundle mExtras;
-
- /**
- * Creates a builder for destination information.
- *
- * @param id The destination's stable identifier.
- * @param service Metatada about the service that is providing access to
- * this destination.
- * @param name The destination's name for display to the user.
- */
- public Builder(@NonNull String id, @NonNull ServiceMetadata service,
- @NonNull CharSequence name) {
- if (TextUtils.isEmpty(id)) {
- throw new IllegalArgumentException("id must not be null or empty");
- }
- if (service == null) {
- throw new IllegalArgumentException("service must not be null");
- }
- if (TextUtils.isEmpty(name)) {
- throw new IllegalArgumentException("name must not be null or empty");
- }
- mId = id;
- mService = service;
- mName = name;
- }
-
- /**
- * Sets the destination's description for display to the user, or null if none.
- */
- public @NonNull Builder setDescription(@Nullable CharSequence description) {
- mDescription = description;
- return this;
- }
-
- /**
- * Sets an icon resource from this package used to identify the destination,
- * or -1 if none.
- */
- public @NonNull Builder setIconResourceId(@DrawableRes int resid) {
- mIconResourceId = resid;
- return this;
- }
-
- /**
- * Gets optional extra information about the destination, or null if none.
- */
- public @NonNull Builder setExtras(@Nullable Bundle extras) {
- mExtras = extras;
- return this;
- }
-
- /**
- * Builds the {@link DestinationInfo} object.
- */
- public @NonNull DestinationInfo build() {
- return new DestinationInfo(mId, mService, mName, mDescription,
- mIconResourceId, mExtras);
- }
- }
- }
-
- /**
- * Describes metadata about a {@link MediaRouteService} which is providing
- * access to certain kinds of destinations.
- */
- public static final class ServiceMetadata {
- private final ServiceInfo mService;
- private CharSequence mLabel;
- private Drawable mIcon;
-
- ServiceMetadata(Service service) throws NameNotFoundException {
- mService = service.getPackageManager().getServiceInfo(
- new ComponentName(service, service.getClass()),
- PackageManager.GET_META_DATA);
- }
-
- ServiceMetadata(ServiceInfo service) {
- mService = service;
- }
-
- /**
- * Gets the service's component information including it name, label and icon.
- */
- public @NonNull ServiceInfo getService() {
- return mService;
- }
-
- /**
- * Gets the service's component name.
- */
- public @NonNull ComponentName getComponentName() {
- return new ComponentName(mService.packageName, mService.name);
- }
-
- /**
- * Gets the service's package name.
- */
- public @NonNull String getPackageName() {
- return mService.packageName;
- }
-
- /**
- * Gets the service's name for display to the user, or null if none.
- */
- public @NonNull CharSequence getLabel(@NonNull PackageManager pm) {
- if (mLabel == null) {
- mLabel = mService.loadLabel(pm);
- }
- return mLabel;
- }
-
- /**
- * Gets the icon drawable, or null if none.
- */
- public @Nullable Drawable getIcon(@NonNull PackageManager pm) {
- if (mIcon == null) {
- mIcon = mService.loadIcon(pm);
- }
- return mIcon;
- }
-
- // TODO: add service metadata
-
- Drawable getDrawable(PackageManager pm, int resid) {
- return pm.getDrawable(getPackageName(), resid, mService.applicationInfo);
- }
-
- @Override
- public @NonNull String toString() {
- return "ServiceInfo{ service=" + getComponentName().toShortString() + " }";
- }
- }
-
- /**
- * Describes a request to discover routes on behalf of an application.
- */
- public static final class DiscoveryRequest {
- private final ArrayList<MediaRouteSelector> mSelectors =
- new ArrayList<MediaRouteSelector>();
- private int mFlags;
-
- DiscoveryRequest(@NonNull List<MediaRouteSelector> selectors) {
- setSelectors(selectors);
- }
-
- /**
- * Sets the list of media route selectors to consider during discovery.
- */
- public void setSelectors(@NonNull List<MediaRouteSelector> selectors) {
- if (selectors == null) {
- throw new IllegalArgumentException("selectors");
- }
- mSelectors.clear();
- mSelectors.addAll(selectors);
- }
-
- /**
- * Gets the list of media route selectors to consider during discovery.
- */
- public @NonNull List<MediaRouteSelector> getSelectors() {
- return mSelectors;
- }
-
- /**
- * Gets discovery flags, such as {@link MediaRouter#DISCOVERY_FLAG_BACKGROUND}.
- */
- public @DiscoveryFlags int getFlags() {
- return mFlags;
- }
-
- /**
- * Sets discovery flags, such as {@link MediaRouter#DISCOVERY_FLAG_BACKGROUND}.
- */
- public void setFlags(@DiscoveryFlags int flags) {
- mFlags = flags;
- }
-
- @Override
- public @NonNull String toString() {
- return "DiscoveryRequest{ selectors=" + mSelectors
- + ", flags=0x" + Integer.toHexString(mFlags)
- + " }";
- }
- }
-
- /**
- * Describes a request to connect to a previously discovered route on
- * behalf of an application.
- */
- public static final class ConnectionRequest {
- private RouteInfo mRoute;
- private int mFlags;
- private Bundle mExtras;
-
- ConnectionRequest(@NonNull RouteInfo route) {
- setRoute(route);
- }
-
- /**
- * Gets the route to which to connect.
- */
- public @NonNull RouteInfo getRoute() {
- return mRoute;
- }
-
- /**
- * Sets the route to which to connect.
- */
- public void setRoute(@NonNull RouteInfo route) {
- if (route == null) {
- throw new IllegalArgumentException("route must not be null");
- }
- mRoute = route;
- }
-
- /**
- * Gets connection flags, such as {@link MediaRouter#CONNECTION_FLAG_BARGE}.
- */
- public @ConnectionFlags int getFlags() {
- return mFlags;
- }
-
- /**
- * Sets connection flags, such as {@link MediaRouter#CONNECTION_FLAG_BARGE}.
- */
- public void setFlags(@ConnectionFlags int flags) {
- mFlags = flags;
- }
-
- /**
- * Gets optional extras supplied by the application as part of the call to
- * connect, or null if none. The media route service may use this
- * information to configure the route during connection.
- */
- public @Nullable Bundle getExtras() {
- return mExtras;
- }
-
- /**
- * Sets optional extras supplied by the application as part of the call to
- * connect, or null if none. The media route service may use this
- * information to configure the route during connection.
- */
- public void setExtras(@Nullable Bundle extras) {
- mExtras = extras;
- }
-
- @Override
- public @NonNull String toString() {
- return "ConnectionRequest{ route=" + mRoute
- + ", flags=0x" + Integer.toHexString(mFlags)
- + ", extras=" + mExtras + " }";
- }
- }
-
- /**
- * Callback interface to specify policy for route discovery, filtering,
- * and connection establishment as well as observe media router state changes.
- */
- public static abstract class RoutingCallback extends StateCallback {
- /**
- * Called to prepare a discovery request object to specify the desired
- * media route selectors when the media router has been asked to start discovery.
- * <p>
- * By default, the discovery request contains all of the selectors which
- * have been added to the media router. Subclasses may override the list of
- * selectors by modifying the discovery request object before returning.
- * </p>
- *
- * @param request The discovery request object which may be modified by
- * this method to alter how discovery will be performed.
- * @param selectors The immutable list of media route selectors which were
- * added to the media router.
- * @return True to allow discovery to proceed or false to abort it.
- * By default, this methods returns true.
- */
- public boolean onPrepareDiscoveryRequest(@NonNull DiscoveryRequest request,
- @NonNull List<MediaRouteSelector> selectors) {
- return true;
- }
-
- /**
- * Called to prepare a connection request object to specify the desired
- * route and connection parameters when the media router has been asked to
- * connect to a particular destination.
- * <p>
- * By default, the connection request specifies the first available route
- * to the destination. Subclasses may override the route and destination
- * or set additional connection parameters by modifying the connection request
- * object before returning.
- * </p>
- *
- * @param request The connection request object which may be modified by
- * this method to alter how the connection will be established.
- * @param destination The destination to which the media router was asked
- * to connect.
- * @param routes The list of routes that belong to that destination sorted
- * in the same order as their matching media route selectors which were
- * used during discovery.
- * @return True to allow the connection to proceed or false to abort it.
- * By default, this methods returns true.
- */
- public boolean onPrepareConnectionRequest(
- @NonNull ConnectionRequest request,
- @NonNull DestinationInfo destination, @NonNull List<RouteInfo> routes) {
- return true;
- }
- }
-
- /**
- * Callback class to receive events from a {@link MediaRouter.Delegate}.
- */
- public static abstract class StateCallback {
- /**
- * Called when the media router has been released.
- */
- public void onReleased() { }
-
- /**
- * Called when the discovery state has changed.
- *
- * @param state The new discovery state: one of
- * {@link #DISCOVERY_STATE_STOPPED} or {@link #DISCOVERY_STATE_STARTED}.
- */
- public void onDiscoveryStateChanged(@DiscoveryState int state) { }
-
- /**
- * Called when the connection state has changed.
- *
- * @param state The new connection state: one of
- * {@link #CONNECTION_STATE_DISCONNECTED}, {@link #CONNECTION_STATE_CONNECTING}
- * or {@link #CONNECTION_STATE_CONNECTED}.
- */
- public void onConnectionStateChanged(@ConnectionState int state) { }
-
- /**
- * Called when the selected destination has changed.
- *
- * @param destination The new selected destination, or null if none.
- */
- public void onSelectedDestinationChanged(@Nullable DestinationInfo destination) { }
-
- /**
- * Called when route discovery has started.
- */
- public void onDiscoveryStarted() { }
-
- /**
- * Called when route discovery has stopped normally.
- * <p>
- * Abnormal termination is reported via {@link #onDiscoveryFailed}.
- * </p>
- */
- public void onDiscoveryStopped() { }
-
- /**
- * Called when discovery has failed in a non-recoverable manner.
- *
- * @param error The error code: one of
- * {@link MediaRouter#DISCOVERY_ERROR_UNKNOWN},
- * {@link MediaRouter#DISCOVERY_ERROR_ABORTED},
- * or {@link MediaRouter#DISCOVERY_ERROR_NO_CONNECTIVITY}.
- * @param message The localized error message, or null if none. This message
- * may be shown to the user.
- * @param extras Additional information about the error which a client
- * may use, or null if none.
- */
- public void onDiscoveryFailed(@DiscoveryError int error, @Nullable CharSequence message,
- @Nullable Bundle extras) { }
-
- /**
- * Called when a new destination is found or has changed during discovery.
- * <p>
- * Certain destinations may be omitted because they have been filtered
- * out by the media router's routing callback.
- * </p>
- *
- * @param destination The destination that was found.
- */
- public void onDestinationFound(@NonNull DestinationInfo destination) { }
-
- /**
- * Called when a destination is no longer reachable or is no longer
- * offering any routes that satisfy the discovery request.
- *
- * @param destination The destination that went away.
- */
- public void onDestinationLost(@NonNull DestinationInfo destination) { }
-
- /**
- * Called when a connection attempt begins.
- */
- public void onConnecting() { }
-
- /**
- * Called when the connection succeeds.
- */
- public void onConnected() { }
-
- /**
- * Called when the connection is terminated normally.
- * <p>
- * Abnormal termination is reported via {@link #onConnectionFailed}.
- * </p>
- */
- public void onDisconnected() { }
-
- /**
- * Called when a connection attempt or connection in
- * progress has failed in a non-recoverable manner.
- *
- * @param error The error code: one of
- * {@link MediaRouter#CONNECTION_ERROR_ABORTED},
- * {@link MediaRouter#CONNECTION_ERROR_UNAUTHORIZED},
- * {@link MediaRouter#CONNECTION_ERROR_UNREACHABLE},
- * {@link MediaRouter#CONNECTION_ERROR_BUSY},
- * {@link MediaRouter#CONNECTION_ERROR_TIMEOUT},
- * {@link MediaRouter#CONNECTION_ERROR_BROKEN},
- * or {@link MediaRouter#CONNECTION_ERROR_BARGED}.
- * @param message The localized error message, or null if none. This message
- * may be shown to the user.
- * @param extras Additional information about the error which a client
- * may use, or null if none.
- */
- public void onConnectionFailed(@ConnectionError int error,
- @Nullable CharSequence message, @Nullable Bundle extras) { }
- }
-}
diff --git a/media/java/android/media/routing/ParcelableConnectionInfo.aidl b/media/java/android/media/routing/ParcelableConnectionInfo.aidl
deleted file mode 100644
index 4a9ec94..0000000
--- a/media/java/android/media/routing/ParcelableConnectionInfo.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 2014, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.media.routing;
-
-parcelable ParcelableConnectionInfo;
diff --git a/media/java/android/media/routing/ParcelableConnectionInfo.java b/media/java/android/media/routing/ParcelableConnectionInfo.java
deleted file mode 100644
index 45cfe9f..0000000
--- a/media/java/android/media/routing/ParcelableConnectionInfo.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.media.routing;
-
-import android.media.AudioAttributes;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Internal parcelable representation of a media route connection.
- */
-class ParcelableConnectionInfo implements Parcelable {
- public AudioAttributes audioAttributes;
- public int presentationDisplayId = -1;
- // todo: volume
- public IBinder[] protocolBinders;
- public Bundle extras;
-
- public static final Parcelable.Creator<ParcelableConnectionInfo> CREATOR =
- new Parcelable.Creator<ParcelableConnectionInfo>() {
- @Override
- public ParcelableConnectionInfo createFromParcel(Parcel source) {
- ParcelableConnectionInfo info = new ParcelableConnectionInfo();
- if (source.readInt() != 0) {
- info.audioAttributes = AudioAttributes.CREATOR.createFromParcel(source);
- }
- info.presentationDisplayId = source.readInt();
- info.protocolBinders = source.createBinderArray();
- info.extras = source.readBundle();
- return info;
- }
-
- @Override
- public ParcelableConnectionInfo[] newArray(int size) {
- return new ParcelableConnectionInfo[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- if (audioAttributes != null) {
- dest.writeInt(1);
- audioAttributes.writeToParcel(dest, flags);
- } else {
- dest.writeInt(0);
- }
- dest.writeInt(presentationDisplayId);
- dest.writeBinderArray(protocolBinders);
- dest.writeBundle(extras);
- }
-}
diff --git a/media/java/android/media/routing/ParcelableDestinationInfo.aidl b/media/java/android/media/routing/ParcelableDestinationInfo.aidl
deleted file mode 100644
index bf1c198..0000000
--- a/media/java/android/media/routing/ParcelableDestinationInfo.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 2014, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.media.routing;
-
-parcelable ParcelableDestinationInfo;
diff --git a/media/java/android/media/routing/ParcelableDestinationInfo.java b/media/java/android/media/routing/ParcelableDestinationInfo.java
deleted file mode 100644
index eca5eec..0000000
--- a/media/java/android/media/routing/ParcelableDestinationInfo.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.media.routing;
-
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-/**
- * Internal parcelable representation of a media destination.
- */
-class ParcelableDestinationInfo implements Parcelable {
- public String id;
- public CharSequence name;
- public CharSequence description;
- public int iconResourceId;
- public Bundle extras;
-
- public static final Parcelable.Creator<ParcelableDestinationInfo> CREATOR =
- new Parcelable.Creator<ParcelableDestinationInfo>() {
- @Override
- public ParcelableDestinationInfo createFromParcel(Parcel source) {
- ParcelableDestinationInfo info = new ParcelableDestinationInfo();
- info.id = source.readString();
- info.name = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
- info.description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
- info.iconResourceId = source.readInt();
- info.extras = source.readBundle();
- return info;
- }
-
- @Override
- public ParcelableDestinationInfo[] newArray(int size) {
- return new ParcelableDestinationInfo[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(id);
- TextUtils.writeToParcel(name, dest, flags);
- TextUtils.writeToParcel(description, dest, flags);
- dest.writeInt(iconResourceId);
- dest.writeBundle(extras);
- }
-}
diff --git a/media/java/android/media/routing/ParcelableRouteInfo.aidl b/media/java/android/media/routing/ParcelableRouteInfo.aidl
deleted file mode 100644
index 126afaa..0000000
--- a/media/java/android/media/routing/ParcelableRouteInfo.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 2014, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.media.routing;
-
-parcelable ParcelableRouteInfo;
diff --git a/media/java/android/media/routing/ParcelableRouteInfo.java b/media/java/android/media/routing/ParcelableRouteInfo.java
deleted file mode 100644
index fb1a547..0000000
--- a/media/java/android/media/routing/ParcelableRouteInfo.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.media.routing;
-
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Internal parcelable representation of a media route.
- */
-class ParcelableRouteInfo implements Parcelable {
- public String id;
- public int selectorIndex; // index of selector within list used for discovery
- public int features;
- public String[] protocols;
- public Bundle extras;
-
- public static final Parcelable.Creator<ParcelableRouteInfo> CREATOR =
- new Parcelable.Creator<ParcelableRouteInfo>() {
- @Override
- public ParcelableRouteInfo createFromParcel(Parcel source) {
- ParcelableRouteInfo info = new ParcelableRouteInfo();
- info.id = source.readString();
- info.selectorIndex = source.readInt();
- info.features = source.readInt();
- info.protocols = source.createStringArray();
- info.extras = source.readBundle();
- return info;
- }
-
- @Override
- public ParcelableRouteInfo[] newArray(int size) {
- return new ParcelableRouteInfo[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(id);
- dest.writeInt(selectorIndex);
- dest.writeInt(features);
- dest.writeStringArray(protocols);
- dest.writeBundle(extras);
- }
-}
diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl
index af3b72e..bd0019f 100644
--- a/media/java/android/media/session/ISession.aidl
+++ b/media/java/android/media/session/ISession.aidl
@@ -19,7 +19,6 @@
import android.content.pm.ParceledListSlice;
import android.media.AudioAttributes;
import android.media.MediaMetadata;
-import android.media.routing.IMediaRouter;
import android.media.session.ISessionController;
import android.media.session.PlaybackState;
import android.media.session.MediaSession;
@@ -35,7 +34,6 @@
ISessionController getController();
void setFlags(int flags);
void setActive(boolean active);
- void setMediaRouter(in IMediaRouter router);
void setMediaButtonReceiver(in PendingIntent mbr);
void setLaunchPendingIntent(in PendingIntent pi);
void destroy();
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index 5764bd1..6b80477 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -20,8 +20,6 @@
import android.content.pm.ParceledListSlice;
import android.media.MediaMetadata;
import android.media.Rating;
-import android.media.routing.IMediaRouterDelegate;
-import android.media.routing.IMediaRouterStateCallback;
import android.media.session.ISessionControllerCallback;
import android.media.session.ParcelableVolumeInfo;
import android.media.session.PlaybackState;
@@ -51,8 +49,6 @@
void adjustVolume(int direction, int flags, String packageName);
void setVolumeTo(int value, int flags, String packageName);
- IMediaRouterDelegate createMediaRouterDelegate(IMediaRouterStateCallback callback);
-
// These commands are for the TransportControls
void play();
void playUri(in Uri uri, in Bundle extras);
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 074e5ad..2ec0293 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -26,7 +26,6 @@
import android.media.MediaMetadata;
import android.media.Rating;
import android.media.VolumeProvider;
-import android.media.routing.MediaRouter;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -119,17 +118,6 @@
}
/**
- * Creates a media router delegate through which the destination of the media
- * router may be observed and controlled.
- *
- * @return The media router delegate, or null if the media session does
- * not support media routing.
- */
- public @Nullable MediaRouter.Delegate createMediaRouterDelegate() {
- return new MediaRouter.Delegate();
- }
-
- /**
* Send the specified media button event to the session. Only media keys can
* be sent by this method, other keys will be ignored.
*
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 2cd161c..de725fc 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -28,7 +28,6 @@
import android.media.MediaMetadata;
import android.media.Rating;
import android.media.VolumeProvider;
-import android.media.routing.MediaRouter;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -225,23 +224,6 @@
}
/**
- * Associates a {@link MediaRouter} with this session to control the destination
- * of media content.
- * <p>
- * A media router may only be associated with at most one session at a time.
- * </p>
- *
- * @param router The media router, or null to remove the current association.
- */
- public void setMediaRouter(@Nullable MediaRouter router) {
- try {
- mBinder.setMediaRouter(router != null ? router.getBinder() : null);
- } catch (RemoteException e) {
- Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e);
- }
- }
-
- /**
* Set a pending intent for your media button receiver to allow restarting
* playback after the session has been stopped. If your app is started in
* this way an {@link Intent#ACTION_MEDIA_BUTTON} intent will be sent via
diff --git a/media/java/android/media/tv/TvTrackInfo.java b/media/java/android/media/tv/TvTrackInfo.java
index 6ddb2a2..e0aacd6 100644
--- a/media/java/android/media/tv/TvTrackInfo.java
+++ b/media/java/android/media/tv/TvTrackInfo.java
@@ -46,10 +46,12 @@
private final int mAudioSampleRate;
private final int mVideoWidth;
private final int mVideoHeight;
+ private final float mVideoFrameRate;
private final Bundle mExtra;
private TvTrackInfo(int type, String id, String language, int audioChannelCount,
- int audioSampleRate, int videoWidth, int videoHeight, Bundle extra) {
+ int audioSampleRate, int videoWidth, int videoHeight, float videoFrameRate,
+ Bundle extra) {
mType = type;
mId = id;
mLanguage = language;
@@ -57,6 +59,7 @@
mAudioSampleRate = audioSampleRate;
mVideoWidth = videoWidth;
mVideoHeight = videoHeight;
+ mVideoFrameRate = videoFrameRate;
mExtra = extra;
}
@@ -68,6 +71,7 @@
mAudioSampleRate = in.readInt();
mVideoWidth = in.readInt();
mVideoHeight = in.readInt();
+ mVideoFrameRate = in.readFloat();
mExtra = in.readBundle();
}
@@ -137,6 +141,17 @@
}
/**
+ * Returns the frame rate of the video, in the unit of fps (frames per second). Valid only for
+ * {@link #TYPE_VIDEO} tracks.
+ */
+ public final float getVideoFrameRate() {
+ if (mType != TYPE_VIDEO) {
+ throw new IllegalStateException("Not a video track");
+ }
+ return mVideoFrameRate;
+ }
+
+ /**
* Returns the extra information about the current track.
*/
public final Bundle getExtra() {
@@ -163,6 +178,7 @@
dest.writeInt(mAudioSampleRate);
dest.writeInt(mVideoWidth);
dest.writeInt(mVideoHeight);
+ dest.writeFloat(mVideoFrameRate);
dest.writeBundle(mExtra);
}
@@ -190,6 +206,7 @@
private int mAudioSampleRate;
private int mVideoWidth;
private int mVideoHeight;
+ private float mVideoFrameRate;
private Bundle mExtra;
/**
@@ -279,6 +296,20 @@
}
/**
+ * Sets the frame rate of the video, in the unit fps (frames per rate). Valid only for
+ * {@link #TYPE_VIDEO} tracks.
+ *
+ * @param videoFrameRate The frame rate of the video.
+ */
+ public final Builder setVideoFrameRate(float videoFrameRate) {
+ if (mType != TYPE_VIDEO) {
+ throw new IllegalStateException("Not a video track");
+ }
+ mVideoFrameRate = videoFrameRate;
+ return this;
+ }
+
+ /**
* Sets the extra information about the current track.
*
* @param extra The extra information.
@@ -295,7 +326,7 @@
*/
public TvTrackInfo build() {
return new TvTrackInfo(mType, mId, mLanguage, mAudioChannelCount, mAudioSampleRate,
- mVideoWidth, mVideoHeight, mExtra);
+ mVideoWidth, mVideoHeight, mVideoFrameRate, mExtra);
}
}
}
\ No newline at end of file
diff --git a/packages/PrintSpooler/res/values/themes.xml b/packages/PrintSpooler/res/values/themes.xml
index db319e9..0870229 100644
--- a/packages/PrintSpooler/res/values/themes.xml
+++ b/packages/PrintSpooler/res/values/themes.xml
@@ -16,7 +16,10 @@
<resources>
- <style name="PrintActivity" parent="@android:style/Theme.Material.Settings">
+ <style name="PrintActivity" parent="@android:style/Theme.Material">
+ <item name="android:colorPrimary">@*android:color/material_blue_grey_900</item>
+ <item name="android:colorPrimaryDark">@*android:color/material_blue_grey_950</item>
+ <item name="android:colorAccent">@*android:color/material_deep_teal_A500</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 531ac31..6b3e871 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -37,8 +37,8 @@
/** Quick settings tile: Cast **/
public class CastTile extends QSTile<QSTile.BooleanState> {
- private static final Intent WIFI_DISPLAY_SETTINGS =
- new Intent(Settings.ACTION_WIFI_DISPLAY_SETTINGS);
+ private static final Intent CAST_SETTINGS =
+ new Intent(Settings.ACTION_CAST_SETTINGS);
private final CastController mController;
private final CastDetailAdapter mDetailAdapter;
@@ -144,7 +144,7 @@
@Override
public Intent getSettingsIntent() {
- return WIFI_DISPLAY_SETTINGS;
+ return CAST_SETTINGS;
}
@Override
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 2af3b2f..8bbc404 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -356,7 +356,7 @@
break;
case Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED:
tv().setAutoWakeup(enabled);
- setOption(OPTION_CEC_AUTO_WAKEUP, toInt(enabled));
+ setCecOption(OPTION_CEC_AUTO_WAKEUP, toInt(enabled));
break;
case Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED:
tv().setAutoDeviceOff(enabled);
@@ -495,6 +495,10 @@
}
}
+ List<HdmiPortInfo> getPortInfo() {
+ return mPortInfo;
+ }
+
/**
* Returns HDMI port information for the given port id.
*
@@ -1121,7 +1125,7 @@
@Override
public List<HdmiPortInfo> getPortInfo() {
enforceAccessPermission();
- return mPortInfo;
+ return HdmiControlService.this.getPortInfo();
}
@Override
@@ -1694,11 +1698,17 @@
}
private void disableDevices(PendingActionClearedCallback callback) {
- for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) {
- device.disableDevice(mStandbyMessageReceived, callback);
+ if (mCecController != null) {
+ for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) {
+ device.disableDevice(mStandbyMessageReceived, callback);
+ }
+ if (isTvDevice()) {
+ unregisterSettingsObserver();
+ }
}
- if (isTvDevice()) {
- unregisterSettingsObserver();
+
+ if (mMhlController != null) {
+ mMhlController.clearAllLocalDevices();
}
}
@@ -1770,7 +1780,7 @@
}
@ServiceThreadOnly
- void setOption(int key, int value) {
+ void setCecOption(int key, int value) {
assertRunOnServiceThread();
mCecController.setOption(key, value);
}
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index f820a3c..84027e2 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -26,9 +26,6 @@
import android.media.MediaMetadata;
import android.media.Rating;
import android.media.VolumeProvider;
-import android.media.routing.IMediaRouter;
-import android.media.routing.IMediaRouterDelegate;
-import android.media.routing.IMediaRouterStateCallback;
import android.media.session.ISession;
import android.media.session.ISessionCallback;
import android.media.session.ISessionController;
@@ -96,7 +93,6 @@
new ArrayList<ISessionControllerCallback>();
private long mFlags;
- private IMediaRouter mMediaRouter;
private PendingIntent mMediaButtonReceiver;
private PendingIntent mLaunchIntent;
@@ -692,12 +688,6 @@
}
@Override
- public void setMediaRouter(IMediaRouter router) {
- mMediaRouter = router;
- mHandler.post(MessageHandler.MSG_UPDATE_SESSION_STATE);
- }
-
- @Override
public void setMediaButtonReceiver(PendingIntent pi) {
mMediaButtonReceiver = pi;
}
@@ -1147,13 +1137,6 @@
public boolean isTransportControlEnabled() {
return MediaSessionRecord.this.isTransportControlEnabled();
}
-
- @Override
- public IMediaRouterDelegate createMediaRouterDelegate(
- IMediaRouterStateCallback callback) {
- // todo
- return null;
- }
}
private class MessageHandler extends Handler {
diff --git a/tests/OneMedia/Android.mk b/tests/OneMedia/Android.mk
index 4feac68..4d39728 100644
--- a/tests/OneMedia/Android.mk
+++ b/tests/OneMedia/Android.mk
@@ -9,9 +9,6 @@
LOCAL_PACKAGE_NAME := OneMedia
LOCAL_CERTIFICATE := platform
-LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-media-protocols
-
LOCAL_PROGUARD_ENABLED := disabled
include $(BUILD_PACKAGE)
diff --git a/tests/OneMedia/AndroidManifest.xml b/tests/OneMedia/AndroidManifest.xml
index 95072a4..beafeb4 100644
--- a/tests/OneMedia/AndroidManifest.xml
+++ b/tests/OneMedia/AndroidManifest.xml
@@ -25,15 +25,6 @@
android:name="com.android.onemedia.OnePlayerService"
android:exported="true"
android:process="com.android.onemedia.service" />
- <service
- android:name=".provider.OneMediaRouteProvider"
- android:permission="android.permission.BIND_MEDIA_ROUTE_SERVICE"
- android:exported="true"
- android:process="com.android.onemedia.provider">
- <intent-filter>
- <action android:name="android.media.routing.MediaRouteService" />
- </intent-filter>
- </service>
</application>
</manifest>
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
index 9afcf24..8b7c883 100644
--- a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
@@ -19,24 +19,16 @@
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.MediaMetadata;
-import android.media.routing.MediaRouteSelector;
-import android.media.routing.MediaRouter;
-import android.media.routing.MediaRouter.ConnectionRequest;
-import android.media.routing.MediaRouter.DestinationInfo;
-import android.media.routing.MediaRouter.RouteInfo;
import android.media.session.MediaSession;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
import android.os.Bundle;
-import android.support.media.protocols.MediaPlayerProtocol;
-import android.support.media.protocols.MediaPlayerProtocol.MediaStatus;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.view.KeyEvent;
import com.android.onemedia.playback.LocalRenderer;
-import com.android.onemedia.playback.OneMRPRenderer;
import com.android.onemedia.playback.Renderer;
import com.android.onemedia.playback.RequestUtils;
@@ -47,7 +39,6 @@
private static final String TAG = "PlayerSession";
protected MediaSession mSession;
- protected MediaRouter mRouter;
protected Context mContext;
protected Renderer mRenderer;
protected MediaSession.Callback mCallback;
@@ -80,22 +71,11 @@
.getSystemService(Context.MEDIA_SESSION_SERVICE);
Log.d(TAG, "Creating session for package " + mContext.getBasePackageName());
- mRouter = new MediaRouter(mContext);
- mRouter.addSelector(new MediaRouteSelector.Builder()
- .addRequiredProtocol(MediaPlayerProtocol.class)
- .build());
- mRouter.addSelector(new MediaRouteSelector.Builder()
- .setRequiredFeatures(MediaRouter.ROUTE_FEATURE_LIVE_AUDIO)
- .setOptionalFeatures(MediaRouter.ROUTE_FEATURE_LIVE_VIDEO)
- .build());
- mRouter.setRoutingCallback(new RoutingCallback(), null);
-
mSession = new MediaSession(mContext, "OneMedia");
mSession.setCallback(mCallback);
mSession.setPlaybackState(mPlaybackState);
mSession.setFlags(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS
| MediaSession.FLAG_HANDLES_MEDIA_BUTTONS);
- mSession.setMediaRouter(mRouter);
mSession.setActive(true);
updateMetadata();
}
@@ -113,10 +93,6 @@
mSession.release();
mSession = null;
}
- if (mRouter != null) {
- mRouter.release();
- mRouter = null;
- }
}
public void setListener(Listener listener) {
@@ -266,63 +242,4 @@
mRenderer.onPause();
}
}
-
- private class RoutingCallback extends MediaRouter.RoutingCallback {
- @Override
- public void onConnectionStateChanged(int state) {
- if (state == MediaRouter.CONNECTION_STATE_CONNECTING) {
- if (mRenderer != null) {
- mRenderer.onStop();
- }
- mRenderer = null;
- updateState(PlaybackState.STATE_CONNECTING);
- return;
- }
-
- MediaRouter.ConnectionInfo connection = mRouter.getConnection();
- if (connection != null) {
- MediaPlayerProtocol protocol =
- connection.getProtocolObject(MediaPlayerProtocol.class);
- if (protocol != null) {
- Log.d(TAG, "Connected to route using media player protocol");
-
- protocol.setCallback(new PlayerCallback(), null);
- mRenderer = new OneMRPRenderer(protocol);
- updateState(PlaybackState.STATE_NONE);
- return;
- }
- }
-
- // Use local route
- mRenderer = new LocalRenderer(mContext, null);
- mRenderer.registerListener(mRenderListener);
- updateState(PlaybackState.STATE_NONE);
- }
- }
-
- private class PlayerCallback extends MediaPlayerProtocol.Callback {
- @Override
- public void onStatusUpdated(MediaStatus status, Bundle extras) {
- if (status != null) {
- Log.d(TAG, "Received status update: " + status.toBundle());
- switch (status.getPlayerState()) {
- case MediaStatus.PLAYER_STATE_BUFFERING:
- updateState(PlaybackState.STATE_BUFFERING);
- break;
- case MediaStatus.PLAYER_STATE_IDLE:
- updateState(PlaybackState.STATE_STOPPED);
- break;
- case MediaStatus.PLAYER_STATE_PAUSED:
- updateState(PlaybackState.STATE_PAUSED);
- break;
- case MediaStatus.PLAYER_STATE_PLAYING:
- updateState(PlaybackState.STATE_PLAYING);
- break;
- case MediaStatus.PLAYER_STATE_UNKNOWN:
- updateState(PlaybackState.STATE_NONE);
- break;
- }
- }
- }
- }
}
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/OneMRPRenderer.java b/tests/OneMedia/src/com/android/onemedia/playback/OneMRPRenderer.java
deleted file mode 100644
index 55eb92c..0000000
--- a/tests/OneMedia/src/com/android/onemedia/playback/OneMRPRenderer.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.android.onemedia.playback;
-
-import android.os.Bundle;
-import android.support.media.protocols.MediaPlayerProtocol;
-import android.support.media.protocols.MediaPlayerProtocol.MediaInfo;
-
-/**
- * Renderer for communicating with the OneMRP route
- */
-public class OneMRPRenderer extends Renderer {
- private final MediaPlayerProtocol mProtocol;
-
- public OneMRPRenderer(MediaPlayerProtocol protocol) {
- super(null, null);
- mProtocol = protocol;
- }
-
- @Override
- public void setContent(Bundle request) {
- MediaInfo mediaInfo = new MediaInfo(request.getString(RequestUtils.EXTRA_KEY_SOURCE),
- MediaInfo.STREAM_TYPE_BUFFERED, "audio/mp3");
- mProtocol.load(mediaInfo, true, 0, null);
- }
-
- @Override
- public boolean onStop() {
- mProtocol.stop(null);
- return true;
- }
-
- @Override
- public boolean onPlay() {
- mProtocol.play(null);
- return true;
- }
-
- @Override
- public boolean onPause() {
- mProtocol.pause(null);
- return true;
- }
-
- @Override
- public long getSeekPosition() {
- return -1;
- }
-}
diff --git a/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java b/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java
deleted file mode 100644
index 5845e48..0000000
--- a/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.onemedia.provider;
-
-import android.media.routing.MediaRouteSelector;
-import android.media.routing.MediaRouteService;
-import android.media.routing.MediaRouter.ConnectionInfo;
-import android.media.routing.MediaRouter.ConnectionRequest;
-import android.media.routing.MediaRouter.DestinationInfo;
-import android.media.routing.MediaRouter.DiscoveryRequest;
-import android.media.routing.MediaRouter.RouteInfo;
-import android.media.session.PlaybackState;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Process;
-import android.support.media.protocols.MediaPlayerProtocol;
-import android.support.media.protocols.MediaPlayerProtocol.MediaInfo;
-import android.support.media.protocols.MediaPlayerProtocol.MediaStatus;
-import android.os.Looper;
-import android.os.ResultReceiver;
-import android.os.SystemClock;
-import android.util.Log;
-
-import com.android.onemedia.playback.LocalRenderer;
-import com.android.onemedia.playback.Renderer;
-import com.android.onemedia.playback.RequestUtils;
-
-import java.util.ArrayList;
-
-/**
- * Test of MediaRouteProvider. Show a dummy provider with a simple interface for
- * playing music.
- */
-public class OneMediaRouteProvider extends MediaRouteService {
- private static final String TAG = "OneMRP";
- private static final boolean DEBUG = true;
-
- private static final String TEST_DESTINATION_ID = "testDestination";
- private static final String TEST_ROUTE_ID = "testRoute";
-
- private Renderer mRenderer;
- private RenderListener mRenderListener;
- private PlaybackState mPlaybackState;
- private Handler mHandler;
-
- private OneStub mStub;
-
- @Override
- public void onCreate() {
- mHandler = new Handler();
- mRenderer = new LocalRenderer(this, null);
- mRenderListener = new RenderListener();
- PlaybackState.Builder bob = new PlaybackState.Builder();
- bob.setActions(PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_PLAY);
- mPlaybackState = bob.build();
-
- mRenderer.registerListener(mRenderListener);
- }
-
- @Override
- public ClientSession onCreateClientSession(ClientInfo client) {
- if (client.getUid() != Process.myUid()) {
- // for testing purposes, only allow connections from this application
- // since this provider is not fully featured
- return null;
- }
- return new OneSession(client);
- }
-
- private final class OneSession extends ClientSession {
- private final ClientInfo mClient;
-
- public OneSession(ClientInfo client) {
- mClient = client;
- }
-
- @Override
- public boolean onStartDiscovery(DiscoveryRequest req, DiscoveryCallback callback) {
- for (MediaRouteSelector selector : req.getSelectors()) {
- if (isMatch(selector)) {
- DestinationInfo destination = new DestinationInfo.Builder(
- TEST_DESTINATION_ID, getServiceMetadata(), "OneMedia")
- .setDescription("Test route from OneMedia app.")
- .build();
- ArrayList<RouteInfo> routes = new ArrayList<RouteInfo>();
- routes.add(new RouteInfo.Builder(
- TEST_ROUTE_ID, destination, selector).build());
- callback.onDestinationFound(destination, routes);
- return true;
- }
- }
- return false;
- }
-
- @Override
- public void onStopDiscovery() {
- }
-
- @Override
- public boolean onConnect(ConnectionRequest req, ConnectionCallback callback) {
- if (req.getRoute().getId().equals(TEST_ROUTE_ID)) {
- mStub = new OneStub();
- ConnectionInfo connection = new ConnectionInfo.Builder(req.getRoute())
- .setProtocolStub(MediaPlayerProtocol.class, mStub)
- .build();
- callback.onConnected(connection);
- return true;
- }
- return false;
- }
-
- @Override
- public void onDisconnect() {
- mStub = null;
- }
-
- private boolean isMatch(MediaRouteSelector selector) {
- if (!selector.containsProtocol(MediaPlayerProtocol.class)) {
- return false;
- }
- for (String protocol : selector.getRequiredProtocols()) {
- if (!protocol.equals(MediaPlayerProtocol.class.getName())) {
- return false;
- }
- }
- return true;
- }
- }
-
- private final class OneStub extends MediaPlayerProtocol.Stub {
- MediaInfo mMediaInfo;
-
- public OneStub() {
- super(mHandler);
- }
-
- @Override
- public void onLoad(MediaInfo mediaInfo, boolean autoplay, long playPosition,
- Bundle extras) {
- if (DEBUG) {
- Log.d(TAG, "Attempting to play " + mediaInfo.getContentId());
- }
- // look up the route and send a play command to it
- mMediaInfo = mediaInfo;
- Bundle bundle = new Bundle();
- bundle.putString(RequestUtils.EXTRA_KEY_SOURCE, mediaInfo.getContentId());
- mRenderer.setContent(bundle);
- }
-
- @Override
- public void onPlay(Bundle extras) {
- mRenderer.onPlay();
- }
-
- @Override
- public void onPause(Bundle extras) {
- mRenderer.onPause();
- }
- }
-
- private class RenderListener implements Renderer.Listener {
-
- @Override
- public void onError(int type, int extra, Bundle extras, Throwable error) {
- Log.d(TAG, "Sending onError with type " + type + " and extra " + extra);
- sendStatusUpdate(PlaybackState.STATE_ERROR);
- }
-
- @Override
- public void onStateChanged(int newState) {
- long position = -1;
- if (mRenderer != null) {
- position = mRenderer.getSeekPosition();
- }
- int pbState;
- float rate = 0;
- String errorMsg = null;
- switch (newState) {
- case Renderer.STATE_ENDED:
- case Renderer.STATE_STOPPED:
- pbState = PlaybackState.STATE_STOPPED;
- break;
- case Renderer.STATE_INIT:
- case Renderer.STATE_PREPARING:
- pbState = PlaybackState.STATE_BUFFERING;
- break;
- case Renderer.STATE_ERROR:
- pbState = PlaybackState.STATE_ERROR;
- break;
- case Renderer.STATE_PAUSED:
- pbState = PlaybackState.STATE_PAUSED;
- break;
- case Renderer.STATE_PLAYING:
- pbState = PlaybackState.STATE_PLAYING;
- rate = 1;
- break;
- default:
- pbState = PlaybackState.STATE_ERROR;
- errorMsg = "unknown state";
- break;
- }
- PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState);
- bob.setState(pbState, position, rate, SystemClock.elapsedRealtime());
- bob.setErrorMessage(errorMsg);
- mPlaybackState = bob.build();
-
- sendStatusUpdate(mPlaybackState.getState());
- }
-
- @Override
- public void onBufferingUpdate(int percent) {
- }
-
- @Override
- public void onFocusLost() {
- Log.d(TAG, "Focus lost, pausing");
- // Don't update state here, we'll get a separate call to
- // onStateChanged when it pauses
- mRenderer.onPause();
- }
-
- @Override
- public void onNextStarted() {
- }
-
- private void sendStatusUpdate(int state) {
- if (mStub != null) {
- MediaStatus status = new MediaStatus(1, mStub.mMediaInfo);
- switch (state) {
- case PlaybackState.STATE_BUFFERING:
- case PlaybackState.STATE_FAST_FORWARDING:
- case PlaybackState.STATE_REWINDING:
- case PlaybackState.STATE_SKIPPING_TO_NEXT:
- case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
- status.setPlayerState(MediaStatus.PLAYER_STATE_BUFFERING);
- break;
- case PlaybackState.STATE_CONNECTING:
- case PlaybackState.STATE_STOPPED:
- status.setPlayerState(MediaStatus.PLAYER_STATE_IDLE);
- break;
- case PlaybackState.STATE_PAUSED:
- status.setPlayerState(MediaStatus.PLAYER_STATE_PAUSED);
- break;
- case PlaybackState.STATE_PLAYING:
- status.setPlayerState(MediaStatus.PLAYER_STATE_PLAYING);
- break;
- case PlaybackState.STATE_NONE:
- case PlaybackState.STATE_ERROR:
- default:
- status.setPlayerState(MediaStatus.PLAYER_STATE_UNKNOWN);
- break;
- }
- mStub.sendStatusUpdatedEvent(status, null);
- }
- }
- }
-}
diff --git a/tools/layoutlib/bridge/resources/bars/status_bar.xml b/tools/layoutlib/bridge/resources/bars/status_bar.xml
index 75bfb6e..04571e1 100644
--- a/tools/layoutlib/bridge/resources/bars/status_bar.xml
+++ b/tools/layoutlib/bridge/resources/bars/status_bar.xml
@@ -1,17 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"/>
- <ImageView
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_marginTop="1dp"/>
- <ImageView
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_marginLeft="3dp"
- android:layout_marginRight="5dp"
- android:layout_marginTop="2dp"/>
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"/>
+ <!-- The exact size of the wifi icon is specified in order to scale it properly.
+ Without scaling, it appeared huge. This is currently, 70% of the actual size. -->
+ <ImageView
+ android:layout_height="22.4dp"
+ android:layout_width="20.65dp"
+ android:layout_marginTop="1dp"/>
+ <ImageView
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_marginLeft="3dp"
+ android:layout_marginRight="5dp"
+ android:layout_marginTop="4dp"/>
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="4dp"
+ android:layout_marginRight="5dp"
+ android:gravity="center_vertical"
+ android:textSize="16dp"
+ android:fontFamily="sans-serif-medium"/>
</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 931daed..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 6e1ac91..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 625c61d..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.xml b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.xml
new file mode 100644
index 0000000..0498b6c
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="32.0dp"
+ android:height="29.5dp"
+ android:viewportWidth="26.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+</vector>
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index f939678..5b69681 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -91,7 +91,7 @@
// first count the array size
int count = 0;
for (ResourceValue data : mResourceData) {
- if (data != null) {
+ if (data != null && !RenderResources.REFERENCE_NULL.equals(data.getValue())) {
count++;
}
}
@@ -103,7 +103,8 @@
// fill the array with the indices.
int index = 1;
for (int i = 0 ; i < mResourceData.length ; i++) {
- if (mResourceData[i] != null) {
+ if (mResourceData[i] != null
+ && !RenderResources.REFERENCE_NULL.equals(mResourceData[i].getValue())) {
mIndices[index++] = i;
}
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
index 9b814f5..16b54f1 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
@@ -20,10 +20,7 @@
import java.util.Collections;
import java.util.List;
-import static android.os.Build.VERSION_CODES.GINGERBREAD;
-import static android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH;
-import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
-import static android.os.Build.VERSION_CODES.KITKAT;
+import static android.os.Build.VERSION_CODES.*;
/**
* Various helper methods to simulate older versions of platform.
@@ -39,13 +36,16 @@
private static final List<String> sDefaultResourceDir =
Collections.singletonList(DEFAULT_RESOURCE_DIR);
+ private static final int WHITE = 0xFFFFFFFF;
+ private static final int BLACK = 0xFF000000;
+
public static boolean showOnScreenNavBar(int platformVersion) {
return platformVersion == 0 || platformVersion >= ICE_CREAM_SANDWICH;
}
public static int getStatusBarColor(int platformVersion) {
// return white for froyo and earlier; black otherwise.
- return platformVersion == 0 || platformVersion >= GINGERBREAD ? 0xFF000000 : 0xFFFFFFFF;
+ return platformVersion == 0 || platformVersion >= GINGERBREAD ? BLACK : WHITE;
}
public static List<String> getResourceDirs(int platformVersion) {
@@ -70,4 +70,49 @@
return Collections.unmodifiableList(list);
}
+
+ public static String getTime(int platformVersion) {
+ if (platformVersion == 0) {
+ // TODO: revisit when the version is selected.
+ return "4:57";
+ }
+ if (platformVersion < GINGERBREAD) {
+ return "2:20";
+ }
+ if (platformVersion < ICE_CREAM_SANDWICH) {
+ return "2:30";
+ }
+ if (platformVersion < JELLY_BEAN) {
+ return "4:00";
+ }
+ if (platformVersion < KITKAT) {
+ return "4:30";
+ }
+ if (platformVersion <= KITKAT_WATCH) {
+ return "4:40";
+ }
+ // Should never happen.
+ return "4:04";
+ }
+
+ public static int getTimeColor(int platformVersion) {
+ if (platformVersion == 0 || platformVersion >= KITKAT ||
+ platformVersion > FROYO && platformVersion < HONEYCOMB) {
+ // Gingerbread and KitKat onwards.
+ return WHITE;
+ }
+ // Black for froyo.
+ if (platformVersion < GINGERBREAD) {
+ return BLACK;
+ } else if (platformVersion < KITKAT) {
+ // Honeycomb to JB-mr2: Holo blue light.
+ return 0xff33b5e5;
+ }
+ // Should never happen.
+ return WHITE;
+ }
+
+ public static String getWifiIconType(int platformVersion) {
+ return platformVersion == 0 ? "xml" : "png";
+ }
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index bed232ab..13ddf07 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -127,24 +127,25 @@
}
}
- protected TextView setText(int index, String stringReference) {
+ protected TextView setText(int index, String string, boolean reference) {
View child = getChildAt(index);
if (child instanceof TextView) {
TextView textView = (TextView) child;
- setText(textView, stringReference);
+ setText(textView, string, reference);
return textView;
}
return null;
}
- private void setText(TextView textView, String stringReference) {
- ResourceValue value = getResourceValue(stringReference);
- if (value != null) {
- textView.setText(value.getValue());
- } else {
- textView.setText(stringReference);
+ private void setText(TextView textView, String string, boolean reference) {
+ if (reference) {
+ ResourceValue value = getResourceValue(string);
+ if (value != null) {
+ string = value.getValue();
+ }
}
+ textView.setText(string);
}
protected void setStyle(String themeEntryName) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
index 1795db9..c7c62d6 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
@@ -16,22 +16,38 @@
package com.android.layoutlib.bridge.bars;
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
+import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.resources.Density;
import org.xmlpull.v1.XmlPullParserException;
import android.content.Context;
+import android.graphics.drawable.Drawable;
import android.view.Gravity;
+import android.view.View;
+import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
+import java.io.IOException;
+import java.io.InputStream;
+
public class StatusBar extends CustomBar {
+ private final Context mContext;
+ private final int mSimulatedPlatformVersion;
+
public StatusBar(Context context, Density density, int direction, boolean RtlEnabled,
int simulatedPlatformVersion) throws XmlPullParserException {
// FIXME: if direction is RTL but it's not enabled in application manifest, mirror this bar.
super(context, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml",
simulatedPlatformVersion);
+ mContext = context;
+ mSimulatedPlatformVersion = simulatedPlatformVersion;
// FIXME: use FILL_H?
setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT);
@@ -41,8 +57,44 @@
// created for them.
// We do know the order though.
// 0 is the spacer
- loadIcon(1, "stat_sys_wifi_signal_4_fully.png", density);
+ loadIcon(1, "stat_sys_wifi_signal_4_fully."
+ + Config.getWifiIconType(simulatedPlatformVersion), density);
loadIcon(2, "stat_sys_battery_100.png", density);
+ setText(3, Config.getTime(simulatedPlatformVersion), false)
+ .setTextColor(Config.getTimeColor(simulatedPlatformVersion));
+ }
+
+ @Override
+ protected void loadIcon(int index, String iconName, Density density) {
+ if (!iconName.endsWith(".xml")) {
+ super.loadIcon(index, iconName, density);
+ return;
+ }
+ View child = getChildAt(index);
+ if (child instanceof ImageView) {
+ ImageView imageView = (ImageView) child;
+ // The xml is stored only in xhdpi.
+ IconLoader iconLoader = new IconLoader(iconName, Density.XHIGH,
+ mSimulatedPlatformVersion, null);
+ InputStream stream = iconLoader.getIcon();
+
+ if (stream != null) {
+ try {
+ BridgeXmlBlockParser parser = new BridgeXmlBlockParser(
+ ParserFactory.create(stream, null), (BridgeContext) mContext, true);
+ Drawable drawable = Drawable.createFromXml(mContext.getResources(), parser);
+ if (drawable != null) {
+ imageView.setImageDrawable(drawable);
+ }
+ } catch (XmlPullParserException e) {
+ Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e,
+ null);
+ } catch (IOException e) {
+ Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e,
+ null);
+ }
+ }
+ }
}
@Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
index ff952bd..10f1383 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
@@ -34,7 +34,7 @@
// Cannot access the inside items through id because no R.id values have been
// created for them.
// We do know the order though.
- mTextView = setText(0, label);
+ mTextView = setText(0, label, true);
setStyle("windowTitleBackgroundStyle");
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index e27bd7e..3d976e7 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1696,6 +1696,7 @@
*
* @hide
*/
+ @SystemApi
public void connect(WifiConfiguration config, ActionListener listener) {
if (config == null) throw new IllegalArgumentException("config cannot be null");
validateChannel();
@@ -1718,6 +1719,7 @@
* initialized again
* @hide
*/
+ @SystemApi
public void connect(int networkId, ActionListener listener) {
if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative");
validateChannel();
@@ -1742,6 +1744,7 @@
* initialized again
* @hide
*/
+ @SystemApi
public void save(WifiConfiguration config, ActionListener listener) {
if (config == null) throw new IllegalArgumentException("config cannot be null");
validateChannel();
@@ -1761,6 +1764,7 @@
* initialized again
* @hide
*/
+ @SystemApi
public void forget(int netId, ActionListener listener) {
if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");
validateChannel();
@@ -1776,6 +1780,7 @@
* initialized again
* @hide
*/
+ @SystemApi
public void disable(int netId, ActionListener listener) {
if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");
validateChannel();