diff options
128 files changed, 1609 insertions, 1187 deletions
diff --git a/api/current.txt b/api/current.txt index c083398e08ae..2a4a713bf812 100644 --- a/api/current.txt +++ b/api/current.txt @@ -4781,8 +4781,6 @@ package android.app { method public android.app.Notification clone(); method public int describeContents(); method public java.lang.String getGroup(); - method public android.graphics.drawable.Icon getLargeIcon(); - method public android.graphics.drawable.Icon getSmallIcon(); method public java.lang.String getSortKey(); method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent); method public void writeToParcel(android.os.Parcel, int); @@ -4927,7 +4925,6 @@ package android.app { ctor public Notification.BigPictureStyle(); ctor public Notification.BigPictureStyle(android.app.Notification.Builder); method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.Bitmap); - method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.drawable.Icon); method public android.app.Notification.BigPictureStyle bigPicture(android.graphics.Bitmap); method public android.app.Notification.BigPictureStyle setBigContentTitle(java.lang.CharSequence); method public android.app.Notification.BigPictureStyle setSummaryText(java.lang.CharSequence); @@ -4966,7 +4963,6 @@ package android.app { method public android.app.Notification.Builder setGroup(java.lang.String); method public android.app.Notification.Builder setGroupSummary(boolean); method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap); - method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon); method public android.app.Notification.Builder setLights(int, int, int); method public android.app.Notification.Builder setLocalOnly(boolean); method public android.app.Notification.Builder setNumber(int); @@ -4978,7 +4974,6 @@ package android.app { method public android.app.Notification.Builder setShowWhen(boolean); method public android.app.Notification.Builder setSmallIcon(int); method public android.app.Notification.Builder setSmallIcon(int, int); - method public android.app.Notification.Builder setSmallIcon(android.graphics.drawable.Icon); method public android.app.Notification.Builder setSortKey(java.lang.String); method public android.app.Notification.Builder setSound(android.net.Uri); method public deprecated android.app.Notification.Builder setSound(android.net.Uri, int); @@ -6058,22 +6053,14 @@ package android.app.usage { field public static final android.os.Parcelable.Creator<android.app.usage.ConfigurationStats> CREATOR; } - public class NetworkStatsManager { - method public android.app.usage.NetworkUsageStats queryDetails(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; - method public android.app.usage.NetworkUsageStats queryDetailsForUid(int, java.lang.String, long, long, int) throws android.os.RemoteException, java.lang.SecurityException; - method public android.app.usage.NetworkUsageStats querySummary(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; - method public android.app.usage.NetworkUsageStats.Bucket querySummaryForDevice(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; - method public android.app.usage.NetworkUsageStats.Bucket querySummaryForUser(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; - } - - public final class NetworkUsageStats implements java.lang.AutoCloseable { + public final class NetworkStats implements java.lang.AutoCloseable { method public void close(); - method public boolean getNextBucket(android.app.usage.NetworkUsageStats.Bucket); + method public boolean getNextBucket(android.app.usage.NetworkStats.Bucket); method public boolean hasNextBucket(); } - public static class NetworkUsageStats.Bucket { - ctor public NetworkUsageStats.Bucket(); + public static class NetworkStats.Bucket { + ctor public NetworkStats.Bucket(); method public long getEndTimeStamp(); method public long getRxBytes(); method public long getRxPackets(); @@ -6085,10 +6072,19 @@ package android.app.usage { field public static final int STATE_ALL = -1; // 0xffffffff field public static final int STATE_DEFAULT = 1; // 0x1 field public static final int STATE_FOREGROUND = 2; // 0x2 + field public static final int UID_ALL = -1; // 0xffffffff field public static final int UID_REMOVED = -4; // 0xfffffffc field public static final int UID_TETHERING = -5; // 0xfffffffb } + public class NetworkStatsManager { + method public android.app.usage.NetworkStats queryDetails(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; + method public android.app.usage.NetworkStats queryDetailsForUid(int, java.lang.String, long, long, int) throws android.os.RemoteException, java.lang.SecurityException; + method public android.app.usage.NetworkStats querySummary(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; + method public android.app.usage.NetworkStats.Bucket querySummaryForDevice(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; + method public android.app.usage.NetworkStats.Bucket querySummaryForUser(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; + } + public final class UsageEvents implements android.os.Parcelable { method public int describeContents(); method public boolean getNextEvent(android.app.usage.UsageEvents.Event); @@ -13169,7 +13165,7 @@ package android.hardware.camera2 { method public abstract void close(); method public abstract android.hardware.camera2.CameraDevice getDevice(); method public abstract android.view.Surface getInputSurface(); - method public abstract boolean isReprocessible(); + method public abstract boolean isReprocessable(); method public abstract void prepare(android.view.Surface) throws android.hardware.camera2.CameraAccessException; method public abstract int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; method public abstract int setRepeatingRequest(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; @@ -13290,7 +13286,7 @@ package android.hardware.camera2 { method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException; method public abstract void createCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; method public abstract android.hardware.camera2.CaptureRequest.Builder createReprocessCaptureRequest(android.hardware.camera2.TotalCaptureResult) throws android.hardware.camera2.CameraAccessException; - method public abstract void createReprocessibleCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; + method public abstract void createReprocessableCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; method public abstract java.lang.String getId(); field public static final int TEMPLATE_MANUAL = 6; // 0x6 field public static final int TEMPLATE_PREVIEW = 1; // 0x1 @@ -13469,7 +13465,7 @@ package android.hardware.camera2 { field public static final int REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT = 8; // 0x8 field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2; // 0x2 field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 1; // 0x1 - field public static final int REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING = 4; // 0x4 + field public static final int REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING = 4; // 0x4 field public static final int REQUEST_AVAILABLE_CAPABILITIES_RAW = 3; // 0x3 field public static final int REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS = 5; // 0x5 field public static final int REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING = 7; // 0x7 @@ -14703,7 +14699,7 @@ package android.media { method public int[] getChannelMasks(); method public int[] getFormats(); method public int getId(); - method public java.lang.CharSequence getName(); + method public java.lang.CharSequence getProductName(); method public int[] getSampleRates(); method public int getType(); method public boolean isSink(); @@ -15234,7 +15230,6 @@ package android.media { method public abstract android.media.Image.Plane[] getPlanes(); method public abstract long getTimestamp(); method public abstract int getWidth(); - method public boolean isOpaque(); method public void setCropRect(android.graphics.Rect); method public void setTimestamp(long); } @@ -15254,9 +15249,7 @@ package android.media { method public int getMaxImages(); method public android.view.Surface getSurface(); method public int getWidth(); - method public boolean isOpaque(); method public static android.media.ImageReader newInstance(int, int, int, int); - method public static android.media.ImageReader newOpaqueInstance(int, int, int); method public void setOnImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler); } @@ -15271,11 +15264,11 @@ package android.media { method public int getMaxImages(); method public static android.media.ImageWriter newInstance(android.view.Surface, int); method public void queueInputImage(android.media.Image); - method public void setImageListener(android.media.ImageWriter.ImageListener, android.os.Handler); + method public void setOnImageReleasedListener(android.media.ImageWriter.OnImageReleasedListener, android.os.Handler); } - public static abstract interface ImageWriter.ImageListener { - method public abstract void onInputImageReleased(android.media.ImageWriter); + public static abstract interface ImageWriter.OnImageReleasedListener { + method public abstract void onImageReleased(android.media.ImageWriter); } public class JetPlayer { @@ -15677,9 +15670,10 @@ package android.media { ctor public MediaCryptoException(java.lang.String); } - public abstract interface MediaDataSource implements java.io.Closeable { - method public abstract long getSize(); - method public abstract int readAt(long, byte[], int); + public abstract class MediaDataSource implements java.io.Closeable { + ctor public MediaDataSource(); + method public abstract long getSize() throws java.io.IOException; + method public abstract int readAt(long, byte[], int, int) throws java.io.IOException; } public class MediaDescription implements android.os.Parcelable { @@ -16103,7 +16097,6 @@ package android.media { method public void setOnTimedTextListener(android.media.MediaPlayer.OnTimedTextListener); method public void setOnVideoSizeChangedListener(android.media.MediaPlayer.OnVideoSizeChangedListener); method public void setPlaybackParams(android.media.PlaybackParams); - method public void setPlaybackRate(float, int); method public void setScreenOnWhilePlaying(boolean); method public void setSurface(android.view.Surface); method public void setSyncParams(android.media.SyncParams); @@ -16130,9 +16123,6 @@ package android.media { field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3 field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip"; - field public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0; // 0x0 - field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2; // 0x2 - field public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1; // 0x1 field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1; // 0x1 field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2; // 0x2 } @@ -16434,14 +16424,10 @@ package android.media { method public void setCallback(android.media.MediaSync.Callback, android.os.Handler); method public void setOnErrorListener(android.media.MediaSync.OnErrorListener, android.os.Handler); method public void setPlaybackParams(android.media.PlaybackParams); - method public void setPlaybackRate(float, int); method public void setSurface(android.view.Surface); method public void setSyncParams(android.media.SyncParams); field public static final int MEDIASYNC_ERROR_AUDIOTRACK_FAIL = 1; // 0x1 field public static final int MEDIASYNC_ERROR_SURFACE_FAIL = 2; // 0x2 - field public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0; // 0x0 - field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2; // 0x2 - field public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1; // 0x1 } public static abstract class MediaSync.Callback { @@ -16463,9 +16449,9 @@ package android.media { } public final class MediaTimestamp { - field public final float clockRate; - field public final long mediaTimeUs; - field public final long nanoTime; + method public long getAnchorMediaTimeUs(); + method public long getAnchorSytemNanoTime(); + method public float getMediaClockRate(); } public final class NotProvisionedException extends android.media.MediaDrmException { @@ -30055,7 +30041,7 @@ package android.telecom { field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5 } - public abstract class Conference implements android.telecom.Conferenceable { + public abstract class Conference extends android.telecom.Conferenceable { ctor public Conference(android.telecom.PhoneAccountHandle); method public final boolean addConnection(android.telecom.Connection); method public final void destroy(); @@ -30094,10 +30080,10 @@ package android.telecom { field public static final long CONNECT_TIME_NOT_SPECIFIED = 0L; // 0x0L } - public abstract interface Conferenceable { + public abstract class Conferenceable { } - public abstract class Connection implements android.telecom.Conferenceable { + public abstract class Connection extends android.telecom.Conferenceable { ctor public Connection(); method public static java.lang.String capabilitiesToString(int); method public static android.telecom.Connection createCanceledConnection(); @@ -38812,7 +38798,7 @@ package android.webkit { } public abstract class WebResourceError { - method public abstract java.lang.CharSequence getDescription(); + method public java.lang.CharSequence getDescription(); method public abstract int getErrorCode(); } diff --git a/api/system-current.txt b/api/system-current.txt index d7c95da784c5..52cff6202213 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4875,8 +4875,6 @@ package android.app { method public android.app.Notification clone(); method public int describeContents(); method public java.lang.String getGroup(); - method public android.graphics.drawable.Icon getLargeIcon(); - method public android.graphics.drawable.Icon getSmallIcon(); method public java.lang.String getSortKey(); method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent); method public void writeToParcel(android.os.Parcel, int); @@ -5021,7 +5019,6 @@ package android.app { ctor public Notification.BigPictureStyle(); ctor public Notification.BigPictureStyle(android.app.Notification.Builder); method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.Bitmap); - method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.drawable.Icon); method public android.app.Notification.BigPictureStyle bigPicture(android.graphics.Bitmap); method public android.app.Notification.BigPictureStyle setBigContentTitle(java.lang.CharSequence); method public android.app.Notification.BigPictureStyle setSummaryText(java.lang.CharSequence); @@ -5060,7 +5057,6 @@ package android.app { method public android.app.Notification.Builder setGroup(java.lang.String); method public android.app.Notification.Builder setGroupSummary(boolean); method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap); - method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon); method public android.app.Notification.Builder setLights(int, int, int); method public android.app.Notification.Builder setLocalOnly(boolean); method public android.app.Notification.Builder setNumber(int); @@ -5072,7 +5068,6 @@ package android.app { method public android.app.Notification.Builder setShowWhen(boolean); method public android.app.Notification.Builder setSmallIcon(int); method public android.app.Notification.Builder setSmallIcon(int, int); - method public android.app.Notification.Builder setSmallIcon(android.graphics.drawable.Icon); method public android.app.Notification.Builder setSortKey(java.lang.String); method public android.app.Notification.Builder setSound(android.net.Uri); method public deprecated android.app.Notification.Builder setSound(android.net.Uri, int); @@ -6249,22 +6244,14 @@ package android.app.usage { field public static final android.os.Parcelable.Creator<android.app.usage.ConfigurationStats> CREATOR; } - public class NetworkStatsManager { - method public android.app.usage.NetworkUsageStats queryDetails(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; - method public android.app.usage.NetworkUsageStats queryDetailsForUid(int, java.lang.String, long, long, int) throws android.os.RemoteException, java.lang.SecurityException; - method public android.app.usage.NetworkUsageStats querySummary(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; - method public android.app.usage.NetworkUsageStats.Bucket querySummaryForDevice(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; - method public android.app.usage.NetworkUsageStats.Bucket querySummaryForUser(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; - } - - public final class NetworkUsageStats implements java.lang.AutoCloseable { + public final class NetworkStats implements java.lang.AutoCloseable { method public void close(); - method public boolean getNextBucket(android.app.usage.NetworkUsageStats.Bucket); + method public boolean getNextBucket(android.app.usage.NetworkStats.Bucket); method public boolean hasNextBucket(); } - public static class NetworkUsageStats.Bucket { - ctor public NetworkUsageStats.Bucket(); + public static class NetworkStats.Bucket { + ctor public NetworkStats.Bucket(); method public long getEndTimeStamp(); method public long getRxBytes(); method public long getRxPackets(); @@ -6276,10 +6263,19 @@ package android.app.usage { field public static final int STATE_ALL = -1; // 0xffffffff field public static final int STATE_DEFAULT = 1; // 0x1 field public static final int STATE_FOREGROUND = 2; // 0x2 + field public static final int UID_ALL = -1; // 0xffffffff field public static final int UID_REMOVED = -4; // 0xfffffffc field public static final int UID_TETHERING = -5; // 0xfffffffb } + public class NetworkStatsManager { + method public android.app.usage.NetworkStats queryDetails(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; + method public android.app.usage.NetworkStats queryDetailsForUid(int, java.lang.String, long, long, int) throws android.os.RemoteException, java.lang.SecurityException; + method public android.app.usage.NetworkStats querySummary(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; + method public android.app.usage.NetworkStats.Bucket querySummaryForDevice(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; + method public android.app.usage.NetworkStats.Bucket querySummaryForUser(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException; + } + public final class UsageEvents implements android.os.Parcelable { method public int describeContents(); method public boolean getNextEvent(android.app.usage.UsageEvents.Event); @@ -13483,7 +13479,7 @@ package android.hardware.camera2 { method public abstract void close(); method public abstract android.hardware.camera2.CameraDevice getDevice(); method public abstract android.view.Surface getInputSurface(); - method public abstract boolean isReprocessible(); + method public abstract boolean isReprocessable(); method public abstract void prepare(android.view.Surface) throws android.hardware.camera2.CameraAccessException; method public abstract int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; method public abstract int setRepeatingRequest(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; @@ -13604,7 +13600,7 @@ package android.hardware.camera2 { method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException; method public abstract void createCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; method public abstract android.hardware.camera2.CaptureRequest.Builder createReprocessCaptureRequest(android.hardware.camera2.TotalCaptureResult) throws android.hardware.camera2.CameraAccessException; - method public abstract void createReprocessibleCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; + method public abstract void createReprocessableCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; method public abstract java.lang.String getId(); field public static final int TEMPLATE_MANUAL = 6; // 0x6 field public static final int TEMPLATE_PREVIEW = 1; // 0x1 @@ -13783,7 +13779,7 @@ package android.hardware.camera2 { field public static final int REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT = 8; // 0x8 field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2; // 0x2 field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 1; // 0x1 - field public static final int REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING = 4; // 0x4 + field public static final int REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING = 4; // 0x4 field public static final int REQUEST_AVAILABLE_CAPABILITIES_RAW = 3; // 0x3 field public static final int REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS = 5; // 0x5 field public static final int REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING = 7; // 0x7 @@ -15916,7 +15912,7 @@ package android.media { method public int[] getChannelMasks(); method public int[] getFormats(); method public int getId(); - method public java.lang.CharSequence getName(); + method public java.lang.CharSequence getProductName(); method public int[] getSampleRates(); method public int getType(); method public boolean isSink(); @@ -16471,7 +16467,6 @@ package android.media { method public abstract android.media.Image.Plane[] getPlanes(); method public abstract long getTimestamp(); method public abstract int getWidth(); - method public boolean isOpaque(); method public void setCropRect(android.graphics.Rect); method public void setTimestamp(long); } @@ -16491,9 +16486,7 @@ package android.media { method public int getMaxImages(); method public android.view.Surface getSurface(); method public int getWidth(); - method public boolean isOpaque(); method public static android.media.ImageReader newInstance(int, int, int, int); - method public static android.media.ImageReader newOpaqueInstance(int, int, int); method public void setOnImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler); } @@ -16508,11 +16501,11 @@ package android.media { method public int getMaxImages(); method public static android.media.ImageWriter newInstance(android.view.Surface, int); method public void queueInputImage(android.media.Image); - method public void setImageListener(android.media.ImageWriter.ImageListener, android.os.Handler); + method public void setOnImageReleasedListener(android.media.ImageWriter.OnImageReleasedListener, android.os.Handler); } - public static abstract interface ImageWriter.ImageListener { - method public abstract void onInputImageReleased(android.media.ImageWriter); + public static abstract interface ImageWriter.OnImageReleasedListener { + method public abstract void onImageReleased(android.media.ImageWriter); } public class JetPlayer { @@ -16914,9 +16907,10 @@ package android.media { ctor public MediaCryptoException(java.lang.String); } - public abstract interface MediaDataSource implements java.io.Closeable { - method public abstract long getSize(); - method public abstract int readAt(long, byte[], int); + public abstract class MediaDataSource implements java.io.Closeable { + ctor public MediaDataSource(); + method public abstract long getSize() throws java.io.IOException; + method public abstract int readAt(long, byte[], int, int) throws java.io.IOException; } public class MediaDescription implements android.os.Parcelable { @@ -17341,7 +17335,6 @@ package android.media { method public void setOnTimedTextListener(android.media.MediaPlayer.OnTimedTextListener); method public void setOnVideoSizeChangedListener(android.media.MediaPlayer.OnVideoSizeChangedListener); method public void setPlaybackParams(android.media.PlaybackParams); - method public void setPlaybackRate(float, int); method public void setScreenOnWhilePlaying(boolean); method public void setSurface(android.view.Surface); method public void setSyncParams(android.media.SyncParams); @@ -17368,9 +17361,6 @@ package android.media { field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3 field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip"; - field public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0; // 0x0 - field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2; // 0x2 - field public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1; // 0x1 field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1; // 0x1 field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2; // 0x2 } @@ -17674,14 +17664,10 @@ package android.media { method public void setCallback(android.media.MediaSync.Callback, android.os.Handler); method public void setOnErrorListener(android.media.MediaSync.OnErrorListener, android.os.Handler); method public void setPlaybackParams(android.media.PlaybackParams); - method public void setPlaybackRate(float, int); method public void setSurface(android.view.Surface); method public void setSyncParams(android.media.SyncParams); field public static final int MEDIASYNC_ERROR_AUDIOTRACK_FAIL = 1; // 0x1 field public static final int MEDIASYNC_ERROR_SURFACE_FAIL = 2; // 0x2 - field public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0; // 0x0 - field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2; // 0x2 - field public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1; // 0x1 } public static abstract class MediaSync.Callback { @@ -17703,9 +17689,9 @@ package android.media { } public final class MediaTimestamp { - field public final float clockRate; - field public final long mediaTimeUs; - field public final long nanoTime; + method public long getAnchorMediaTimeUs(); + method public long getAnchorSytemNanoTime(); + method public float getMediaClockRate(); } public final class NotProvisionedException extends android.media.MediaDrmException { @@ -32208,7 +32194,7 @@ package android.telecom { field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5 } - public abstract class Conference implements android.telecom.Conferenceable { + public abstract class Conference extends android.telecom.Conferenceable { ctor public Conference(android.telecom.PhoneAccountHandle); method public final boolean addConnection(android.telecom.Connection); method public final void destroy(); @@ -32252,10 +32238,10 @@ package android.telecom { field public static final long CONNECT_TIME_NOT_SPECIFIED = 0L; // 0x0L } - public abstract interface Conferenceable { + public abstract class Conferenceable { } - public abstract class Connection implements android.telecom.Conferenceable { + public abstract class Connection extends android.telecom.Conferenceable { ctor public Connection(); method public static java.lang.String capabilitiesToString(int); method public static android.telecom.Connection createCanceledConnection(); @@ -41136,7 +41122,7 @@ package android.webkit { public abstract class WebResourceError { ctor public WebResourceError(); - method public abstract java.lang.CharSequence getDescription(); + method public java.lang.CharSequence getDescription(); method public abstract int getErrorCode(); } diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index eb834f282709..1599459a51d9 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -1585,7 +1585,7 @@ public final class Pm { } private int runGrantRevokePermission(boolean grant) { - int userId = UserHandle.USER_CURRENT; + int userId = UserHandle.USER_OWNER; String opt = null; while ((opt = nextOption()) != null) { diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index f506d59448bf..5dcbe37db54f 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -96,7 +96,7 @@ import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.renderscript.RenderScriptCacheDir; -import android.security.AndroidKeyStoreProvider; +import android.security.keystore.AndroidKeyStoreProvider; import com.android.internal.app.IVoiceInteractor; import com.android.internal.content.ReferrerIntent; diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 3ffeea7e3bd5..49b254936295 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -30,7 +30,6 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; -import android.graphics.drawable.Icon; import android.media.AudioAttributes; import android.media.AudioManager; import android.media.session.MediaSession; @@ -886,9 +885,6 @@ public class Notification implements Parcelable */ public static final int HEADS_UP_REQUESTED = 2; - private Icon mSmallIcon; - private Icon mLargeIcon; - /** * Structure to encapsulate a named action that can be shown as part of this notification. * It must include an icon, a label, and a {@link PendingIntent} to be fired when the action is @@ -1366,7 +1362,7 @@ public class Notification implements Parcelable int version = parcel.readInt(); when = parcel.readLong(); - mSmallIcon = Icon.CREATOR.createFromParcel(parcel); + icon = parcel.readInt(); number = parcel.readInt(); if (parcel.readInt() != 0) { contentIntent = PendingIntent.CREATOR.createFromParcel(parcel); @@ -1384,7 +1380,7 @@ public class Notification implements Parcelable contentView = RemoteViews.CREATOR.createFromParcel(parcel); } if (parcel.readInt() != 0) { - mLargeIcon = Icon.CREATOR.createFromParcel(parcel); + largeIcon = Bitmap.CREATOR.createFromParcel(parcel); } defaults = parcel.readInt(); flags = parcel.readInt(); @@ -1449,7 +1445,7 @@ public class Notification implements Parcelable */ public void cloneInto(Notification that, boolean heavy) { that.when = this.when; - that.mSmallIcon = this.mSmallIcon; + that.icon = this.icon; that.number = this.number; // PendingIntents are global, so there's no reason (or way) to clone them. @@ -1466,8 +1462,8 @@ public class Notification implements Parcelable if (heavy && this.contentView != null) { that.contentView = this.contentView.clone(); } - if (heavy && this.mLargeIcon != null) { - that.mLargeIcon = this.mLargeIcon; + if (heavy && this.largeIcon != null) { + that.largeIcon = Bitmap.createBitmap(this.largeIcon); } that.iconLevel = this.iconLevel; that.sound = this.sound; // android.net.Uri is immutable @@ -1548,7 +1544,7 @@ public class Notification implements Parcelable contentView = null; bigContentView = null; headsUpContentView = null; - mLargeIcon = null; + largeIcon = null; if (extras != null) { extras.remove(Notification.EXTRA_LARGE_ICON); extras.remove(Notification.EXTRA_LARGE_ICON_BIG); @@ -1590,7 +1586,7 @@ public class Notification implements Parcelable parcel.writeInt(1); parcel.writeLong(when); - mSmallIcon.writeToParcel(parcel, 0); + parcel.writeInt(icon); parcel.writeInt(number); if (contentIntent != null) { parcel.writeInt(1); @@ -1622,9 +1618,9 @@ public class Notification implements Parcelable } else { parcel.writeInt(0); } - if (mLargeIcon != null) { + if (largeIcon != null) { parcel.writeInt(1); - mLargeIcon.writeToParcel(parcel, 0); + largeIcon.writeToParcel(parcel, 0); } else { parcel.writeInt(0); } @@ -1869,27 +1865,6 @@ public class Notification implements Parcelable } /** - * The small icon representing this notification in the status bar and content view. - * - * @return the small icon representing this notification. - * - * @see Builder#getSmallIcon() - * @see Builder#setSmallIcon(Icon) - */ - public Icon getSmallIcon() { - return mSmallIcon; - } - - /** - * The large icon shown in this notification's content view. - * @see Builder#getLargeIcon() - * @see Builder#setLargeIcon(Icon) - */ - public Icon getLargeIcon() { - return mLargeIcon; - } - - /** * @hide */ public boolean isValid() { @@ -1991,7 +1966,7 @@ public class Notification implements Parcelable private Context mContext; private long mWhen; - private Icon mSmallIcon, mLargeIcon; + private int mSmallIcon; private int mSmallIconLevel; private int mNumber; private CharSequence mContentTitle; @@ -2004,6 +1979,7 @@ public class Notification implements Parcelable private PendingIntent mFullScreenIntent; private CharSequence mTickerText; private RemoteViews mTickerView; + private Bitmap mLargeIcon; private Uri mSound; private int mAudioStreamType; private AudioAttributes mAudioAttributes; @@ -2184,7 +2160,8 @@ public class Notification implements Parcelable * @see Notification#icon */ public Builder setSmallIcon(@DrawableRes int icon) { - return setSmallIcon(Icon.createWithResource(mContext.getResources(), icon)); + mSmallIcon = icon; + return this; } /** @@ -2199,20 +2176,8 @@ public class Notification implements Parcelable * @see Notification#iconLevel */ public Builder setSmallIcon(@DrawableRes int icon, int level) { - mSmallIconLevel = level; - return setSmallIcon(icon); - } - - /** - * Set the small icon, which will be used to represent the notification in the - * status bar and content view (unless overriden there by a - * {@link #setLargeIcon(Bitmap) large icon}). - * - * @param icon An Icon object to use. - * @see Notification#icon - */ - public Builder setSmallIcon(Icon icon) { mSmallIcon = icon; + mSmallIconLevel = level; return this; } @@ -2359,24 +2324,14 @@ public class Notification implements Parcelable } /** - * Add a large icon to the notification content view. + * Add a large icon to the notification (and the ticker on some devices). * * In the platform template, this image will be shown on the left of the notification view - * in place of the {@link #setSmallIcon(Icon) small icon} (which will be placed in a small - * badge atop the large icon). - */ - public Builder setLargeIcon(Bitmap b) { - return setLargeIcon(b != null ? Icon.createWithBitmap(b) : null); - } - - /** - * Add a large icon to the notification content view. + * in place of the {@link #setSmallIcon(int) small icon} (which will move to the right side). * - * In the platform template, this image will be shown on the left of the notification view - * in place of the {@link #setSmallIcon(Icon) small icon} (which will be placed in a small - * badge atop the large icon). + * @see Notification#largeIcon */ - public Builder setLargeIcon(Icon icon) { + public Builder setLargeIcon(Bitmap icon) { mLargeIcon = icon; return this; } @@ -2885,13 +2840,13 @@ public class Notification implements Parcelable boolean contentTextInLine2 = false; if (mLargeIcon != null) { - contentView.setImageViewIcon(R.id.icon, mLargeIcon); + contentView.setImageViewBitmap(R.id.icon, mLargeIcon); processLargeLegacyIcon(mLargeIcon, contentView); - contentView.setImageViewIcon(R.id.right_icon, mSmallIcon); + contentView.setImageViewResource(R.id.right_icon, mSmallIcon); contentView.setViewVisibility(R.id.right_icon, View.VISIBLE); processSmallRightIcon(mSmallIcon, contentView); } else { // small icon at left - contentView.setImageViewIcon(R.id.icon, mSmallIcon); + contentView.setImageViewResource(R.id.icon, mSmallIcon); contentView.setViewVisibility(R.id.icon, View.VISIBLE); processSmallIconAsLarge(mSmallIcon, contentView); } @@ -3131,16 +3086,14 @@ public class Notification implements Parcelable /** * Apply any necessary background to smallIcons being used in the largeIcon spot. */ - private void processSmallIconAsLarge(Icon largeIcon, RemoteViews contentView) { + private void processSmallIconAsLarge(int largeIconId, RemoteViews contentView) { if (!isLegacy()) { contentView.setDrawableParameters(R.id.icon, false, -1, 0xFFFFFFFF, PorterDuff.Mode.SRC_ATOP, -1); + } + if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, largeIconId)) { applyLargeIconBackground(contentView); - } else { - if (mColorUtil.isGrayscaleIcon(mContext, largeIcon)) { - applyLargeIconBackground(contentView); - } } } @@ -3149,9 +3102,8 @@ public class Notification implements Parcelable * if it's grayscale). */ // TODO: also check bounds, transparency, that sort of thing. - private void processLargeLegacyIcon(Icon largeIcon, RemoteViews contentView) { - if (largeIcon != null && isLegacy() - && mColorUtil.isGrayscaleIcon(mContext, largeIcon)) { + private void processLargeLegacyIcon(Bitmap largeIcon, RemoteViews contentView) { + if (isLegacy() && mColorUtil.isGrayscaleIcon(largeIcon)) { applyLargeIconBackground(contentView); } else { removeLargeIconBackground(contentView); @@ -3185,15 +3137,14 @@ public class Notification implements Parcelable /** * Recolor small icons when used in the R.id.right_icon slot. */ - private void processSmallRightIcon(Icon smallIcon, RemoteViews contentView) { + private void processSmallRightIcon(int smallIconDrawableId, + RemoteViews contentView) { if (!isLegacy()) { contentView.setDrawableParameters(R.id.right_icon, false, -1, 0xFFFFFFFF, PorterDuff.Mode.SRC_ATOP, -1); } - final boolean gray = (smallIcon.getType() == Icon.TYPE_RESOURCE - && mColorUtil.isGrayscaleIcon(mContext, smallIcon.getResId())); - if (!isLegacy() || gray) { + if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, smallIconDrawableId)) { contentView.setInt(R.id.right_icon, "setBackgroundResource", R.drawable.notification_icon_legacy_bg); @@ -3229,10 +3180,7 @@ public class Notification implements Parcelable public Notification buildUnstyled() { Notification n = new Notification(); n.when = mWhen; - n.mSmallIcon = mSmallIcon; - if (mSmallIcon.getType() == Icon.TYPE_RESOURCE) { - n.icon = mSmallIcon.getResId(); - } + n.icon = mSmallIcon; n.iconLevel = mSmallIconLevel; n.number = mNumber; @@ -3244,10 +3192,7 @@ public class Notification implements Parcelable n.fullScreenIntent = mFullScreenIntent; n.tickerText = mTickerText; n.tickerView = makeTickerView(); - n.mLargeIcon = mLargeIcon; - if (mLargeIcon != null && mLargeIcon.getType() == Icon.TYPE_BITMAP) { - n.largeIcon = mLargeIcon.getBitmap(); - } + n.largeIcon = mLargeIcon; n.sound = mSound; n.audioStreamType = mAudioStreamType; n.audioAttributes = mAudioAttributes; @@ -3297,7 +3242,7 @@ public class Notification implements Parcelable extras.putCharSequence(EXTRA_TEXT, mContentText); extras.putCharSequence(EXTRA_SUB_TEXT, mSubText); extras.putCharSequence(EXTRA_INFO_TEXT, mContentInfo); - extras.putParcelable(EXTRA_SMALL_ICON, mSmallIcon); + extras.putInt(EXTRA_SMALL_ICON, mSmallIcon); extras.putInt(EXTRA_PROGRESS, mProgress); extras.putInt(EXTRA_PROGRESS_MAX, mProgressMax); extras.putBoolean(EXTRA_PROGRESS_INDETERMINATE, mProgressIndeterminate); @@ -3485,7 +3430,7 @@ public class Notification implements Parcelable // Notification fields. mWhen = n.when; - mSmallIcon = n.mSmallIcon; + mSmallIcon = n.icon; mSmallIconLevel = n.iconLevel; mNumber = n.number; @@ -3496,7 +3441,7 @@ public class Notification implements Parcelable mFullScreenIntent = n.fullScreenIntent; mTickerText = n.tickerText; mTickerView = n.tickerView; - mLargeIcon = n.mLargeIcon; + mLargeIcon = n.largeIcon; mSound = n.sound; mAudioStreamType = n.audioStreamType; mAudioAttributes = n.audioAttributes; @@ -3527,7 +3472,7 @@ public class Notification implements Parcelable mContentText = extras.getCharSequence(EXTRA_TEXT); mSubText = extras.getCharSequence(EXTRA_SUB_TEXT); mContentInfo = extras.getCharSequence(EXTRA_INFO_TEXT); - mSmallIcon = extras.getParcelable(EXTRA_SMALL_ICON); + mSmallIcon = extras.getInt(EXTRA_SMALL_ICON); mProgress = extras.getInt(EXTRA_PROGRESS); mProgressMax = extras.getInt(EXTRA_PROGRESS_MAX); mProgressIndeterminate = extras.getBoolean(EXTRA_PROGRESS_INDETERMINATE); @@ -3819,7 +3764,7 @@ public class Notification implements Parcelable */ public static class BigPictureStyle extends Style { private Bitmap mPicture; - private Icon mBigLargeIcon; + private Bitmap mBigLargeIcon; private boolean mBigLargeIconSet = false; public BigPictureStyle() { @@ -3858,15 +3803,8 @@ public class Notification implements Parcelable * Override the large icon when the big notification is shown. */ public BigPictureStyle bigLargeIcon(Bitmap b) { - return bigLargeIcon(b != null ? Icon.createWithBitmap(b) : null); - } - - /** - * Override the large icon when the big notification is shown. - */ - public BigPictureStyle bigLargeIcon(Icon icon) { mBigLargeIconSet = true; - mBigLargeIcon = icon; + mBigLargeIcon = b; return this; } @@ -3877,7 +3815,7 @@ public class Notification implements Parcelable // 1. mBigLargeIconSet -> mBigLargeIcon (null or non-null) applies, overrides // mLargeIcon // 2. !mBigLargeIconSet -> mLargeIcon applies - Icon oldLargeIcon = null; + Bitmap oldLargeIcon = null; if (mBigLargeIconSet) { oldLargeIcon = mBuilder.mLargeIcon; mBuilder.mLargeIcon = mBigLargeIcon; diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java index 9540eb136c4c..4d2158ffb457 100644 --- a/core/java/android/app/backup/BackupTransport.java +++ b/core/java/android/app/backup/BackupTransport.java @@ -162,8 +162,17 @@ public class BackupTransport { * this is called, {@link #finishBackup} will be called to ensure the request * is sent and received successfully. * + * <p>If the transport returns anything other than TRANSPORT_OK from this method, + * the OS will halt the current initialize operation and schedule a retry in the + * near future. Even if the transport is in a state such that attempting to + * "initialize" the backend storage is meaningless -- for example, if there is + * no current live dataset at all, or there is no authenticated account under which + * to store the data remotely -- the transport should return TRANSPORT_OK here + * and treat the initializeDevice() / finishBackup() pair as a graceful no-op. + * * @return One of {@link BackupTransport#TRANSPORT_OK} (OK so far) or - * {@link BackupTransport#TRANSPORT_ERROR} (on network error or other failure). + * {@link BackupTransport#TRANSPORT_ERROR} (to retry following network error + * or other failure). */ public int initializeDevice() { return BackupTransport.TRANSPORT_ERROR; diff --git a/core/java/android/app/usage/NetworkUsageStats.java b/core/java/android/app/usage/NetworkStats.java index 990d23194037..5193563413b6 100644 --- a/core/java/android/app/usage/NetworkUsageStats.java +++ b/core/java/android/app/usage/NetworkStats.java @@ -19,7 +19,6 @@ package android.app.usage; import android.content.Context; import android.net.INetworkStatsService; import android.net.INetworkStatsSession; -import android.net.NetworkStats; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; import android.net.TrafficStats; @@ -33,7 +32,7 @@ import dalvik.system.CloseGuard; * Class providing enumeration over buckets of network usage statistics. NetworkUsageStats objects * are returned as results to various queries in {@link NetworkStatsManager}. */ -public final class NetworkUsageStats implements AutoCloseable { +public final class NetworkStats implements AutoCloseable { private final static String TAG = "NetworkUsageStats"; private final CloseGuard mCloseGuard = CloseGuard.get(); @@ -70,7 +69,7 @@ public final class NetworkUsageStats implements AutoCloseable { /** * Results of a summary query. */ - private NetworkStats mSummary = null; + private android.net.NetworkStats mSummary = null; /** * Results of detail queries. @@ -85,11 +84,11 @@ public final class NetworkUsageStats implements AutoCloseable { /** * Recycling entry objects to prevent heap fragmentation. */ - private NetworkStats.Entry mRecycledSummaryEntry = null; + private android.net.NetworkStats.Entry mRecycledSummaryEntry = null; private NetworkStatsHistory.Entry mRecycledHistoryEntry = null; /** @hide */ - NetworkUsageStats(Context context, NetworkTemplate template, long startTimestamp, + NetworkStats(Context context, NetworkTemplate template, long startTimestamp, long endTimestamp) throws RemoteException, SecurityException { final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface( ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); @@ -136,14 +135,19 @@ public final class NetworkUsageStats implements AutoCloseable { public static final int STATE_FOREGROUND = 0x2; /** + * Special UID value for aggregate/unspecified. + */ + public static final int UID_ALL = android.net.NetworkStats.UID_ALL; + + /** * Special UID value for removed apps. */ - public static final int UID_REMOVED = -4; + public static final int UID_REMOVED = TrafficStats.UID_REMOVED; /** * Special UID value for data usage by tethering. */ - public static final int UID_TETHERING = -5; + public static final int UID_TETHERING = TrafficStats.UID_TETHERING; private int mUid; private int mState; @@ -156,9 +160,9 @@ public final class NetworkUsageStats implements AutoCloseable { private static int convertState(int networkStatsSet) { switch (networkStatsSet) { - case NetworkStats.SET_ALL : return STATE_ALL; - case NetworkStats.SET_DEFAULT : return STATE_DEFAULT; - case NetworkStats.SET_FOREGROUND : return STATE_FOREGROUND; + case android.net.NetworkStats.SET_ALL : return STATE_ALL; + case android.net.NetworkStats.SET_DEFAULT : return STATE_DEFAULT; + case android.net.NetworkStats.SET_FOREGROUND : return STATE_FOREGROUND; } return 0; } @@ -337,8 +341,8 @@ public final class NetworkUsageStats implements AutoCloseable { void startHistoryEnumeration(int uid) { mHistory = null; try { - mHistory = mSession.getHistoryForUid(mTemplate, uid, NetworkStats.SET_ALL, - NetworkStats.TAG_NONE, NetworkStatsHistory.FIELD_ALL); + mHistory = mSession.getHistoryForUid(mTemplate, uid, android.net.NetworkStats.SET_ALL, + android.net.NetworkStats.TAG_NONE, NetworkStatsHistory.FIELD_ALL); setSingleUid(uid); } catch (RemoteException e) { Log.w(TAG, e); @@ -364,8 +368,9 @@ public final class NetworkUsageStats implements AutoCloseable { stepUid(); mHistory = null; try { - mHistory = mSession.getHistoryForUid(mTemplate, getUid(), NetworkStats.SET_ALL, - NetworkStats.TAG_NONE, NetworkStatsHistory.FIELD_ALL); + mHistory = mSession.getHistoryForUid(mTemplate, getUid(), + android.net.NetworkStats.SET_ALL, android.net.NetworkStats.TAG_NONE, + NetworkStatsHistory.FIELD_ALL); } catch (RemoteException e) { Log.w(TAG, e); // Leaving mHistory null @@ -405,7 +410,7 @@ public final class NetworkUsageStats implements AutoCloseable { } Bucket bucket = new Bucket(); if (mRecycledSummaryEntry == null) { - mRecycledSummaryEntry = new NetworkStats.Entry(); + mRecycledSummaryEntry = new android.net.NetworkStats.Entry(); } mSummary.getTotal(mRecycledSummaryEntry); fillBucketFromSummaryEntry(bucket); diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index af7c053a417d..2ae018175e57 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -16,18 +16,17 @@ package android.app.usage; -import android.app.usage.NetworkUsageStats.Bucket; +import android.app.usage.NetworkStats.Bucket; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkIdentity; import android.net.NetworkTemplate; import android.os.RemoteException; -import android.os.UserHandle; import android.util.Log; /** * Provides access to network usage history and statistics. Usage data is collected in - * discrete bins of time called 'Buckets'. See {@link NetworkUsageStats.Bucket} for details. + * discrete bins of time called 'Buckets'. See {@link NetworkStats.Bucket} for details. * <p /> * Queries can define a time interval in the form of start and end timestamps (Long.MIN_VALUE and * Long.MAX_VALUE can be used to simulate open ended intervals). All queries (except @@ -37,15 +36,20 @@ import android.util.Log; * <h3> * Summary queries * </h3> + * {@link #querySummaryForDevice} <p /> + * {@link #querySummaryForUser} <p /> + * {@link #querySummary} <p /> * These queries aggregate network usage across the whole interval. Therefore there will be only one * bucket for a particular key and state combination. In case of the user-wide and device-wide * summaries a single bucket containing the totalised network usage is returned. * <h3> * History queries * </h3> + * {@link #queryDetailsForUid} <p /> + * {@link #queryDetails} <p /> * These queries do not aggregate over time but do aggregate over state. Therefore there can be * multiple buckets for a particular key but all Bucket's state is going to be - * {@link NetworkUsageStats.Bucket#STATE_ALL}. + * {@link NetworkStats.Bucket#STATE_ALL}. * <p /> * <b>NOTE:</b> This API requires the permission * {@link android.Manifest.permission#PACKAGE_USAGE_STATS}, which is a system-level permission and @@ -68,7 +72,10 @@ public class NetworkStatsManager { } /** * Query network usage statistics summaries. Result is summarised data usage for the whole - * device. Result is a single Bucket aggregated over time, state and uid. + * device. Result is a single Bucket aggregated over time, state and uid. This means the + * bucket's start and end timestamp are going to be the same as the 'startTime' and 'endTime' + * parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid + * {@link NetworkStats.Bucket#UID_ALL}. * * @param networkType As defined in {@link ConnectivityManager}, e.g. * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} @@ -89,7 +96,7 @@ public class NetworkStatsManager { } Bucket bucket = null; - NetworkUsageStats stats = new NetworkUsageStats(mContext, template, startTime, endTime); + NetworkStats stats = new NetworkStats(mContext, template, startTime, endTime); bucket = stats.getDeviceSummaryForNetwork(startTime, endTime); stats.close(); @@ -99,6 +106,9 @@ public class NetworkStatsManager { /** * Query network usage statistics summaries. Result is summarised data usage for all uids * belonging to calling user. Result is a single Bucket aggregated over time, state and uid. + * This means the bucket's start and end timestamp are going to be the same as the 'startTime' + * and 'endTime' parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid + * {@link NetworkStats.Bucket#UID_ALL}. * * @param networkType As defined in {@link ConnectivityManager}, e.g. * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} @@ -118,8 +128,8 @@ public class NetworkStatsManager { return null; } - NetworkUsageStats stats; - stats = new NetworkUsageStats(mContext, template, startTime, endTime); + NetworkStats stats; + stats = new NetworkStats(mContext, template, startTime, endTime); stats.startSummaryEnumeration(startTime, endTime); stats.close(); @@ -129,7 +139,9 @@ public class NetworkStatsManager { /** * Query network usage statistics summaries. Result filtered to include only uids belonging to * calling user. Result is aggregated over time, hence all buckets will have the same start and - * end timestamps. Not aggregated over state or uid. + * end timestamps. Not aggregated over state or uid. This means buckets' start and end + * timestamps are going to be the same as the 'startTime' and 'endTime' parameters, state and + * uid are going to vary. * * @param networkType As defined in {@link ConnectivityManager}, e.g. * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} @@ -142,15 +154,15 @@ public class NetworkStatsManager { * @return Statistics object or null if permissions are insufficient or error happened during * statistics collection. */ - public NetworkUsageStats querySummary(int networkType, String subscriberId, long startTime, + public NetworkStats querySummary(int networkType, String subscriberId, long startTime, long endTime) throws SecurityException, RemoteException { NetworkTemplate template = createTemplate(networkType, subscriberId); if (template == null) { return null; } - NetworkUsageStats result; - result = new NetworkUsageStats(mContext, template, startTime, endTime); + NetworkStats result; + result = new NetworkStats(mContext, template, startTime, endTime); result.startSummaryEnumeration(startTime, endTime); return result; @@ -158,7 +170,9 @@ public class NetworkStatsManager { /** * Query network usage statistics details. Only usable for uids belonging to calling user. - * Result is aggregated over state but not aggregated over time. + * Result is aggregated over state but not aggregated over time. This means buckets' start and + * end timestamps are going to be between 'startTime' and 'endTime' parameters, state is going + * to be {@link NetworkStats.Bucket#STATE_ALL} and uid the same as the 'uid' parameter. * * @param networkType As defined in {@link ConnectivityManager}, e.g. * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} @@ -172,15 +186,15 @@ public class NetworkStatsManager { * @return Statistics object or null if permissions are insufficient or error happened during * statistics collection. */ - public NetworkUsageStats queryDetailsForUid(int networkType, String subscriberId, + public NetworkStats queryDetailsForUid(int networkType, String subscriberId, long startTime, long endTime, int uid) throws SecurityException, RemoteException { NetworkTemplate template = createTemplate(networkType, subscriberId); if (template == null) { return null; } - NetworkUsageStats result; - result = new NetworkUsageStats(mContext, template, startTime, endTime); + NetworkStats result; + result = new NetworkStats(mContext, template, startTime, endTime); result.startHistoryEnumeration(uid); return result; @@ -188,7 +202,9 @@ public class NetworkStatsManager { /** * Query network usage statistics details. Result filtered to include only uids belonging to - * calling user. Result is aggregated over state but not aggregated over time or uid. + * calling user. Result is aggregated over state but not aggregated over time or uid. This means + * buckets' start and end timestamps are going to be between 'startTime' and 'endTime' + * parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid will vary. * * @param networkType As defined in {@link ConnectivityManager}, e.g. * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} @@ -201,14 +217,14 @@ public class NetworkStatsManager { * @return Statistics object or null if permissions are insufficient or error happened during * statistics collection. */ - public NetworkUsageStats queryDetails(int networkType, String subscriberId, long startTime, + public NetworkStats queryDetails(int networkType, String subscriberId, long startTime, long endTime) throws SecurityException, RemoteException { NetworkTemplate template = createTemplate(networkType, subscriberId); if (template == null) { return null; } - NetworkUsageStats result; - result = new NetworkUsageStats(mContext, template, startTime, endTime); + NetworkStats result; + result = new NetworkStats(mContext, template, startTime, endTime); result.startUserUidEnumeration(); return result; } diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java index f70e07548320..c6f622c8daf3 100644 --- a/core/java/android/hardware/camera2/CameraCaptureSession.java +++ b/core/java/android/hardware/camera2/CameraCaptureSession.java @@ -29,11 +29,11 @@ import java.util.List; * <p>A CameraCaptureSession is created by providing a set of target output surfaces to * {@link CameraDevice#createCaptureSession createCaptureSession}, or by providing an * {@link android.hardware.camera2.params.InputConfiguration} and a set of target output surfaces to - * {@link CameraDevice#createReprocessibleCaptureSession createReprocessibleCaptureSession} for a - * reprocessible capture session. Once created, the session is active until a new session is + * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession} for a + * reprocessable capture session. Once created, the session is active until a new session is * created by the camera device, or the camera device is closed.</p> * - * <p>All capture sessions can be used for capturing images from the camera but only reprocessible + * <p>All capture sessions can be used for capturing images from the camera but only reprocessable * capture sessions can reprocess images captured from the camera in the same session previously. * </p> * @@ -41,7 +41,7 @@ import java.util.List; * it requires configuring the camera device's internal pipelines and allocating memory buffers for * sending images to the desired targets. Therefore the setup is done asynchronously, and * {@link CameraDevice#createCaptureSession createCaptureSession} and - * {@link CameraDevice#createReprocessibleCaptureSession createReprocessibleCaptureSession} will + * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession} will * send the ready-to-use CameraCaptureSession to the provided listener's * {@link CameraCaptureSession.StateCallback#onConfigured onConfigured} callback. If configuration * cannot be completed, then the @@ -156,7 +156,7 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * <p>All capture sessions can be used for capturing images from the camera but only capture * sessions created by - * {@link CameraDevice#createReprocessibleCaptureSession createReprocessibleCaptureSession} + * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession} * can submit reprocess capture requests. Submitting a reprocess request to a regular capture * session will result in an {@link IllegalArgumentException}.</p> * @@ -179,9 +179,9 @@ public abstract class CameraCaptureSession implements AutoCloseable { * @throws IllegalArgumentException if the request targets no Surfaces or Surfaces that are not * configured as outputs for this session; or the request * targets a set of Surfaces that cannot be submitted - * simultaneously in a reprocessible capture session; or a + * simultaneously in a reprocessable capture session; or a * reprocess capture request is submitted in a - * non-reprocessible capture session; or the reprocess capture + * non-reprocessable capture session; or the reprocess capture * request was created with a {@link TotalCaptureResult} from * a different session; or the capture targets a Surface in * the middle of being {@link #prepare prepared}; or the @@ -192,7 +192,7 @@ public abstract class CameraCaptureSession implements AutoCloseable { * @see #setRepeatingRequest * @see #setRepeatingBurst * @see #abortCaptures - * @see CameraDevice#createReprocessibleCaptureSession + * @see CameraDevice#createReprocessableCaptureSession */ public abstract int capture(CaptureRequest request, CaptureCallback listener, Handler handler) throws CameraAccessException; @@ -214,7 +214,7 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * <p>All capture sessions can be used for capturing images from the camera but only capture * sessions created by - * {@link CameraDevice#createReprocessibleCaptureSession createReprocessibleCaptureSession} + * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession} * can submit reprocess capture requests. Submitting a reprocess request to a regular * capture session will result in an {@link IllegalArgumentException}.</p> * @@ -238,9 +238,9 @@ public abstract class CameraCaptureSession implements AutoCloseable { * @throws IllegalArgumentException If the requests target no Surfaces, or the requests target * Surfaces not currently configured as outputs; or one of the * requests targets a set of Surfaces that cannot be submitted - * simultaneously in a reprocessible capture session; or a + * simultaneously in a reprocessable capture session; or a * reprocess capture request is submitted in a - * non-reprocessible capture session; or one of the reprocess + * non-reprocessable capture session; or one of the reprocess * capture requests was created with a * {@link TotalCaptureResult} from a different session; or one * of the captures targets a Surface in the middle of being @@ -425,7 +425,7 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * <p>This method is the fastest way to switch the camera device to a new session with * {@link CameraDevice#createCaptureSession} or - * {@link CameraDevice#createReprocessibleCaptureSession}, at the cost of discarding in-progress + * {@link CameraDevice#createReprocessableCaptureSession}, at the cost of discarding in-progress * work. It must be called before the new session is created. Once all pending requests are * either completed or thrown away, the {@link StateCallback#onReady} callback will be called, * if the session has not been closed. Otherwise, the {@link StateCallback#onClosed} @@ -448,7 +448,7 @@ public abstract class CameraCaptureSession implements AutoCloseable { * @see #setRepeatingRequest * @see #setRepeatingBurst * @see CameraDevice#createCaptureSession - * @see CameraDevice#createReprocessibleCaptureSession + * @see CameraDevice#createReprocessableCaptureSession */ public abstract void abortCaptures() throws CameraAccessException; @@ -459,14 +459,14 @@ public abstract class CameraCaptureSession implements AutoCloseable { * @return {@code true} if the application can submit reprocess capture requests with this * camera capture session. {@code false} otherwise. * - * @see CameraDevice#createReprocessibleCaptureSession + * @see CameraDevice#createReprocessableCaptureSession */ - public abstract boolean isReprocessible(); + public abstract boolean isReprocessable(); /** - * Get the input Surface associated with a reprocessible capture session. + * Get the input Surface associated with a reprocessable capture session. * - * <p>Each reprocessible capture session has an input {@link Surface} where the reprocess + * <p>Each reprocessable capture session has an input {@link Surface} where the reprocess * capture requests get the input images from, rather than the camera device. The application * can create a {@link android.media.ImageWriter} with this input {@link Surface} and use it to * provide input images for reprocess capture requests.</p> @@ -474,7 +474,7 @@ public abstract class CameraCaptureSession implements AutoCloseable { * @return The {@link Surface} where reprocessing capture requests get the input images from. If * this is not a reprocess capture session, {@code null} will be returned. * - * @see CameraDevice#createReprocessibleCaptureSession + * @see CameraDevice#createReprocessableCaptureSession * @see android.media.ImageWriter * @see android.media.ImageReader */ diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 19e821c4db4e..d3b63f9d0f14 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -1239,7 +1239,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * only the input buffer will be used to produce these output stream buffers, and a * new sensor image will not be captured.</p> * <p>For example, for Zero Shutter Lag (ZSL) still capture use case, the input - * stream image format will be OPAQUE, the associated output stream image format + * stream image format will be PRIVATE, the associated output stream image format * should be JPEG.</p> * <p><b>Range of valid values:</b><br></p> * <p>0 or 1.</p> @@ -1326,7 +1326,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR MANUAL_SENSOR}</li> * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING MANUAL_POST_PROCESSING}</li> * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_RAW RAW}</li> - * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING OPAQUE_REPROCESSING}</li> + * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING PRIVATE_REPROCESSING}</li> * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS READ_SENSOR_SETTINGS}</li> * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE BURST_CAPTURE}</li> * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING YUV_REPROCESSING}</li> @@ -1339,7 +1339,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * @see #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR * @see #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING * @see #REQUEST_AVAILABLE_CAPABILITIES_RAW - * @see #REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING + * @see #REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING * @see #REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS * @see #REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE * @see #REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING @@ -1536,12 +1536,12 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <tr> * <td align="left">{@link android.graphics.ImageFormat#PRIVATE }</td> * <td align="left">{@link android.graphics.ImageFormat#JPEG }</td> - * <td align="left">OPAQUE_REPROCESSING</td> + * <td align="left">PRIVATE_REPROCESSING</td> * </tr> * <tr> * <td align="left">{@link android.graphics.ImageFormat#PRIVATE }</td> * <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td> - * <td align="left">OPAQUE_REPROCESSING</td> + * <td align="left">PRIVATE_REPROCESSING</td> * </tr> * <tr> * <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td> @@ -1556,8 +1556,9 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * </tbody> * </table> * <p>PRIVATE refers to a device-internal format that is not directly application-visible. A - * PRIVATE input surface can be acquired by {@link android.media.ImageReader#newOpaqueInstance }.</p> - * <p>For a OPAQUE_REPROCESSING-capable camera device, using the PRIVATE format as either input + * PRIVATE input surface can be acquired by {@link android.media.ImageReader#newInstance } + * with {@link android.graphics.ImageFormat#PRIVATE } as the format.</p> + * <p>For a PRIVATE_REPROCESSING-capable camera device, using the PRIVATE format as either input * or output will never hurt maximum frame rate (i.e. {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration getOutputStallDuration(ImageFormat.PRIVATE, size)} is always 0),</p> * <p>Attempting to configure an input stream with output streams not * listed as available in this map is not valid.</p> @@ -2647,8 +2648,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * formats/sizes combination.</p> * <p>If this key reports 0, it means a reprocess request doesn't introduce any glitch to the * ongoing camera repeating request outputs, as if this reprocess request is never issued.</p> - * <p>This key is supported if the camera device supports OPAQUE or YUV reprocessing ( - * i.e. {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains OPAQUE_REPROCESSING or + * <p>This key is supported if the camera device supports PRIVATE or YUV reprocessing ( + * i.e. {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains PRIVATE_REPROCESSING or * YUV_REPROCESSING).</p> * <p><b>Units</b>: Number of frames.</p> * <p><b>Range of valid values:</b><br> diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java index 4af7daff2057..dad4fb651455 100644 --- a/core/java/android/hardware/camera2/CameraDevice.java +++ b/core/java/android/hardware/camera2/CameraDevice.java @@ -100,7 +100,7 @@ public abstract class CameraDevice implements AutoCloseable { * means maximizing image quality without compromising preview frame rate. * AE/AWB/AF should be on auto mode. * This template is guaranteed to be supported on camera devices that support the - * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING OPAQUE_REPROCESSING} + * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING PRIVATE_REPROCESSING} * capability or the * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING YUV_REPROCESSING} * capability. @@ -409,15 +409,15 @@ public abstract class CameraDevice implements AutoCloseable { CameraCaptureSession.StateCallback callback, Handler handler) throws CameraAccessException; /** - * Create a new reprocessible camera capture session by providing the desired reprocessing + * Create a new reprocessable camera capture session by providing the desired reprocessing * input Surface configuration and the target output set of Surfaces to the camera device. * * <p>If a camera device supports YUV reprocessing - * ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING}) or OPAQUE + * ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING}) or PRIVATE * reprocessing - * ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING}), besides + * ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING}), besides * the capture session created via {@link #createCaptureSession createCaptureSession}, the - * application can also create a reprocessible capture session to submit reprocess capture + * application can also create a reprocessable capture session to submit reprocess capture * requests in addition to regular capture requests. A reprocess capture request takes the next * available buffer from the session's input Surface, and sends it through the camera device's * processing pipeline again, to produce buffers for the request's target output Surfaces. No @@ -426,7 +426,7 @@ public abstract class CameraDevice implements AutoCloseable { * directly (e.g. for Zero-Shutter-Lag use case) or indirectly (e.g. combining multiple output * images).</p> * - * <p>The active reprocessible capture session determines an input {@link Surface} and the set + * <p>The active reprocessable capture session determines an input {@link Surface} and the set * of potential output Surfaces for the camera devices for each capture request. The application * can use {@link #createCaptureRequest createCaptureRequest} to create regular capture requests * to capture new images from the camera device, and use {@link #createReprocessCaptureRequest @@ -448,30 +448,30 @@ public abstract class CameraDevice implements AutoCloseable { * they cannot be used as targets for a reprocessing request.</p> * * <p>Since the application cannot access {@link android.graphics.ImageFormat#PRIVATE} images - * directly, an output Surface created by {@link android.media.ImageReader#newOpaqueInstance} - * will be considered as intended to be used for reprocessing input and thus the - * {@link android.media.ImageReader} size must match one of the supported input sizes for - * {@link android.graphics.ImageFormat#PRIVATE} format. Otherwise, creating a reprocessible - * capture session will fail.</p> + * directly, an output Surface created by {@link android.media.ImageReader#newInstance} with + * {@link android.graphics.ImageFormat#PRIVATE} as the format will be considered as intended to + * be used for reprocessing input and thus the {@link android.media.ImageReader} size must + * match one of the supported input sizes for {@link android.graphics.ImageFormat#PRIVATE} + * format. Otherwise, creating a reprocessable capture session will fail.</p> * * <p>The guaranteed stream configurations listed in * {@link #createCaptureSession createCaptureSession} are also guaranteed to work for - * {@link #createReprocessibleCaptureSession createReprocessibleCaptureSession}. In addition, - * the configurations in the tables below are also guaranteed for creating a reprocessible - * capture session if the camera device supports YUV reprocessing or OPAQUE reprocessing. - * However, not all output targets used to create a reprocessible session may be used in a + * {@link #createReprocessableCaptureSession createReprocessableCaptureSession}. In addition, + * the configurations in the tables below are also guaranteed for creating a reprocessable + * capture session if the camera device supports YUV reprocessing or PRIVATE reprocessing. + * However, not all output targets used to create a reprocessable session may be used in a * {@link CaptureRequest} simultaneously. The guaranteed output targets that can be included * in a {@link CaptureRequest} simultaneously are listed in the tables under * {@link #createCaptureSession createCaptureSession}. For example, with a FULL-capability * ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} {@code == } - * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL}) device that supports OPAQUE - * reprocessing, an application can create a reprocessible capture session with 1 input, + * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL}) device that supports PRIVATE + * reprocessing, an application can create a reprocessable capture session with 1 input, * ({@code PRIV}, {@code MAXIMUM}), and 3 outputs, ({@code PRIV}, {@code MAXIMUM}), * ({@code PRIV}, {@code PREVIEW}), and ({@code YUV}, {@code MAXIMUM}). However, it's not * guaranteed that an application can submit a regular or reprocess capture with ({@code PRIV}, * {@code MAXIMUM}) and ({@code YUV}, {@code MAXIMUM}) outputs based on the table listed under * {@link #createCaptureSession createCaptureSession}. In other words, use the tables below to - * determine the guaranteed stream configurations for creating a reprocessible capture session, + * determine the guaranteed stream configurations for creating a reprocessable capture session, * and use the tables under {@link #createCaptureSession createCaptureSession} to determine the * guaranteed output targets that can be submitted in a regular or reprocess * {@link CaptureRequest} simultaneously.</p> @@ -482,12 +482,12 @@ public abstract class CameraDevice implements AutoCloseable { * * <p>Limited-capability ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED}) devices - * support at least the following stream combinations for creating a reprocessible capture + * support at least the following stream combinations for creating a reprocessable capture * session in addition to those listed in {@link #createCaptureSession createCaptureSession} for * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED} devices: * * <table> - * <tr><th colspan="11">LIMITED-level additional guaranteed configurations for creating a reprocessible capture session<br>({@code PRIV} input is guaranteed only if OPAQUE reprocessing is supported. {@code YUV} input is guaranteed only if YUV reprocessing is supported)</th></tr> + * <tr><th colspan="11">LIMITED-level additional guaranteed configurations for creating a reprocessable capture session<br>({@code PRIV} input is guaranteed only if PRIVATE reprocessing is supported. {@code YUV} input is guaranteed only if YUV reprocessing is supported)</th></tr> * <tr><th colspan="2" id="rb">Input</th><th colspan="2" id="rb">Target 1</th><th colspan="2" id="rb">Target 2</th><th colspan="2" id="rb">Target 3</th><th colspan="2" id="rb">Target 4</th><th rowspan="2">Sample use case(s)</th> </tr> * <tr><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th></tr> * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code JPEG}</td><td id="rb">{@code MAXIMUM}</td> <td></td><td id="rb"></td> <td></td><td id="rb"></td> <td>No-viewfinder still image reprocessing.</td> </tr> @@ -499,12 +499,12 @@ public abstract class CameraDevice implements AutoCloseable { * * <p>FULL-capability ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL}) devices - * support at least the following stream combinations for creating a reprocessible capture + * support at least the following stream combinations for creating a reprocessable capture * session in addition to those for * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED} devices: * * <table> - * <tr><th colspan="11">FULL-capability additional guaranteed configurations for creating a reprocessible capture session<br>({@code PRIV} input is guaranteed only if OPAQUE reprocessing is supported. {@code YUV} input is guaranteed only if YUV reprocessing is supported)</th></tr> + * <tr><th colspan="11">FULL-capability additional guaranteed configurations for creating a reprocessable capture session<br>({@code PRIV} input is guaranteed only if PRIVATE reprocessing is supported. {@code YUV} input is guaranteed only if YUV reprocessing is supported)</th></tr> * <tr><th colspan="2" id="rb">Input</th><th colspan="2" id="rb">Target 1</th><th colspan="2" id="rb">Target 2</th><th colspan="2" id="rb">Target 3</th><th colspan="2" id="rb">Target 4</th><th rowspan="2">Sample use case(s)</th> </tr> * <tr><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th></tr> * <tr> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td></td><td id="rb"></td> <td></td><td id="rb"></td> <td>Maximum-resolution multi-frame image fusion in-app processing with regular preview.</td> </tr> @@ -520,12 +520,12 @@ public abstract class CameraDevice implements AutoCloseable { * * <p>RAW-capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES} includes * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_RAW RAW}) devices additionally support - * at least the following stream combinations for creating a reprocessible capture session + * at least the following stream combinations for creating a reprocessable capture session * on both {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL} and * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED} devices * * <table> - * <tr><th colspan="11">RAW-capability additional guaranteed configurations for creating a reprocessible capture session<br>({@code PRIV} input is guaranteed only if OPAQUE reprocessing is supported. {@code YUV} input is guaranteed only if YUV reprocessing is supported)</th></tr> + * <tr><th colspan="11">RAW-capability additional guaranteed configurations for creating a reprocessable capture session<br>({@code PRIV} input is guaranteed only if PRIVATE reprocessing is supported. {@code YUV} input is guaranteed only if YUV reprocessing is supported)</th></tr> * <tr><th colspan="2" id="rb">Input</th><th colspan="2" id="rb">Target 1</th><th colspan="2" id="rb">Target 2</th><th colspan="2" id="rb">Target 3</th><th colspan="2" id="rb">Target 4</th><th rowspan="2">Sample use case(s)</th> </tr> * <tr><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th></tr> * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code RAW}</td><td id="rb">{@code MAXIMUM}</td> <td></td><td id="rb"></td> <td>Mutually exclusive ZSL in-app processing and DNG capture.</td> </tr> @@ -560,7 +560,7 @@ public abstract class CameraDevice implements AutoCloseable { * @see android.media.ImageWriter * @see android.media.ImageReader */ - public abstract void createReprocessibleCaptureSession(InputConfiguration inputConfig, + public abstract void createReprocessableCaptureSession(InputConfiguration inputConfig, List<Surface> outputs, CameraCaptureSession.StateCallback callback, Handler handler) throws CameraAccessException; @@ -602,8 +602,7 @@ public abstract class CameraDevice implements AutoCloseable { * {@link CameraCaptureSession}'s input {@link Surface} to all output {@link Surface Surfaces} * included in the reprocess capture request. The reprocess input images must be generated from * one or multiple output images captured from the same camera device. The application can - * provide input images to camera device via - * {{@link android.media.ImageWriter#queueInputImage ImageWriter#queueInputImage}}. + * provide input images to camera device via {@link android.media.ImageWriter#queueInputImage}. * The application must use the capture result of one of those output images to create a * reprocess capture request so that the camera device can use the information to achieve * optimal reprocess image quality. @@ -618,7 +617,7 @@ public abstract class CameraDevice implements AutoCloseable { * * @see CaptureRequest.Builder * @see TotalCaptureResult - * @see CameraDevice#createReprocessibleCaptureSession + * @see CameraDevice#createReprocessableCaptureSession * @see android.media.ImageWriter */ public abstract CaptureRequest.Builder createReprocessCaptureRequest( diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index 9327f009d780..d99cce717e4f 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -556,7 +556,7 @@ public final class CameraManager { * {@link CameraManager#registerTorchCallback} to be notified of such status changes. * </p> * - * @see registerTorchCallback + * @see #registerTorchCallback */ public static abstract class TorchCallback { /** diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index ca9439bfa0c5..6baa6602f768 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -388,8 +388,8 @@ public abstract class CameraMetadata<TKey> { * <li>{@link CaptureRequest#TONEMAP_CURVE android.tonemap.curve}</li> * <li>{@link CaptureRequest#TONEMAP_MODE android.tonemap.mode}</li> * <li>{@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}</li> - * <li>android.tonemap.gamma</li> - * <li>android.tonemap.presetCurve</li> + * <li>{@link CaptureRequest#TONEMAP_GAMMA android.tonemap.gamma}</li> + * <li>{@link CaptureRequest#TONEMAP_PRESET_CURVE android.tonemap.presetCurve}</li> * </ul> * </li> * <li> @@ -429,8 +429,10 @@ public abstract class CameraMetadata<TKey> { * @see CaptureRequest#SHADING_MODE * @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE * @see CaptureRequest#TONEMAP_CURVE + * @see CaptureRequest#TONEMAP_GAMMA * @see CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS * @see CaptureRequest#TONEMAP_MODE + * @see CaptureRequest#TONEMAP_PRESET_CURVE * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES */ public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2; @@ -472,7 +474,7 @@ public abstract class CameraMetadata<TKey> { * <li>{@link android.graphics.ImageFormat#PRIVATE } will be reprocessable into both * {@link android.graphics.ImageFormat#YUV_420_888 } and * {@link android.graphics.ImageFormat#JPEG } formats.</li> - * <li>The maximum available resolution for OPAQUE streams + * <li>The maximum available resolution for PRIVATE streams * (both input/output) will match the maximum available * resolution of JPEG streams.</li> * <li>Static metadata {@link CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL android.reprocess.maxCaptureStall}.</li> @@ -492,7 +494,7 @@ public abstract class CameraMetadata<TKey> { * @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES */ - public static final int REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING = 4; + public static final int REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING = 4; /** * <p>The camera device supports accurately reporting the sensor settings for many of @@ -565,7 +567,7 @@ public abstract class CameraMetadata<TKey> { /** * <p>The camera device supports the YUV_420_888 reprocessing use case, similar as - * OPAQUE_REPROCESSING, This capability requires the camera device to support the + * PRIVATE_REPROCESSING, This capability requires the camera device to support the * following:</p> * <ul> * <li>One input stream is supported, that is, <code>{@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} == 1</code>.</li> @@ -2185,22 +2187,26 @@ public abstract class CameraMetadata<TKey> { public static final int TONEMAP_MODE_HIGH_QUALITY = 2; /** - * <p>Use the gamma value specified in android.tonemap.gamma to peform + * <p>Use the gamma value specified in {@link CaptureRequest#TONEMAP_GAMMA android.tonemap.gamma} to peform * tonemapping.</p> * <p>All color enhancement and tonemapping must be disabled, except - * for applying the tonemapping curve specified by android.tonemap.gamma.</p> + * for applying the tonemapping curve specified by {@link CaptureRequest#TONEMAP_GAMMA android.tonemap.gamma}.</p> * <p>Must not slow down frame rate relative to raw sensor output.</p> + * + * @see CaptureRequest#TONEMAP_GAMMA * @see CaptureRequest#TONEMAP_MODE */ public static final int TONEMAP_MODE_GAMMA_VALUE = 3; /** * <p>Use the preset tonemapping curve specified in - * android.tonemap.presetCurve to peform tonemapping.</p> + * {@link CaptureRequest#TONEMAP_PRESET_CURVE android.tonemap.presetCurve} to peform tonemapping.</p> * <p>All color enhancement and tonemapping must be disabled, except * for applying the tonemapping curve specified by - * android.tonemap.presetCurve.</p> + * {@link CaptureRequest#TONEMAP_PRESET_CURVE android.tonemap.presetCurve}.</p> * <p>Must not slow down frame rate relative to raw sensor output.</p> + * + * @see CaptureRequest#TONEMAP_PRESET_CURVE * @see CaptureRequest#TONEMAP_MODE */ public static final int TONEMAP_MODE_PRESET_CURVE = 4; diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index ab6ce910f833..3ec11b71fdf9 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -158,9 +158,9 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> private final HashSet<Surface> mSurfaceSet; private final CameraMetadataNative mSettings; private boolean mIsReprocess; - // Each reprocess request must be tied to a reprocessible session ID. + // Each reprocess request must be tied to a reprocessable session ID. // Valid only for reprocess requests (mIsReprocess == true). - private int mReprocessibleSessionId; + private int mReprocessableSessionId; private Object mUserTag; @@ -173,7 +173,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> mSettings = new CameraMetadataNative(); mSurfaceSet = new HashSet<Surface>(); mIsReprocess = false; - mReprocessibleSessionId = CameraCaptureSession.SESSION_ID_NONE; + mReprocessableSessionId = CameraCaptureSession.SESSION_ID_NONE; } /** @@ -186,7 +186,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> mSettings = new CameraMetadataNative(source.mSettings); mSurfaceSet = (HashSet<Surface>) source.mSurfaceSet.clone(); mIsReprocess = source.mIsReprocess; - mReprocessibleSessionId = source.mReprocessibleSessionId; + mReprocessableSessionId = source.mReprocessableSessionId; mUserTag = source.mUserTag; } @@ -199,30 +199,30 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * @param isReprocess Indicates whether to create a reprocess capture request. {@code true} * to create a reprocess capture request. {@code false} to create a regular * capture request. - * @param reprocessibleSessionId The ID of the camera capture session this capture is created + * @param reprocessableSessionId The ID of the camera capture session this capture is created * for. This is used to validate if the application submits a * reprocess capture request to the same session where * the {@link TotalCaptureResult}, used to create the reprocess * capture, came from. * * @throws IllegalArgumentException If creating a reprocess capture request with an invalid - * reprocessibleSessionId. + * reprocessableSessionId. * * @see CameraDevice#createReprocessCaptureRequest */ private CaptureRequest(CameraMetadataNative settings, boolean isReprocess, - int reprocessibleSessionId) { + int reprocessableSessionId) { mSettings = CameraMetadataNative.move(settings); mSurfaceSet = new HashSet<Surface>(); mIsReprocess = isReprocess; if (isReprocess) { - if (reprocessibleSessionId == CameraCaptureSession.SESSION_ID_NONE) { + if (reprocessableSessionId == CameraCaptureSession.SESSION_ID_NONE) { throw new IllegalArgumentException("Create a reprocess capture request with an " + - "invalid session ID: " + reprocessibleSessionId); + "invalid session ID: " + reprocessableSessionId); } - mReprocessibleSessionId = reprocessibleSessionId; + mReprocessableSessionId = reprocessableSessionId; } else { - mReprocessibleSessionId = CameraCaptureSession.SESSION_ID_NONE; + mReprocessableSessionId = CameraCaptureSession.SESSION_ID_NONE; } } @@ -307,20 +307,20 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> } /** - * Get the reprocessible session ID this reprocess capture request is associated with. + * Get the reprocessable session ID this reprocess capture request is associated with. * - * @return the reprocessible session ID this reprocess capture request is associated with + * @return the reprocessable session ID this reprocess capture request is associated with * * @throws IllegalStateException if this capture request is not a reprocess capture request. * @hide */ - public int getReprocessibleSessionId() { + public int getReprocessableSessionId() { if (mIsReprocess == false || - mReprocessibleSessionId == CameraCaptureSession.SESSION_ID_NONE) { - throw new IllegalStateException("Getting the reprocessible session ID for a "+ + mReprocessableSessionId == CameraCaptureSession.SESSION_ID_NONE) { + throw new IllegalStateException("Getting the reprocessable session ID for a "+ "non-reprocess capture request is illegal."); } - return mReprocessibleSessionId; + return mReprocessableSessionId; } /** @@ -346,7 +346,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> && mSurfaceSet.equals(other.mSurfaceSet) && mSettings.equals(other.mSettings) && mIsReprocess == other.mIsReprocess - && mReprocessibleSessionId == other.mReprocessibleSessionId; + && mReprocessableSessionId == other.mReprocessableSessionId; } @Override @@ -395,7 +395,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> } mIsReprocess = (in.readInt() == 0) ? false : true; - mReprocessibleSessionId = CameraCaptureSession.SESSION_ID_NONE; + mReprocessableSessionId = CameraCaptureSession.SESSION_ID_NONE; } @Override @@ -450,19 +450,19 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * @param reprocess Indicates whether to create a reprocess capture request. {@code true} * to create a reprocess capture request. {@code false} to create a regular * capture request. - * @param reprocessibleSessionId The ID of the camera capture session this capture is + * @param reprocessableSessionId The ID of the camera capture session this capture is * created for. This is used to validate if the application * submits a reprocess capture request to the same session * where the {@link TotalCaptureResult}, used to create the * reprocess capture, came from. * * @throws IllegalArgumentException If creating a reprocess capture request with an invalid - * reprocessibleSessionId. + * reprocessableSessionId. * @hide */ public Builder(CameraMetadataNative template, boolean reprocess, - int reprocessibleSessionId) { - mRequest = new CaptureRequest(template, reprocess, reprocessibleSessionId); + int reprocessableSessionId) { + mRequest = new CaptureRequest(template, reprocess, reprocessableSessionId); } /** @@ -1275,7 +1275,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * <p>This control (except for MANUAL) is only effective if * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p> * <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} - * contains OPAQUE_REPROCESSING or YUV_REPROCESSING. MANUAL will be supported if + * contains PRIVATE_REPROCESSING or YUV_REPROCESSING. MANUAL will be supported if * {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_SENSOR. Other intent values are * always supported.</p> * <p><b>Possible values:</b> diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index 3dc8970a1c8a..d931a76303c3 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -1698,7 +1698,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <p>This control (except for MANUAL) is only effective if * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p> * <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} - * contains OPAQUE_REPROCESSING or YUV_REPROCESSING. MANUAL will be supported if + * contains PRIVATE_REPROCESSING or YUV_REPROCESSING. MANUAL will be supported if * {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_SENSOR. Other intent values are * always supported.</p> * <p><b>Possible values:</b> diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java index dff62270b05a..d08c52b5550a 100644 --- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java @@ -153,10 +153,10 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession { Handler handler) throws CameraAccessException { if (request == null) { throw new IllegalArgumentException("request must not be null"); - } else if (request.isReprocess() && !isReprocessible()) { + } else if (request.isReprocess() && !isReprocessable()) { throw new IllegalArgumentException("this capture session cannot handle reprocess " + "requests"); - } else if (request.isReprocess() && request.getReprocessibleSessionId() != mId) { + } else if (request.isReprocess() && request.getReprocessableSessionId() != mId) { throw new IllegalArgumentException("capture request was created for another session"); } @@ -184,10 +184,10 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession { for (CaptureRequest request : requests) { if (request.isReprocess()) { - if (!isReprocessible()) { + if (!isReprocessable()) { throw new IllegalArgumentException("This capture session cannot handle " + "reprocess requests"); - } else if (request.getReprocessibleSessionId() != mId) { + } else if (request.getReprocessableSessionId() != mId) { throw new IllegalArgumentException("Capture request was created for another " + "session"); } @@ -293,7 +293,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession { } @Override - public boolean isReprocessible() { + public boolean isReprocessable() { return mInput != null; } diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index e84b46abf13a..4508dc831841 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -480,16 +480,16 @@ public class CameraDeviceImpl extends CameraDevice { } @Override - public void createReprocessibleCaptureSession(InputConfiguration inputConfig, + public void createReprocessableCaptureSession(InputConfiguration inputConfig, List<Surface> outputs, CameraCaptureSession.StateCallback callback, Handler handler) throws CameraAccessException { if (DEBUG) { - Log.d(TAG, "createReprocessibleCaptureSession"); + Log.d(TAG, "createReprocessableCaptureSession"); } if (inputConfig == null) { throw new IllegalArgumentException("inputConfig cannot be null when creating a " + - "reprocessible capture session"); + "reprocessable capture session"); } List<OutputConfiguration> outConfigurations = new ArrayList<>(outputs.size()); for (Surface surface : outputs) { diff --git a/core/java/android/hardware/camera2/params/InputConfiguration.java b/core/java/android/hardware/camera2/params/InputConfiguration.java index dea1c5c885d5..0c642cf2b6f9 100644 --- a/core/java/android/hardware/camera2/params/InputConfiguration.java +++ b/core/java/android/hardware/camera2/params/InputConfiguration.java @@ -19,11 +19,11 @@ package android.hardware.camera2.params; import android.hardware.camera2.utils.HashCodeHelpers; /** - * Immutable class to store an input configuration that is used to create a reprocessible capture + * Immutable class to store an input configuration that is used to create a reprocessable capture * session. * - * @see CameraDevice#createReprocessibleCaptureSession - * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP + * @see android.hardware.camera2.CameraDevice#createReprocessableCaptureSession + * @see android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP */ public final class InputConfiguration { diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index 657beeecfa2d..338bd7620894 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -32,7 +32,7 @@ import android.os.RemoteException; import android.os.UserHandle; import android.provider.Settings; import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback; -import android.security.AndroidKeyStoreProvider; +import android.security.keystore.AndroidKeyStoreProvider; import android.util.Log; import android.util.Slog; diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 0b55998d5d3f..1cc2d334c477 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -476,8 +476,18 @@ public final class StrictMode { } /** - * Enable detection of mismatches between defined resource types + * Enables detection of mismatches between defined resource types * and getter calls. + * <p> + * This helps detect accidental type mismatches and potentially + * expensive type conversions when obtaining typed resources. + * <p> + * For example, a strict mode violation would be thrown when + * calling {@link android.content.res.TypedArray#getInt(int, int)} + * on an index that contains a String-type resource. If the string + * value can be parsed as an integer, this method call will return + * a value without crashing; however, the developer should format + * the resource as an integer to avoid unnecessary type conversion. */ public Builder detectResourceMismatches() { return enable(DETECT_RESOURCE_MISMATCH); diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index 85b22fbb355b..d70712ac327b 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -717,6 +717,14 @@ public class TextureView extends View { if (surfaceTexture == null) { throw new NullPointerException("surfaceTexture must not be null"); } + if (surfaceTexture == mSurface) { + throw new IllegalArgumentException("Trying to setSurfaceTexture to " + + "the same SurfaceTexture that's already set."); + } + if (surfaceTexture.isReleased()) { + throw new IllegalArgumentException("Cannot setSurfaceTexture to a " + + "released SurfaceTexture"); + } if (mSurface != null) { mSurface.release(); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 1cbd88612867..4f2a3fabbbaa 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2015,6 +2015,7 @@ public final class ViewRootImpl implements ViewParent, mLastWasImTarget = imTarget; InputMethodManager imm = InputMethodManager.peekInstance(); if (imm != null && imTarget) { + imm.startGettingWindowFocus(mView); imm.onWindowFocus(mView, mView.findFocus(), mWindowAttributes.softInputMode, !mHasHadWindowFocus, mWindowAttributes.flags); @@ -3321,6 +3322,10 @@ public final class ViewRootImpl implements ViewParent, InputMethodManager imm = InputMethodManager.peekInstance(); if (mView != null) { + if (hasWindowFocus && imm != null && mLastWasImTarget && + !isInLocalFocusMode()) { + imm.startGettingWindowFocus(mView); + } mAttachInfo.mKeyDispatchState.reset(); mView.dispatchWindowFocusChanged(hasWindowFocus); mAttachInfo.mTreeObserver.dispatchOnWindowFocusChange(hasWindowFocus); diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index c78514959ff2..42e6766a5e9c 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -1011,6 +1011,10 @@ public class AccessibilityNodeInfo implements Parcelable { public void addAction(AccessibilityAction action) { enforceNotSealed(); + addActionUnchecked(action); + } + + private void addActionUnchecked(AccessibilityAction action) { if (action == null) { return; } @@ -2846,9 +2850,9 @@ public class AccessibilityNodeInfo implements Parcelable { addLegacyStandardActions(legacyStandardActions); final int nonLegacyActionCount = actionCount - Integer.bitCount(legacyStandardActions); for (int i = 0; i < nonLegacyActionCount; i++) { - AccessibilityAction action = new AccessibilityAction( + final AccessibilityAction action = new AccessibilityAction( parcel.readInt(), parcel.readCharSequence()); - addAction(action); + addActionUnchecked(action); } } diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 1fb791cf87ad..568e16074daa 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -281,7 +281,12 @@ public final class InputMethodManager { boolean mFullscreenMode; // ----------------------------------------------------------- - + + /** + * This is the root view of the overall window that currently has input + * method focus. + */ + View mCurRootView; /** * This is the view that should currently be served by an input method, * regardless of the state of setting that up. @@ -801,6 +806,7 @@ public final class InputMethodManager { * Disconnect any existing input connection, clearing the served view. */ void finishInputLocked() { + mCurRootView = null; mNextServedView = null; if (mServedView != null) { if (DEBUG) Log.v(TAG, "FINISH INPUT: " + mServedView); @@ -1284,9 +1290,10 @@ public final class InputMethodManager { void focusInLocked(View view) { if (DEBUG) Log.v(TAG, "focusIn: " + view); - if (!view.hasWindowFocus()) { - // This is a request from a window that doesn't have window focus, so ignore it. - if (DEBUG) Log.v(TAG, "Not focused window, ignoring"); + if (mCurRootView != view.getRootView()) { + // This is a request from a window that isn't in the window with + // IME focus, so ignore it. + if (DEBUG) Log.v(TAG, "Not IME target window, ignoring"); return; } @@ -1303,9 +1310,16 @@ public final class InputMethodManager { if (DEBUG) Log.v(TAG, "focusOut: " + view + " mServedView=" + mServedView + " winFocus=" + view.hasWindowFocus()); - if (mServedView == view && view.hasWindowFocus()) { - mNextServedView = null; - scheduleCheckFocusLocked(view); + if (mServedView != view) { + // The following code would auto-hide the IME if we end up + // with no more views with focus. This can happen, however, + // whenever we go into touch mode, so it ends up hiding + // at times when we don't really want it to. For now it + // seems better to just turn it all off. + if (false && view.hasWindowFocus()) { + mNextServedView = null; + scheduleCheckFocusLocked(view); + } } } } @@ -1428,6 +1442,13 @@ public final class InputMethodManager { } } + /** @hide */ + public void startGettingWindowFocus(View rootView) { + synchronized (mH) { + mCurRootView = rootView; + } + } + /** * Report the current selection range. * @@ -2135,6 +2156,7 @@ public final class InputMethodManager { + " mBindSequence=" + mBindSequence + " mCurId=" + mCurId); p.println(" mCurMethod=" + mCurMethod); + p.println(" mCurRootView=" + mCurRootView); p.println(" mServedView=" + mServedView); p.println(" mNextServedView=" + mNextServedView); p.println(" mServedConnecting=" + mServedConnecting); diff --git a/core/java/android/webkit/FindActionModeCallback.java b/core/java/android/webkit/FindActionModeCallback.java index 6fef2d6ce66f..ab6a2f91f95e 100644 --- a/core/java/android/webkit/FindActionModeCallback.java +++ b/core/java/android/webkit/FindActionModeCallback.java @@ -154,6 +154,7 @@ public class FindActionModeCallback implements ActionMode.Callback, TextWatcher, } public void showSoftInput() { + mInput.startGettingWindowFocus(mEditText.getRootView()); mInput.focusIn(mEditText); mInput.showSoftInput(mEditText, 0); } diff --git a/core/java/android/webkit/WebResourceError.java b/core/java/android/webkit/WebResourceError.java index 11f1b6f17566..90693f373e1b 100644 --- a/core/java/android/webkit/WebResourceError.java +++ b/core/java/android/webkit/WebResourceError.java @@ -36,8 +36,11 @@ public abstract class WebResourceError { * and thus can be used for communicating the problem to the user. * * @return The description of the error + * + * Will become abstract after updated WebView.apk will be submitted + * into the Android tree. */ - public abstract CharSequence getDescription(); + public CharSequence getDescription() { return ""; } /** * This class can not be subclassed by applications. diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 55f4562afa92..a1194f7dfa95 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -209,6 +209,10 @@ public class Editor { // Set when this TextView gained focus with some text selected. Will start selection mode. boolean mCreatedWithASelection; + boolean mDoubleTap = false; + + private Runnable mSelectionModeWithoutSelectionRunnable; + // The span controller helps monitoring the changes to which the Editor needs to react: // - EasyEditSpans, for which we have some UI to display on attach and on hide // - SelectionSpans, for which we need to call updateSelection if an IME is attached @@ -349,6 +353,11 @@ public class Editor { mTextView.removeCallbacks(mShowSuggestionRunnable); } + // Cancel the single tap delayed runnable. + if (mSelectionModeWithoutSelectionRunnable != null) { + mTextView.removeCallbacks(mSelectionModeWithoutSelectionRunnable); + } + destroyDisplayListsData(); if (mSpellChecker != null) { @@ -1806,6 +1815,7 @@ public class Editor { // When the cursor moves, the word that was typed may need spell check mSpellChecker.onSelectionChanged(); } + if (!extractedTextModeWillBeStarted()) { if (isCursorInsideEasyCorrectionSpan()) { mShowSuggestionRunnable = new Runnable() { @@ -3721,10 +3731,28 @@ public class Editor { public void show() { super.show(); - final long durationSinceLastCutCopyOrTextChanged = + final long durationSinceCutOrCopy = SystemClock.uptimeMillis() - TextView.sLastCutCopyOrTextChangedTime; - if (durationSinceLastCutCopyOrTextChanged < RECENT_CUT_COPY_DURATION) { - startSelectionActionModeWithoutSelection(); + + // Cancel the single tap delayed runnable. + if (mDoubleTap && mSelectionModeWithoutSelectionRunnable != null) { + mTextView.removeCallbacks(mSelectionModeWithoutSelectionRunnable); + } + + // Prepare and schedule the single tap runnable to run exactly after the double tap + // timeout has passed. + if (!mDoubleTap && (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION)) { + if (mSelectionModeWithoutSelectionRunnable == null) { + mSelectionModeWithoutSelectionRunnable = new Runnable() { + public void run() { + startSelectionActionModeWithoutSelection(); + } + }; + } + + mTextView.postDelayed( + mSelectionModeWithoutSelectionRunnable, + ViewConfiguration.getDoubleTapTimeout() + 1); } hideAfterDelay(); @@ -4113,6 +4141,10 @@ public class Editor { public void show() { getHandle().show(); + + if (mSelectionModifierCursorController != null) { + mSelectionModifierCursorController.hide(); + } } public void hide() { @@ -4154,8 +4186,6 @@ public class Editor { // The offsets of that last touch down event. Remembered to start selection there. private int mMinTouchOffset, mMaxTouchOffset; - // Double tap detection - private long mPreviousTapUpTime = 0; private float mDownPositionX, mDownPositionY; private boolean mGestureStayedInTapRegion; @@ -4237,8 +4267,7 @@ public class Editor { // Double tap detection if (mGestureStayedInTapRegion) { - long duration = SystemClock.uptimeMillis() - mPreviousTapUpTime; - if (duration <= ViewConfiguration.getDoubleTapTimeout()) { + if (mDoubleTap) { final float deltaX = x - mDownPositionX; final float deltaY = y - mDownPositionY; final float distanceSquared = deltaX * deltaX + deltaY * deltaY; @@ -4347,7 +4376,6 @@ public class Editor { break; case MotionEvent.ACTION_UP: - mPreviousTapUpTime = SystemClock.uptimeMillis(); if (mDragAcceleratorActive) { // No longer dragging to select text, let the parent intercept events. mTextView.getParent().requestDisallowInterceptTouchEvent(false); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 3df218e6b4d2..5acd79ff761b 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -599,6 +599,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private final Paint mHighlightPaint; private boolean mHighlightPathBogus = true; + private boolean mFirstTouch = false; + private long mLastTouchUpTime = 0; + // Although these fields are specific to editable text, they are not added to Editor because // they are defined by the TextView's style and are theme-dependent. int mCursorDrawableRes; @@ -8279,6 +8282,22 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener public boolean onTouchEvent(MotionEvent event) { final int action = event.getActionMasked(); + if (mEditor != null && action == MotionEvent.ACTION_DOWN) { + // Detect double tap and inform the Editor. + if (mFirstTouch && (SystemClock.uptimeMillis() - mLastTouchUpTime) <= + ViewConfiguration.getDoubleTapTimeout()) { + mEditor.mDoubleTap = true; + mFirstTouch = false; + } else { + mEditor.mDoubleTap = false; + mFirstTouch = true; + } + } + + if (action == MotionEvent.ACTION_UP) { + mLastTouchUpTime = SystemClock.uptimeMillis(); + } + if (mEditor != null) { mEditor.onTouchEvent(event); diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.java b/core/java/com/android/internal/statusbar/StatusBarIcon.java index 4693d4b7c840..e0792cb37646 100644 --- a/core/java/com/android/internal/statusbar/StatusBarIcon.java +++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java @@ -16,46 +16,40 @@ package com.android.internal.statusbar; -import android.graphics.drawable.Icon; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; public class StatusBarIcon implements Parcelable { + public String iconPackage; public UserHandle user; - public Icon icon; + public int iconId; public int iconLevel; public boolean visible = true; public int number; public CharSequence contentDescription; - public StatusBarIcon(UserHandle user, Icon icon, int iconLevel, int number, + public StatusBarIcon(String iconPackage, UserHandle user, int iconId, int iconLevel, int number, CharSequence contentDescription) { + this.iconPackage = iconPackage; this.user = user; - this.icon = icon; + this.iconId = iconId; this.iconLevel = iconLevel; this.number = number; this.contentDescription = contentDescription; } - public StatusBarIcon(String iconPackage, UserHandle user, - int iconId, int iconLevel, int number, - CharSequence contentDescription) { - this(user, Icon.createWithResource(iconPackage, iconId), - iconLevel, number, contentDescription); - } - @Override public String toString() { - return "StatusBarIcon(icon=" + this.icon - + " user=" + user.getIdentifier() + return "StatusBarIcon(pkg=" + this.iconPackage + "user=" + user.getIdentifier() + + " id=0x" + Integer.toHexString(this.iconId) + " level=" + this.iconLevel + " visible=" + visible + " num=" + this.number + " )"; } @Override public StatusBarIcon clone() { - StatusBarIcon that = new StatusBarIcon(this.user, this.icon, + StatusBarIcon that = new StatusBarIcon(this.iconPackage, this.user, this.iconId, this.iconLevel, this.number, this.contentDescription); that.visible = this.visible; return that; @@ -69,8 +63,9 @@ public class StatusBarIcon implements Parcelable { } public void readFromParcel(Parcel in) { - this.icon = (Icon) in.readParcelable(null); + this.iconPackage = in.readString(); this.user = (UserHandle) in.readParcelable(null); + this.iconId = in.readInt(); this.iconLevel = in.readInt(); this.visible = in.readInt() != 0; this.number = in.readInt(); @@ -78,8 +73,9 @@ public class StatusBarIcon implements Parcelable { } public void writeToParcel(Parcel out, int flags) { - out.writeParcelable(this.icon, 0); + out.writeString(this.iconPackage); out.writeParcelable(this.user, 0); + out.writeInt(this.iconId); out.writeInt(this.iconLevel); out.writeInt(this.visible ? 1 : 0); out.writeInt(this.number); diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java index 607697340ca0..3249ea3a5250 100644 --- a/core/java/com/android/internal/util/NotificationColorUtil.java +++ b/core/java/com/android/internal/util/NotificationColorUtil.java @@ -24,7 +24,6 @@ import android.graphics.Color; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; -import android.graphics.drawable.Icon; import android.graphics.drawable.VectorDrawable; import android.text.SpannableStringBuilder; import android.text.Spanned; @@ -130,20 +129,6 @@ public class NotificationColorUtil { } } - public boolean isGrayscaleIcon(Context context, Icon icon) { - if (icon == null) { - return false; - } - switch (icon.getType()) { - case Icon.TYPE_BITMAP: - return isGrayscaleIcon(icon.getBitmap()); - case Icon.TYPE_RESOURCE: - return isGrayscaleIcon(context, icon.getResId()); - default: - return false; - } - } - /** * Checks whether a drawable with a resoure id is a small grayscale icon. * Grayscale here means "very close to a perfect gray"; icon means "no larger than 64dp". diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp index 35d69fe2bb1d..08d61d593b0a 100644 --- a/core/jni/android/graphics/SurfaceTexture.cpp +++ b/core/jni/android/graphics/SurfaceTexture.cpp @@ -341,6 +341,12 @@ static void SurfaceTexture_release(JNIEnv* env, jobject thiz) surfaceTexture->abandon(); } +static jboolean SurfaceTexture_isReleased(JNIEnv* env, jobject thiz) +{ + sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); + return surfaceTexture->isAbandoned(); +} + // ---------------------------------------------------------------------------- static JNINativeMethod gSurfaceTextureMethods[] = { @@ -355,6 +361,7 @@ static JNINativeMethod gSurfaceTextureMethods[] = { {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix }, {"nativeGetTimestamp", "()J", (void*)SurfaceTexture_getTimestamp }, {"nativeRelease", "()V", (void*)SurfaceTexture_release }, + {"nativeIsReleased", "()Z", (void*)SurfaceTexture_isReleased }, }; int register_android_graphics_SurfaceTexture(JNIEnv* env) diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 38bbe660c419..470e3455cbbc 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1105,7 +1105,7 @@ intern filter data scheme is set to "http" or "https". When set to true, the intent filter will need to use its data tag for getting the URIs to verify with. - For each URI, an HTTPS network request will be done to <code>/.well-known/associations.json</code> + For each URI, an HTTPS network request will be done to <code>/.well-known/statements.json</code> host to verify that the web site is okay with the app intercepting the URI. --> <attr name="autoVerify" format="boolean" /> diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml index 1043b6f392d9..263ea6200a5a 100644 --- a/core/tests/coretests/AndroidManifest.xml +++ b/core/tests/coretests/AndroidManifest.xml @@ -1119,6 +1119,8 @@ </activity> <activity android:name="com.android.internal.app.WindowDecorActionBarTestActivity"> </activity> + <activity android:name="com.android.internal.policy.PhoneWindowActionModeTestActivity"> + </activity> <receiver android:name="android.app.activity.AbortReceiver"> <intent-filter android:priority="1"> diff --git a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java new file mode 100644 index 000000000000..b860c2081f45 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java @@ -0,0 +1,372 @@ +/* + * Copyright (C) 2015 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.internal.policy; + +import android.test.ActivityInstrumentationTestCase2; +import android.test.UiThreadTest; +import android.view.ActionMode; +import android.view.ActionMode.Callback; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.SearchEvent; +import android.view.View; +import android.view.Window; +import android.view.WindowManager.LayoutParams; +import android.view.accessibility.AccessibilityEvent; + +/** + * Tests {@link PhoneWindow}'s {@link ActionMode} related methods. + */ +public final class PhoneWindowActionModeTest + extends ActivityInstrumentationTestCase2<PhoneWindowActionModeTestActivity> { + + private PhoneWindow mPhoneWindow; + private MockWindowCallback mWindowCallback; + private MockActionModeCallback mActionModeCallback; + + public PhoneWindowActionModeTest() { + super(PhoneWindowActionModeTestActivity.class); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + mPhoneWindow = (PhoneWindow) getActivity().getWindow(); + mWindowCallback = new MockWindowCallback(); + mPhoneWindow.setCallback(mWindowCallback); + mActionModeCallback = new MockActionModeCallback(); + } + + public void testStartActionModeWithCallback() { + mWindowCallback.mShouldReturnOwnActionMode = true; + + ActionMode mode = mPhoneWindow.getDecorView().startActionMode( + mActionModeCallback, ActionMode.TYPE_FLOATING); + + assertEquals(mWindowCallback.mLastCreatedActionMode, mode); + } + + public void testStartActionModePrimaryFinishesPreviousMode() { + // Use custom callback to control the provided ActionMode. + mWindowCallback.mShouldReturnOwnActionMode = true; + + ActionMode mode1 = mPhoneWindow.getDecorView().startActionMode( + mActionModeCallback, ActionMode.TYPE_PRIMARY); + ActionMode mode2 = mPhoneWindow.getDecorView().startActionMode( + mActionModeCallback, ActionMode.TYPE_PRIMARY); + + assertTrue(mode1 instanceof MockActionMode); + assertTrue(((MockActionMode) mode1).mIsFinished); + assertNotNull(mode2); + } + + public void testStartActionModeFloatingFinishesPreviousMode() { + // Use custom callback to control the provided ActionMode. + mWindowCallback.mShouldReturnOwnActionMode = true; + + ActionMode mode1 = mPhoneWindow.getDecorView().startActionMode( + mActionModeCallback, ActionMode.TYPE_FLOATING); + ActionMode mode2 = mPhoneWindow.getDecorView().startActionMode( + mActionModeCallback, ActionMode.TYPE_FLOATING); + + assertTrue(mode1 instanceof MockActionMode); + assertTrue(((MockActionMode) mode1).mIsFinished); + assertNotNull(mode2); + } + + public void testStartActionModePreservesPreviousModeOfDifferentType1() { + // Use custom callback to control the provided ActionMode. + mWindowCallback.mShouldReturnOwnActionMode = true; + + ActionMode mode1 = mPhoneWindow.getDecorView().startActionMode( + mActionModeCallback, ActionMode.TYPE_FLOATING); + ActionMode mode2 = mPhoneWindow.getDecorView().startActionMode( + mActionModeCallback, ActionMode.TYPE_PRIMARY); + + assertTrue(mode1 instanceof MockActionMode); + assertFalse(((MockActionMode) mode1).mIsFinished); + assertNotNull(mode2); + } + + public void testStartActionModePreservesPreviousModeOfDifferentType2() { + // Use custom callback to control the provided ActionMode. + mWindowCallback.mShouldReturnOwnActionMode = true; + + ActionMode mode1 = mPhoneWindow.getDecorView().startActionMode( + mActionModeCallback, ActionMode.TYPE_PRIMARY); + ActionMode mode2 = mPhoneWindow.getDecorView().startActionMode( + mActionModeCallback, ActionMode.TYPE_FLOATING); + + assertTrue(mode1 instanceof MockActionMode); + assertFalse(((MockActionMode) mode1).mIsFinished); + assertNotNull(mode2); + } + + public void testWindowCallbackModesLifecycleIsNotHandled() { + mWindowCallback.mShouldReturnOwnActionMode = true; + + ActionMode mode = mPhoneWindow.getDecorView().startActionMode( + mActionModeCallback, ActionMode.TYPE_PRIMARY); + + assertNotNull(mode); + assertEquals(mWindowCallback.mLastCreatedActionMode, mode); + assertFalse(mActionModeCallback.mIsCreateActionModeCalled); + assertTrue(mWindowCallback.mIsActionModeStarted); + } + + @UiThreadTest + public void testCreatedPrimaryModeLifecycleIsHandled() { + mWindowCallback.mShouldReturnOwnActionMode = false; + + ActionMode mode = mPhoneWindow.getDecorView().startActionMode( + mActionModeCallback, ActionMode.TYPE_PRIMARY); + + assertNotNull(mode); + assertEquals(ActionMode.TYPE_PRIMARY, mode.getType()); + assertTrue(mActionModeCallback.mIsCreateActionModeCalled); + assertTrue(mWindowCallback.mIsActionModeStarted); + } + + @UiThreadTest + public void testCreatedFloatingModeLifecycleIsHandled() { + mWindowCallback.mShouldReturnOwnActionMode = false; + + ActionMode mode = mPhoneWindow.getDecorView().startActionMode( + mActionModeCallback, ActionMode.TYPE_FLOATING); + + assertNotNull(mode); + assertEquals(ActionMode.TYPE_FLOATING, mode.getType()); + assertTrue(mActionModeCallback.mIsCreateActionModeCalled); + assertTrue(mWindowCallback.mIsActionModeStarted); + } + + @UiThreadTest + public void testCreatedModeIsNotStartedIfCreateReturnsFalse() { + mWindowCallback.mShouldReturnOwnActionMode = false; + mActionModeCallback.mShouldCreateActionMode = false; + + ActionMode mode = mPhoneWindow.getDecorView().startActionMode( + mActionModeCallback, ActionMode.TYPE_FLOATING); + + assertTrue(mActionModeCallback.mIsCreateActionModeCalled); + assertFalse(mWindowCallback.mIsActionModeStarted); + assertNull(mode); + } + + private static final class MockWindowCallback implements Window.Callback { + private boolean mShouldReturnOwnActionMode = false; + private MockActionMode mLastCreatedActionMode; + private boolean mIsActionModeStarted = false; + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + return false; + } + + @Override + public boolean dispatchKeyShortcutEvent(KeyEvent event) { + return false; + } + + @Override + public boolean dispatchTouchEvent(MotionEvent event) { + return false; + } + + @Override + public boolean dispatchTrackballEvent(MotionEvent event) { + return false; + } + + @Override + public boolean dispatchGenericMotionEvent(MotionEvent event) { + return false; + } + + @Override + public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { + return false; + } + + @Override + public View onCreatePanelView(int featureId) { + return null; + } + + @Override + public boolean onCreatePanelMenu(int featureId, Menu menu) { + return false; + } + + @Override + public boolean onPreparePanel(int featureId, View view, Menu menu) { + return false; + } + + @Override + public boolean onMenuOpened(int featureId, Menu menu) { + return false; + } + + @Override + public boolean onMenuItemSelected(int featureId, MenuItem item) { + return false; + } + + @Override + public void onWindowAttributesChanged(LayoutParams attrs) {} + + @Override + public void onContentChanged() {} + + @Override + public void onWindowFocusChanged(boolean hasFocus) {} + + @Override + public void onAttachedToWindow() {} + + @Override + public void onDetachedFromWindow() {} + + @Override + public void onPanelClosed(int featureId, Menu menu) {} + + @Override + public boolean onSearchRequested() { + return false; + } + + @Override + public boolean onSearchRequested(SearchEvent searchEvent) { + return false; + } + + @Override + public ActionMode onWindowStartingActionMode(Callback callback) { + if (mShouldReturnOwnActionMode) { + MockActionMode mode = new MockActionMode(); + mLastCreatedActionMode = mode; + return mode; + } + return null; + } + + @Override + public ActionMode onWindowStartingActionMode(Callback callback, int type) { + if (mShouldReturnOwnActionMode) { + MockActionMode mode = new MockActionMode(); + mode.mActionModeType = type; + mLastCreatedActionMode = mode; + return mode; + } + return null; + } + + @Override + public void onActionModeStarted(ActionMode mode) { + mIsActionModeStarted = true; + } + + @Override + public void onActionModeFinished(ActionMode mode) {} + } + + private static final class MockActionModeCallback implements ActionMode.Callback { + private boolean mShouldCreateActionMode = true; + private boolean mIsCreateActionModeCalled = false; + + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return true; + } + + @Override + public void onDestroyActionMode(ActionMode mode) {} + + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + mIsCreateActionModeCalled = true; + return mShouldCreateActionMode; + } + + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + return false; + } + } + + private static final class MockActionMode extends ActionMode { + private int mActionModeType = ActionMode.TYPE_PRIMARY; + private boolean mIsFinished = false; + + @Override + public int getType() { + return mActionModeType; + } + + @Override + public void setTitle(CharSequence title) {} + + @Override + public void setTitle(int resId) {} + + @Override + public void setSubtitle(CharSequence subtitle) {} + + @Override + public void setSubtitle(int resId) {} + + @Override + public void setCustomView(View view) {} + + @Override + public void invalidate() {} + + @Override + public void finish() { + mIsFinished = true; + } + + @Override + public Menu getMenu() { + return null; + } + + @Override + public CharSequence getTitle() { + return null; + } + + @Override + public CharSequence getSubtitle() { + return null; + } + + @Override + public View getCustomView() { + return null; + } + + @Override + public MenuInflater getMenuInflater() { + return null; + } + } +} diff --git a/telecomm/java/android/telecom/IConferenceable.java b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTestActivity.java index a664baa5f3dc..1516040e315a 100644 --- a/telecomm/java/android/telecom/IConferenceable.java +++ b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTestActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 The Android Open Source Project + * Copyright (C) 2015 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. @@ -11,18 +11,20 @@ * 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 + * limitations under the License. */ -package android.telecom; +package com.android.internal.policy; -/** - * Interface used to identify entities with which another entity can participate in a conference - * call with. The {@link ConnectionService} implementation will only recognize - * {@link Conferenceable}s which are {@link Connection}s or {@link Conference}s. - * <p> - * @deprecated use {@link Conferenceable} instead. - * @hide - */ -public interface IConferenceable extends Conferenceable { +import android.app.Activity; +import android.os.Bundle; +import android.view.View; + +public class PhoneWindowActionModeTestActivity extends Activity { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(new View(this)); + } } diff --git a/docs/html/google/play/billing/billing_reference.jd b/docs/html/google/play/billing/billing_reference.jd index 01e680fd54b6..7884929e44e8 100644 --- a/docs/html/google/play/billing/billing_reference.jd +++ b/docs/html/google/play/billing/billing_reference.jd @@ -172,8 +172,8 @@ does not include tax.</td> </tr> <tr> <td>{@code INAPP_DATA_SIGNATURE}</td> - <td>String containing the signature of the purchase data that was signed -with the private key of the developer. The data signature uses the + <td>String containing the signature of the purchase data that was signed +with the private key of the developer. The data signature uses the RSASSA-PKCS1-v1_5 scheme.</td> </tr> </table> @@ -197,7 +197,13 @@ RSASSA-PKCS1-v1_5 scheme.</td> lose access at that time unless they re-enable automatic renewal (or manually renew, as described in <a href="{@docRoot}google/play/billing/billing_subscriptions.html#manual-renewal">Manual - Renewal</a>).</td> + Renewal</a>). + If you offer a <a href="{@docRoot}google/play/billing/billing_subscriptions.html#grace-period" + >grace period</a>, this value remains set to <code>true</code> for all + subscriptions, as long as the grace period has not lapsed. The next billing date + is extended dynamically every day until the end of the grace period or until the + user fixes their payment method. + </td> </tr> <tr> <td>{@code orderId}</td> diff --git a/docs/html/google/play/billing/billing_subscriptions.jd b/docs/html/google/play/billing/billing_subscriptions.jd index 8f55354e5b6d..f7df7524e8c1 100644 --- a/docs/html/google/play/billing/billing_subscriptions.jd +++ b/docs/html/google/play/billing/billing_subscriptions.jd @@ -47,42 +47,42 @@ meta.tags="monetization, inappbilling, subscriptions" </div> <p>Subscriptions let you sell content, services, or features in your app with -automated, recurring billing. You can easily adapt an existing In-app Billing +automated, recurring billing. You can easily adapt an existing In-app Billing implementation to sell subscriptions.</p> -<p>This document is focused on highlighting implementation details that are -specific to subscriptions, along with some strategies for the associated billing +<p>This document is focused on highlighting implementation details that are +specific to subscriptions, along with some strategies for the associated billing and business models.</p> <h2 id="overview">Overview of Subscriptions</h2> -<p>A <em>subscription</em> is a product type offered in In-app Billing that -lets you sell content, services, or features to users from inside your app with +<p>A <em>subscription</em> is a product type offered in In-app Billing that +lets you sell content, services, or features to users from inside your app with recurring, automated billing at the interval you specify. You can sell subscriptions to almost any type of digital content, from any type of app or game.</p> <p>As with other in-app products, you configure and publish subscriptions using -the Developer Console and then sell them from inside apps installed on +the Developer Console and then sell them from inside apps installed on Android devices. In the Developer console, you create subscription products and add them to a product list, then set a price and optional trial period for each, choose a billing interval, and then -publish. For more information about using the Developer Console, see +publish. For more information about using the Developer Console, see <a href="#administering">Configuring Subscription Items</a>.</p> -<p>When users purchase subscriptions in your apps, Google Play handles all -checkout details so your apps never have to directly process any financial -transactions. Google Play processes all payments for subscriptions through -Google Wallet, just as it does for standard in-app products and app purchases. +<p>When users purchase subscriptions in your apps, Google Play handles all +checkout details so your apps never have to directly process any financial +transactions. Google Play processes all payments for subscriptions through +Google Wallet, just as it does for standard in-app products and app purchases. This ensures a consistent and familiar purchase flow for your users.</p> <img src="{@docRoot}images/in-app-billing/v3/billing_subscription_v3.png" style="float:right; border:4px solid ddd;"> -<p>After users have purchased subscriptions, they can view the subscriptions and -cancel them from the <strong>My Apps</strong> screen in the Play Store app or -from the app's product details page in the Play Store app. For more information +<p>After users have purchased subscriptions, they can view the subscriptions and +cancel them from the <strong>My Apps</strong> screen in the Play Store app or +from the app's product details page in the Play Store app. For more information about handling user cancellations, see <a href="#cancellation">Subscription Cancellation</a>.</p> -<p>In addition to client-side API calls, you can use the server-side API for -In-app Billing to provide subscription purchasers with extended access to +<p>In addition to client-side API calls, you can use the server-side API for +In-app Billing to provide subscription purchasers with extended access to content (for example, from your web site or another service). The server-side API lets you validate the status of a subscription when users sign into your other services. For more information about the API, see <a @@ -95,12 +95,12 @@ Android apps.</p> your own business logic to your Android app to determine whether the user has already purchased a subscription elsewhere, then allow access to your content if so or offer a subscription purchase from Google Play if not.</li> -<li>You can implement your own solution for sharing subscriptions across as -many different apps or products as you want. For example, you could sell a -subscription that gives a subscriber access to an entire collection of apps, -games, or other content for a monthly or annual fee. To implement this solution, -you could add your own business logic to your app to determine whether the user -has already purchased a given subscription and if so, allow access to your +<li>You can implement your own solution for sharing subscriptions across as +many different apps or products as you want. For example, you could sell a +subscription that gives a subscriber access to an entire collection of apps, +games, or other content for a monthly or annual fee. To implement this solution, +you could add your own business logic to your app to determine whether the user +has already purchased a given subscription and if so, allow access to your content.</li> </ul> </p> @@ -111,14 +111,14 @@ information about the current policies and terms, please read the <a href="http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en &answer=140504">policies document</a>.</p> -<p>To learn about the minimum system requirements for +<p>To learn about the minimum system requirements for subscriptions, see the <a href="{@docRoot}google/play/billing/versions.html#Subs">Version Notes</a>.</p> <h2 id="administering">Configuring Subscription Items</h2> <p>To create and manage subscriptions, you can use the Developer Console to set up a -product list for the app, then configure these attributes for each subscription +product list for the app, then configure these attributes for each subscription product:</p> <ul> @@ -133,7 +133,7 @@ product:</p> <li>Additional currency pricing (can be auto-filled)</li> </ul> -<p>For details on how to add and configure products in the Developer Console, +<p>For details on how to add and configure products in the Developer Console, see <a href="{@docRoot}google/play/billing/billing_admin.html">Administering In-app Billing</a>.</p> @@ -149,18 +149,20 @@ price. You can price multiple subscriptions for the same content differently — for example you could offer a discount on an annual subscription relative to the monthly equivalent. </p> -<p class="caution"><strong>Important</strong>: To change the price of a -subscription, you can publish a new subscription product ID at a new price, -then offer it in your app instead of the original product. Users who have -already purchased will continue to be charged at the +<p class="caution"><strong>Important</strong>: To change the price of a +subscription, you can publish a new subscription product ID at a new price, +then offer it in your app instead of the original product. Users who have +already purchased will continue to be charged at the original price, but new users will be charged at the new price.</p> <h3 id="user-billing">User billing</h3> -<p>In the Developer Console, you can configure subscription products with +<p>In the Developer Console, you can configure subscription products with automated recurring billing at your choice of intervals:</p> <ul> + <li>Weekly — Google Play bills the customer’s Google Wallet account at + the time of purchase and every week after the original purchase date.</li> <li>Monthly — Google Play bills the customer’s Google Wallet account at the time of purchase and monthly subsequent to the purchase date (exact billing intervals can vary slightly over time).</li> @@ -183,32 +185,27 @@ monthly and annual subscriptions, billing cycles will always match subscription cycles, based on the purchase date. (Seasonal subscriptions are charged annually, on the first day of the season.)</p> -<p>Over the life of a subscription, the form of payment billed remains the same -— Google Play always bills the same form of payment (such as credit card -or by Direct Carrier Billing) that was originally used to purchase the -subscription.</p> - -<p>When the subscription payment is approved by Google Wallet, Google Play +<p>When the subscription payment is approved, Google Play provides a purchase token back to the purchasing app through the In-app Billing -API. Your apps can store the token locally or pass it to your backend servers, +API. Your apps can store the token locally or pass it to your backend servers, which can then use it to validate or cancel the subscription remotely using the <a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google Play Developer API</a>.</p> <p>If a recurring payment fails (for example, because the customer’s credit -card has become invalid), the subscription does not renew. How your app is +card has become invalid), the subscription does not renew. How your app is notified depends on the In-app Billing API version that you are using:</p> <ul> -<li>With In-app Billing Version 3, the failed or expired subscription is no longer +<li>With In-app Billing Version 3, the failed or expired subscription is no longer returned when you call {@code getPurchases}.</li> -<li>With In-app Billing Version 2, Google Play notifies your app at the end of -the active cycle that the purchase state of the subscription is now "Expired". +<li>With In-app Billing Version 2, Google Play notifies your app at the end of +the active cycle that the purchase state of the subscription is now "Expired". </li> </ul> -<p class="note"><strong>Recommendation</strong>: Include business logic in your -app to notify your backend servers of subscription purchases, tokens, and any -billing errors that may occur. Your backend servers can use the server-side API +<p class="note"><strong>Recommendation</strong>: Include business logic in your +app to notify your backend servers of subscription purchases, tokens, and any +billing errors that may occur. Your backend servers can use the server-side API to query and update your records and follow up with customers directly, if needed.</p> <h3 id="manual-renewal">Manual Renewal</h3> @@ -220,8 +217,8 @@ is active, it is extended by the appropriate period at the current rate.</p> <p>For example, Achilles has a subscription to the <em>Modern Hoplite</em> app. His subscription is currently due to expire on August 1. On July 10, he -purchases a 3-month subscription at the current rate. Those three months are -added to his existing subscription, so the subscription now expires on November +purchases a 1-month subscription at the current rate. This one month is +added to his existing subscription, so the subscription now expires on September 1.</p> <p>It is up to the app to convey this with an appropriate UI. For example, if a @@ -311,9 +308,9 @@ date to 15 August 2015 14:00:00 UTC.</p> <h3 id="trials">Free trials</h3> <p>In the Developer Console, you can set up a free trial period that lets users -try your subscription content before buying it. The trial period runs for the -period of time that you set and then automatically converts to a full -subscription managed according to the subscription's billing interval and +try your subscription content before buying it. The trial period runs for the +period of time that you set and then automatically converts to a full +subscription managed according to the subscription's billing interval and price. Free trials are supported for monthly and annual subscriptions only, and are not supported for seasonal subscriptions.</p> <p>To take advantage of a free trial, a user must "purchase" the full @@ -328,7 +325,7 @@ by email that they have purchased a subscription that includes a free trial period and that the initial charge was $0.00. </p> <p>When the trial period ends, Google Play automatically initiates billing -against the credit card that the user provided during the initial purchase, at +against the credit card that the user provided during the initial purchase, at the amount set for the full subscription, and continuing at the subscription interval. If necessary, the user can cancel the subscription at any time during the trial @@ -367,15 +364,15 @@ publish the product before Google Play can make it available for purchase. Note that you must also publish the app itself before Google Play will make the products available for purchase inside the app. </p> -<p class="caution"><strong>Important</strong>: You can remove the subscription -product from the product list offered in your app to prevent users from seeing +<p class="caution"><strong>Important</strong>: You can remove the subscription +product from the product list offered in your app to prevent users from seeing or purchasing it.</p> <h2 id="cancellation">Subscription Cancellation</h2> <p>Users can view the status of all of their subscriptions and cancel them if -necessary from the <strong>My Apps</strong> screen in the Play Store app. -Currently, the In-app Billing API does not provide support for programatically +necessary from the <strong>My Apps</strong> screen in the Play Store app. +Currently, the In-app Billing API does not provide support for programatically canceling subscriptions from inside the purchasing app.</p> <p>When the user cancels a subscription, Google Play does not offer a refund for @@ -404,12 +401,12 @@ href="http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en <h3 id="uninstall">App uninstallation</h3> -<p>When the user uninstalls an app that includes purchased subscriptions, the -Play Store app will notify the user that there are active subscriptions. If the -user chooses to continue with the uninstallation, the app is removed and the -subscriptions remain active and recurring billing continues. The user can return -to cancel the associated subscriptions at any time in the <strong>My Apps</strong> -screen of the Play Store app. If the user chooses to cancel the uninstallation, +<p>When the user uninstalls an app that includes purchased subscriptions, the +Play Store app will notify the user that there are active subscriptions. If the +user chooses to continue with the uninstallation, the app is removed and the +subscriptions remain active and recurring billing continues. The user can return +to cancel the associated subscriptions at any time in the <strong>My Apps</strong> +screen of the Play Store app. If the user chooses to cancel the uninstallation, the app and subscriptions remain as they were.</p> <h3 id="refunds">Refunding and revoking subscriptions</h3> @@ -436,8 +433,8 @@ at this time.</p> <h2 id="payment">Payment Processing and Policies</h2> <p>In general, the terms of Google Play allow you to sell in-app subscriptions -only through the standard payment processor, Google Wallet. For purchases of -any subscription products, the transaction fee is the same as the transaction +only through the standard payment processor, Google Wallet. For purchases of +any subscription products, the transaction fee is the same as the transaction fee for application purchases (30%).</p> <p>Apps published on Google Play that are selling subscriptions must use In-app @@ -451,7 +448,7 @@ document</a>.</p> <h3 id="orderId">Subscription order numbers</h3> <p>To help you track transactions relating to a given subscription, Google -Wallet provides a base Merchant Order Number for all recurrences of the +Wallet provides a base Merchant Order Number for all recurrences of the subscription and denotes each recurring transaction by appending an integer as follows: </p> @@ -461,10 +458,29 @@ each recurring transaction by appending an integer as follows: </p> <code>12999556515565155651.5565135565155651..2</code> (third recurrence orderID)<br /> ...<br /></p> -<p>Google Play provides the order number as the value of the -{@code orderId} field of the {@code INAPP_PURCHASE_DATA} JSON field (in V3) +<p>Google Play provides the order number as the value of the +{@code orderId} field of the {@code INAPP_PURCHASE_DATA} JSON field (in V3) or the {@code PURCHASE_STATE_CHANGED} intent (in V2).</p> +<h3 id="grace-period">Grace period for declined payments</h3> + +<p> + The Developer Console allows you to set a grace period for subscriptions, so you can give + your subscribers a chance to update their payment method if a recurring payment is declined. + This setting is useful if your subscribers have an expired credit card, subscribed using a + prepaid card, or canceled a card without updating their payment information. For + information about setting a grace period for subscriptions, see the Developer Console Help + topic <a href="https://support.google.com/googleplay/android-developer/answer/140504" + class="external-link">Add subscriptions & recurring charges</a>. +</p> + +</p> + For information on how setting a grace period affects data returned from the + {@code getBuyIntent()} method, see the + <a href="{@docRoot}google/play/billing/billing_reference.html#purchase-data-table" + >{@code INAPP_PURCHASE_DATA}</a> fields table. +</p> + <h2 id="strategies">Purchase Verification Strategies</h2> <p>In a typical scenario, your app verifies the order status for new purchases diff --git a/docs/html/google/play/billing/index.jd b/docs/html/google/play/billing/index.jd index 47620c80aaa1..c671c71fc859 100644 --- a/docs/html/google/play/billing/index.jd +++ b/docs/html/google/play/billing/index.jd @@ -7,7 +7,7 @@ page.tags="billing, inapp, iap" <p>In-app Billing is a Google Play service that lets you sell digital content from inside your applications. You can use the service to sell a wide range of content, including downloadable -content such as media files or photos, virtual content such as game levels or potions, premium services +content such as media files or photos, virtual content such as game levels or potions, premium services and features, and more. You can use In-app Billing to sell products as</p> <div class="sidebox-wrapper"> @@ -34,17 +34,14 @@ and features, and more. You can use In-app Billing to sell products as</p> <a href="billing_subscriptions.html#deferred-billing">defer</a> a subscriber's next billing date until the date you choose. The user still has access to the content but is not charged during the deferral period.</li> - <li><strong>Google Play Developer API</strong>—The - <a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google - Play Developer API</a> allows you to perform a number of publishing and - app-management tasks. It includes the functionality previously known as the - <em>Purchase Status API.</em> </li> - <li><strong>Refund/Revoke subscription</strong>—You can use the - Google Play Developer API to <a href="billing_subscriptions.html#refunds">refund - and revoke</a> a user's subscription. If you do this, the user's - subscription ends - immediately, and his or her most recent subscription payment is - refunded.</li> + <li><strong>Weekly subscriptions</strong>—You can now set up a + recurring <a href="billing_subscriptions.html#user-billing">subscription</a> + that bills the user every week.</li> + <li><strong>Payment grace period</strong>—If a subscriber misses a + subscription payment due to an expired credit card, you can define a + <a href="billing_subscriptions.html#grace-period">grace period</a> + to the continue the subscription until payment is successful.</li> + </ul> </div> </div> @@ -69,7 +66,7 @@ Wallet merchant account.</p> provides a sample application that demonstrates how to sell standard in-app products and subscriptions from inside an app.</p> -<p>To get started, read the documents below or take the <a href="{@docRoot}training/in-app-billing/index.html">Selling +<p>To get started, read the documents below or take the <a href="{@docRoot}training/in-app-billing/index.html">Selling In-app Products</a> training class.</p> <dl> diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index f52c6611ebe6..5c54324d8107 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -347,6 +347,14 @@ public class SurfaceTexture { nativeRelease(); } + /** + * Returns true if the SurfaceTexture was released + * @hide + */ + public boolean isReleased() { + return nativeIsReleased(); + } + @Override protected void finalize() throws Throwable { try { @@ -383,6 +391,7 @@ public class SurfaceTexture { private native int nativeAttachToGLContext(int texName); private native int nativeGetQueuedCount(); private native void nativeRelease(); + private native boolean nativeIsReleased(); /* * We use a class initializer to allow the native code to cache some diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java index 37fb703d77f7..668a14a41605 100644 --- a/graphics/java/android/graphics/drawable/Icon.java +++ b/graphics/java/android/graphics/drawable/Icon.java @@ -53,14 +53,10 @@ import java.io.OutputStream; public final class Icon implements Parcelable { private static final String TAG = "Icon"; - /** @hide */ - public static final int TYPE_BITMAP = 1; - /** @hide */ - public static final int TYPE_RESOURCE = 2; - /** @hide */ - public static final int TYPE_DATA = 3; - /** @hide */ - public static final int TYPE_URI = 4; + private static final int TYPE_BITMAP = 1; + private static final int TYPE_RESOURCE = 2; + private static final int TYPE_DATA = 3; + private static final int TYPE_URI = 4; private static final int VERSION_STREAM_SERIALIZER = 1; @@ -85,34 +81,15 @@ public final class Icon implements Parcelable { // TYPE_DATA: data offset private int mInt2; - /** - * @return The type of image data held in this Icon. One of - * {@link #TYPE_BITMAP}, - * {@link #TYPE_RESOURCE}, - * {@link #TYPE_DATA}, or - * {@link #TYPE_URI}. - * @hide - */ - public int getType() { - return mType; - } - - /** - * @return The {@link android.graphics.Bitmap} held by this {@link #TYPE_BITMAP} Icon. - * @hide - */ - public Bitmap getBitmap() { + // Internal accessors for different mType variants + private Bitmap getBitmap() { if (mType != TYPE_BITMAP) { throw new IllegalStateException("called getBitmap() on " + this); } return (Bitmap) mObj1; } - /** - * @return The length of the compressed bitmap byte array held by this {@link #TYPE_DATA} Icon. - * @hide - */ - public int getDataLength() { + private int getDataLength() { if (mType != TYPE_DATA) { throw new IllegalStateException("called getDataLength() on " + this); } @@ -121,12 +98,7 @@ public final class Icon implements Parcelable { } } - /** - * @return The offset into the byte array held by this {@link #TYPE_DATA} Icon at which - * valid compressed bitmap data is found. - * @hide - */ - public int getDataOffset() { + private int getDataOffset() { if (mType != TYPE_DATA) { throw new IllegalStateException("called getDataOffset() on " + this); } @@ -135,12 +107,7 @@ public final class Icon implements Parcelable { } } - /** - * @return The byte array held by this {@link #TYPE_DATA} Icon ctonaining compressed - * bitmap data. - * @hide - */ - public byte[] getDataBytes() { + private byte[] getDataBytes() { if (mType != TYPE_DATA) { throw new IllegalStateException("called getDataBytes() on " + this); } @@ -149,58 +116,39 @@ public final class Icon implements Parcelable { } } - /** - * @return The {@link android.content.res.Resources} for this {@link #TYPE_RESOURCE} Icon. - * @hide - */ - public Resources getResources() { + private Resources getResources() { if (mType != TYPE_RESOURCE) { throw new IllegalStateException("called getResources() on " + this); } return (Resources) mObj1; } - /** - * @return The package containing resources for this {@link #TYPE_RESOURCE} Icon. - * @hide - */ - public String getResPackage() { + private String getResPackage() { if (mType != TYPE_RESOURCE) { throw new IllegalStateException("called getResPackage() on " + this); } return mString1; } - /** - * @return The resource ID for this {@link #TYPE_RESOURCE} Icon. - * @hide - */ - public int getResId() { + private int getResId() { if (mType != TYPE_RESOURCE) { throw new IllegalStateException("called getResId() on " + this); } return mInt1; } - /** - * @return The URI (as a String) for this {@link #TYPE_URI} Icon. - * @hide - */ - public String getUriString() { + private String getUriString() { if (mType != TYPE_URI) { throw new IllegalStateException("called getUriString() on " + this); } return mString1; } - /** - * @return The {@link android.net.Uri} for this {@link #TYPE_URI} Icon. - * @hide - */ - public Uri getUri() { + private Uri getUri() { return Uri.parse(getUriString()); } + // Convert a int32 into a four-char string private static final String typeToString(int x) { switch (x) { case TYPE_BITMAP: return "BITMAP"; diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java index 6283e0275bfb..5d777b0cb942 100644 --- a/keystore/java/android/security/Credentials.java +++ b/keystore/java/android/security/Credentials.java @@ -216,7 +216,7 @@ public class Credentials { * particular {@code alias}. All three can exist for any given alias. * Returns {@code true} if there was at least one of those types. */ - static boolean deleteAllTypesForAlias(KeyStore keystore, String alias) { + public static boolean deleteAllTypesForAlias(KeyStore keystore, String alias) { /* * Make sure every type is deleted. There can be all three types, so * don't use a conditional here. @@ -231,7 +231,7 @@ public class Credentials { * particular {@code alias}. All three can exist for any given alias. * Returns {@code true} if there was at least one of those types. */ - static boolean deleteCertificateTypesForAlias(KeyStore keystore, String alias) { + public static boolean deleteCertificateTypesForAlias(KeyStore keystore, String alias) { /* * Make sure every certificate type is deleted. There can be two types, * so don't use a conditional here. @@ -252,7 +252,7 @@ public class Credentials { * Delete secret key for a particular {@code alias}. * Returns {@code true} if an entry was was deleted. */ - static boolean deleteSecretKeyTypeForAlias(KeyStore keystore, String alias) { + public static boolean deleteSecretKeyTypeForAlias(KeyStore keystore, String alias) { return keystore.delete(Credentials.USER_SECRET_KEY + alias); } } diff --git a/keystore/java/android/security/GateKeeper.java b/keystore/java/android/security/GateKeeper.java index 561783627ebd..c1df28c387e5 100644 --- a/keystore/java/android/security/GateKeeper.java +++ b/keystore/java/android/security/GateKeeper.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2015 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.security; import android.os.RemoteException; diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index 72c74dffc448..06f5b067cb50 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -109,7 +109,7 @@ public class KeyStore { mContext = getApplicationContext(); } - static Context getApplicationContext() { + public static Context getApplicationContext() { ActivityThread activityThread = ActivityThread.currentActivityThread(); if (activityThread == null) { throw new IllegalStateException( @@ -136,7 +136,7 @@ public class KeyStore { return mToken; } - static int getKeyTypeForAlgorithm(@KeyProperties.KeyAlgorithmEnum String keyType) { + public static int getKeyTypeForAlgorithm(@KeyProperties.KeyAlgorithmEnum String keyType) { if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyType)) { return NativeConstants.EVP_PKEY_RSA; } else if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyType)) { @@ -632,7 +632,7 @@ public class KeyStore { * Returns a {@link KeyStoreException} corresponding to the provided keystore/keymaster error * code. */ - static KeyStoreException getKeyStoreException(int errorCode) { + public static KeyStoreException getKeyStoreException(int errorCode) { if (errorCode > 0) { // KeyStore layer error switch (errorCode) { @@ -674,7 +674,8 @@ public class KeyStore { * Returns an {@link InvalidKeyException} corresponding to the provided * {@link KeyStoreException}. */ - InvalidKeyException getInvalidKeyException(String keystoreKeyAlias, KeyStoreException e) { + public InvalidKeyException getInvalidKeyException( + String keystoreKeyAlias, KeyStoreException e) { switch (e.getErrorCode()) { case LOCKED: return new UserNotAuthenticatedException(); @@ -745,7 +746,7 @@ public class KeyStore { * Returns an {@link InvalidKeyException} corresponding to the provided keystore/keymaster error * code. */ - InvalidKeyException getInvalidKeyException(String keystoreKeyAlias, int errorCode) { + public InvalidKeyException getInvalidKeyException(String keystoreKeyAlias, int errorCode) { return getInvalidKeyException(keystoreKeyAlias, getKeyStoreException(errorCode)); } } diff --git a/keystore/java/android/security/AndroidKeyPairGenerator.java b/keystore/java/android/security/keystore/AndroidKeyPairGeneratorSpi.java index e9f83200b270..8d3b42120b8c 100644 --- a/keystore/java/android/security/AndroidKeyPairGenerator.java +++ b/keystore/java/android/security/keystore/AndroidKeyPairGeneratorSpi.java @@ -14,11 +14,12 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; import android.annotation.NonNull; -import android.security.keystore.KeyGenParameterSpec; -import android.security.keystore.KeyProperties; +import android.security.Credentials; +import android.security.KeyPairGeneratorSpec; +import android.security.KeyStore; import com.android.org.bouncycastle.x509.X509V3CertificateGenerator; import com.android.org.conscrypt.NativeConstants; @@ -55,15 +56,15 @@ import java.util.Locale; * * {@hide} */ -public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi { +public abstract class AndroidKeyPairGeneratorSpi extends KeyPairGeneratorSpi { - public static class RSA extends AndroidKeyPairGenerator { + public static class RSA extends AndroidKeyPairGeneratorSpi { public RSA() { super(KeyProperties.KEY_ALGORITHM_RSA); } } - public static class EC extends AndroidKeyPairGenerator { + public static class EC extends AndroidKeyPairGeneratorSpi { public EC() { super(KeyProperties.KEY_ALGORITHM_EC); } @@ -92,7 +93,7 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi { private int mKeyType; private int mKeySize; - protected AndroidKeyPairGenerator(@KeyProperties.KeyAlgorithmEnum String algorithm) { + protected AndroidKeyPairGeneratorSpi(@KeyProperties.KeyAlgorithmEnum String algorithm) { mAlgorithm = algorithm; } diff --git a/keystore/java/android/security/AndroidKeyStoreBCWorkaroundProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java index 45329cf2600b..3774e360d66b 100644 --- a/keystore/java/android/security/AndroidKeyStoreBCWorkaroundProvider.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; import java.security.Provider; @@ -40,9 +40,9 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { // classes when this provider is instantiated and installed early on during each app's // initialization process. - private static final String PACKAGE_NAME = "android.security"; + private static final String PACKAGE_NAME = "android.security.keystore"; private static final String KEYSTORE_SECRET_KEY_CLASS_NAME = - PACKAGE_NAME + ".KeyStoreSecretKey"; + PACKAGE_NAME + ".AndroidKeyStoreSecretKey"; AndroidKeyStoreBCWorkaroundProvider() { super("AndroidKeyStoreBCWorkaround", @@ -50,25 +50,25 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { "Android KeyStore security provider to work around Bouncy Castle"); // javax.crypto.Mac - putMacImpl("HmacSHA1", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA1"); - putMacImpl("HmacSHA224", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA224"); - putMacImpl("HmacSHA256", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA256"); - putMacImpl("HmacSHA384", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA384"); - putMacImpl("HmacSHA512", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA512"); + putMacImpl("HmacSHA1", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA1"); + putMacImpl("HmacSHA224", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA224"); + putMacImpl("HmacSHA256", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA256"); + putMacImpl("HmacSHA384", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA384"); + putMacImpl("HmacSHA512", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA512"); // javax.crypto.Cipher putSymmetricCipherImpl("AES/ECB/NoPadding", - PACKAGE_NAME + ".KeyStoreCipherSpi$AES$ECB$NoPadding"); + PACKAGE_NAME + ".AndroidKeyStoreCipherSpi$AES$ECB$NoPadding"); putSymmetricCipherImpl("AES/ECB/PKCS7Padding", - PACKAGE_NAME + ".KeyStoreCipherSpi$AES$ECB$PKCS7Padding"); + PACKAGE_NAME + ".AndroidKeyStoreCipherSpi$AES$ECB$PKCS7Padding"); putSymmetricCipherImpl("AES/CBC/NoPadding", - PACKAGE_NAME + ".KeyStoreCipherSpi$AES$CBC$NoPadding"); + PACKAGE_NAME + ".AndroidKeyStoreCipherSpi$AES$CBC$NoPadding"); putSymmetricCipherImpl("AES/CBC/PKCS7Padding", - PACKAGE_NAME + ".KeyStoreCipherSpi$AES$CBC$PKCS7Padding"); + PACKAGE_NAME + ".AndroidKeyStoreCipherSpi$AES$CBC$PKCS7Padding"); putSymmetricCipherImpl("AES/CTR/NoPadding", - PACKAGE_NAME + ".KeyStoreCipherSpi$AES$CTR$NoPadding"); + PACKAGE_NAME + ".AndroidKeyStoreCipherSpi$AES$CTR$NoPadding"); } private void putMacImpl(String algorithm, String implClass) { diff --git a/keystore/java/android/security/KeyStoreCipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpi.java index b0f1695188c2..27df5e7b1e9c 100644 --- a/keystore/java/android/security/KeyStoreCipherSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpi.java @@ -14,9 +14,11 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; import android.os.IBinder; +import android.security.KeyStore; +import android.security.KeyStoreException; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; import android.security.keymaster.OperationResult; @@ -48,9 +50,10 @@ import javax.crypto.spec.IvParameterSpec; * * @hide */ -public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCryptoOperation { +public abstract class AndroidKeyStoreCipherSpi extends CipherSpi + implements KeyStoreCryptoOperation { - public abstract static class AES extends KeyStoreCipherSpi { + public abstract static class AES extends AndroidKeyStoreCipherSpi { protected AES(int keymasterBlockMode, int keymasterPadding, boolean ivUsed) { super(KeymasterDefs.KM_ALGORITHM_AES, keymasterBlockMode, @@ -120,7 +123,7 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry // Fields below are populated by Cipher.init and KeyStore.begin and should be preserved after // doFinal finishes. protected boolean mEncrypting; - private KeyStoreSecretKey mKey; + private AndroidKeyStoreSecretKey mKey; private SecureRandom mRng; private boolean mFirstOperationInitiated; private byte[] mIv; @@ -147,7 +150,7 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry */ private Exception mCachedException; - protected KeyStoreCipherSpi( + protected AndroidKeyStoreCipherSpi( int keymasterAlgorithm, int keymasterBlockMode, int keymasterPadding, @@ -219,11 +222,11 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry } private void init(int opmode, Key key, SecureRandom random) throws InvalidKeyException { - if (!(key instanceof KeyStoreSecretKey)) { + if (!(key instanceof AndroidKeyStoreSecretKey)) { throw new InvalidKeyException( "Unsupported key: " + ((key != null) ? key.getClass().getName() : "null")); } - mKey = (KeyStoreSecretKey) key; + mKey = (AndroidKeyStoreSecretKey) key; mRng = random; mIv = null; mFirstOperationInitiated = false; diff --git a/keystore/java/android/security/KeyStoreHmacSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java index 5089a2577fcc..b82a7f5a4e5e 100644 --- a/keystore/java/android/security/KeyStoreHmacSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java @@ -14,9 +14,11 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; import android.os.IBinder; +import android.security.KeyStore; +import android.security.KeyStoreException; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; import android.security.keymaster.OperationResult; @@ -34,33 +36,33 @@ import javax.crypto.MacSpi; * * @hide */ -public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOperation { +public abstract class AndroidKeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOperation { - public static class HmacSHA1 extends KeyStoreHmacSpi { + public static class HmacSHA1 extends AndroidKeyStoreHmacSpi { public HmacSHA1() { super(KeymasterDefs.KM_DIGEST_SHA1); } } - public static class HmacSHA224 extends KeyStoreHmacSpi { + public static class HmacSHA224 extends AndroidKeyStoreHmacSpi { public HmacSHA224() { super(KeymasterDefs.KM_DIGEST_SHA_2_224); } } - public static class HmacSHA256 extends KeyStoreHmacSpi { + public static class HmacSHA256 extends AndroidKeyStoreHmacSpi { public HmacSHA256() { super(KeymasterDefs.KM_DIGEST_SHA_2_256); } } - public static class HmacSHA384 extends KeyStoreHmacSpi { + public static class HmacSHA384 extends AndroidKeyStoreHmacSpi { public HmacSHA384() { super(KeymasterDefs.KM_DIGEST_SHA_2_384); } } - public static class HmacSHA512 extends KeyStoreHmacSpi { + public static class HmacSHA512 extends AndroidKeyStoreHmacSpi { public HmacSHA512() { super(KeymasterDefs.KM_DIGEST_SHA_2_512); } @@ -71,14 +73,14 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp private final int mMacSizeBits; // Fields below are populated by engineInit and should be preserved after engineDoFinal. - private KeyStoreSecretKey mKey; + private AndroidKeyStoreSecretKey mKey; // Fields below are reset when engineDoFinal succeeds. private KeyStoreCryptoOperationChunkedStreamer mChunkedStreamer; private IBinder mOperationToken; private long mOperationHandle; - protected KeyStoreHmacSpi(int keymasterDigest) { + protected AndroidKeyStoreHmacSpi(int keymasterDigest) { mKeymasterDigest = keymasterDigest; mMacSizeBits = KeymasterUtils.getDigestOutputSizeBits(keymasterDigest); } @@ -109,11 +111,11 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp InvalidAlgorithmParameterException { if (key == null) { throw new InvalidKeyException("key == null"); - } else if (!(key instanceof KeyStoreSecretKey)) { + } else if (!(key instanceof AndroidKeyStoreSecretKey)) { throw new InvalidKeyException( "Only Android KeyStore secret keys supported. Key: " + key); } - mKey = (KeyStoreSecretKey) key; + mKey = (AndroidKeyStoreSecretKey) key; if (params != null) { throw new InvalidAlgorithmParameterException( diff --git a/keystore/java/android/security/KeyStoreKey.java b/keystore/java/android/security/keystore/AndroidKeyStoreKey.java index 7a3482959162..6098e5c612c0 100644 --- a/keystore/java/android/security/KeyStoreKey.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKey.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; import java.security.Key; @@ -23,11 +23,11 @@ import java.security.Key; * * @hide */ -public class KeyStoreKey implements Key { +public class AndroidKeyStoreKey implements Key { private final String mAlias; private final String mAlgorithm; - public KeyStoreKey(String alias, String algorithm) { + public AndroidKeyStoreKey(String alias, String algorithm) { mAlias = alias; mAlgorithm = algorithm; } diff --git a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java index feec00f7b77b..0821bf5e6b15 100644 --- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java @@ -14,8 +14,10 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; +import android.security.Credentials; +import android.security.KeyStore; import android.security.keymaster.KeyCharacteristics; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; @@ -39,9 +41,9 @@ import javax.crypto.SecretKey; * * @hide */ -public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { +public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { - public static class AES extends KeyStoreKeyGeneratorSpi { + public static class AES extends AndroidKeyStoreKeyGeneratorSpi { public AES() { super(KeymasterDefs.KM_ALGORITHM_AES, 128); } @@ -58,7 +60,7 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { } } - protected static abstract class HmacBase extends KeyStoreKeyGeneratorSpi { + protected static abstract class HmacBase extends AndroidKeyStoreKeyGeneratorSpi { protected HmacBase(int keymasterDigest) { super(KeymasterDefs.KM_ALGORITHM_HMAC, keymasterDigest, @@ -110,13 +112,13 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { private int[] mKeymasterPaddings; private int[] mKeymasterDigests; - protected KeyStoreKeyGeneratorSpi( + protected AndroidKeyStoreKeyGeneratorSpi( int keymasterAlgorithm, int defaultKeySizeBits) { this(keymasterAlgorithm, -1, defaultKeySizeBits); } - protected KeyStoreKeyGeneratorSpi( + protected AndroidKeyStoreKeyGeneratorSpi( int keymasterAlgorithm, int keymasterDigest, int defaultKeySizeBits) { @@ -314,6 +316,6 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { } catch (IllegalArgumentException e) { throw new ProviderException("Failed to obtain JCA secret key algorithm name", e); } - return new KeyStoreSecretKey(keyAliasInKeystore, keyAlgorithmJCA); + return new AndroidKeyStoreSecretKey(keyAliasInKeystore, keyAlgorithmJCA); } } diff --git a/keystore/java/android/security/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java index 257ab54c9495..b20a122f6de2 100644 --- a/keystore/java/android/security/AndroidKeyStoreProvider.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java @@ -14,7 +14,9 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; + +import android.security.KeyStore; import java.security.Provider; import java.security.Security; @@ -38,25 +40,25 @@ public class AndroidKeyStoreProvider extends Provider { // Instead, they need to be offered by AndroidKeyStoreBCWorkaroundProvider. See its Javadoc // for details. - private static final String PACKAGE_NAME = "android.security"; + private static final String PACKAGE_NAME = "android.security.keystore"; public AndroidKeyStoreProvider() { super(PROVIDER_NAME, 1.0, "Android KeyStore security provider"); // java.security.KeyStore - put("KeyStore.AndroidKeyStore", PACKAGE_NAME + ".AndroidKeyStore"); + put("KeyStore.AndroidKeyStore", PACKAGE_NAME + ".AndroidKeyStoreSpi"); // java.security.KeyPairGenerator - put("KeyPairGenerator.EC", PACKAGE_NAME + ".AndroidKeyPairGenerator$EC"); - put("KeyPairGenerator.RSA", PACKAGE_NAME + ".AndroidKeyPairGenerator$RSA"); + put("KeyPairGenerator.EC", PACKAGE_NAME + ".AndroidKeyPairGeneratorSpi$EC"); + put("KeyPairGenerator.RSA", PACKAGE_NAME + ".AndroidKeyPairGeneratorSpi$RSA"); // javax.crypto.KeyGenerator - put("KeyGenerator.AES", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$AES"); - put("KeyGenerator.HmacSHA1", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA1"); - put("KeyGenerator.HmacSHA224", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA224"); - put("KeyGenerator.HmacSHA256", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA256"); - put("KeyGenerator.HmacSHA384", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA384"); - put("KeyGenerator.HmacSHA512", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA512"); + put("KeyGenerator.AES", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$AES"); + put("KeyGenerator.HmacSHA1", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$HmacSHA1"); + put("KeyGenerator.HmacSHA224", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$HmacSHA224"); + put("KeyGenerator.HmacSHA256", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$HmacSHA256"); + put("KeyGenerator.HmacSHA384", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$HmacSHA384"); + put("KeyGenerator.HmacSHA512", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$HmacSHA512"); // java.security.SecretKeyFactory putSecretKeyFactoryImpl("AES"); @@ -95,7 +97,7 @@ public class AndroidKeyStoreProvider extends Provider { } private void putSecretKeyFactoryImpl(String algorithm) { - put("SecretKeyFactory." + algorithm, PACKAGE_NAME + ".KeyStoreSecretKeyFactorySpi"); + put("SecretKeyFactory." + algorithm, PACKAGE_NAME + ".AndroidKeyStoreSecretKeyFactorySpi"); } /** diff --git a/keystore/java/android/security/KeyStoreSecretKey.java b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKey.java index ee2546598962..f75516b2c1c1 100644 --- a/keystore/java/android/security/KeyStoreSecretKey.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKey.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; import javax.crypto.SecretKey; @@ -23,9 +23,9 @@ import javax.crypto.SecretKey; * * @hide */ -public class KeyStoreSecretKey extends KeyStoreKey implements SecretKey { +public class AndroidKeyStoreSecretKey extends AndroidKeyStoreKey implements SecretKey { - public KeyStoreSecretKey(String alias, String algorithm) { + public AndroidKeyStoreSecretKey(String alias, String algorithm) { super(alias, algorithm); } } diff --git a/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java index 618ba47f3ff4..455f1709fa14 100644 --- a/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; +import android.security.Credentials; +import android.security.KeyStore; import android.security.keymaster.KeyCharacteristics; import android.security.keymaster.KeymasterDefs; -import android.security.keystore.KeyInfo; -import android.security.keystore.KeyProperties; import libcore.util.EmptyArray; @@ -39,7 +39,7 @@ import javax.crypto.spec.SecretKeySpec; * * @hide */ -public class KeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi { +public class AndroidKeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi { private final KeyStore mKeyStore = KeyStore.getInstance(); @@ -49,7 +49,7 @@ public class KeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi { if (keySpecClass == null) { throw new InvalidKeySpecException("keySpecClass == null"); } - if (!(key instanceof KeyStoreSecretKey)) { + if (!(key instanceof AndroidKeyStoreSecretKey)) { throw new InvalidKeySpecException("Only Android KeyStore secret keys supported: " + ((key != null) ? key.getClass().getName() : "null")); } @@ -60,7 +60,7 @@ public class KeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi { if (!KeyInfo.class.equals(keySpecClass)) { throw new InvalidKeySpecException("Unsupported key spec: " + keySpecClass.getName()); } - String keyAliasInKeystore = ((KeyStoreSecretKey) key).getAlias(); + String keyAliasInKeystore = ((AndroidKeyStoreSecretKey) key).getAlias(); String entryAlias; if (keyAliasInKeystore.startsWith(Credentials.USER_SECRET_KEY)) { entryAlias = keyAliasInKeystore.substring(Credentials.USER_SECRET_KEY.length()); diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java index 69bf877c3f94..d6145a391502 100644 --- a/keystore/java/android/security/AndroidKeyStore.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java @@ -14,13 +14,15 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; import com.android.org.conscrypt.OpenSSLEngine; import com.android.org.conscrypt.OpenSSLKeyHolder; import libcore.util.EmptyArray; +import android.security.Credentials; +import android.security.KeyStoreParameter; import android.security.keymaster.KeyCharacteristics; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; @@ -81,7 +83,7 @@ import javax.crypto.SecretKey; * * @hide */ -public class AndroidKeyStore extends KeyStoreSpi { +public class AndroidKeyStoreSpi extends KeyStoreSpi { public static final String NAME = "AndroidKeyStore"; private android.security.KeyStore mKeyStore; @@ -140,7 +142,7 @@ public class AndroidKeyStore extends KeyStoreSpi { new UnrecoverableKeyException("Unsupported secret key type").initCause(e); } - return new KeyStoreSecretKey(keyAliasInKeystore, keyAlgorithmString); + return new AndroidKeyStoreSecretKey(keyAliasInKeystore, keyAlgorithmString); } return null; @@ -476,10 +478,10 @@ public class AndroidKeyStore extends KeyStoreSpi { } KeyProtection params = (KeyProtection) param; - if (key instanceof KeyStoreSecretKey) { + if (key instanceof AndroidKeyStoreSecretKey) { // KeyStore-backed secret key. It cannot be duplicated into another entry and cannot // overwrite its own entry. - String keyAliasInKeystore = ((KeyStoreSecretKey) key).getAlias(); + String keyAliasInKeystore = ((AndroidKeyStoreSecretKey) key).getAlias(); if (keyAliasInKeystore == null) { throw new KeyStoreException("KeyStore-backed secret key does not have an alias"); } diff --git a/keystore/java/android/security/ArrayUtils.java b/keystore/java/android/security/keystore/ArrayUtils.java index 71b99d035dd1..81be38485722 100644 --- a/keystore/java/android/security/ArrayUtils.java +++ b/keystore/java/android/security/keystore/ArrayUtils.java @@ -1,4 +1,20 @@ -package android.security; +/* + * Copyright (C) 2015 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.security.keystore; import libcore.util.EmptyArray; diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java index fa3b1cb125dd..f598482aae2e 100644 --- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java @@ -21,7 +21,6 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.text.TextUtils; -import android.security.ArrayUtils; import android.security.KeyStore; import java.math.BigInteger; diff --git a/keystore/java/android/security/keystore/KeyInfo.java b/keystore/java/android/security/keystore/KeyInfo.java index aec2512a0185..e4f921e939a1 100644 --- a/keystore/java/android/security/keystore/KeyInfo.java +++ b/keystore/java/android/security/keystore/KeyInfo.java @@ -18,7 +18,6 @@ package android.security.keystore; import android.annotation.NonNull; import android.annotation.Nullable; -import android.security.ArrayUtils; import java.security.PrivateKey; import java.security.spec.KeySpec; diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java index 113159de04d9..48fdd983b2e9 100644 --- a/keystore/java/android/security/keystore/KeyProtection.java +++ b/keystore/java/android/security/keystore/KeyProtection.java @@ -20,8 +20,6 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.KeyguardManager; -import android.content.Context; -import android.security.ArrayUtils; import android.security.KeyStore; import java.security.Key; diff --git a/keystore/java/android/security/KeyStoreConnectException.java b/keystore/java/android/security/keystore/KeyStoreConnectException.java index 885f1f7566db..e008976d3c31 100644 --- a/keystore/java/android/security/KeyStoreConnectException.java +++ b/keystore/java/android/security/keystore/KeyStoreConnectException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; import java.security.ProviderException; diff --git a/keystore/java/android/security/KeyStoreCryptoOperation.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperation.java index c5cf211a6f2d..2c709ae1ac5b 100644 --- a/keystore/java/android/security/KeyStoreCryptoOperation.java +++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperation.java @@ -14,7 +14,9 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; + +import android.security.KeyStore; /** * Cryptographic operation backed by {@link KeyStore}. diff --git a/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java index 06191994af62..7d57e5f518a4 100644 --- a/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java +++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java @@ -14,9 +14,11 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; import android.os.IBinder; +import android.security.KeyStore; +import android.security.KeyStoreException; import android.security.keymaster.OperationResult; import libcore.util.EmptyArray; diff --git a/keystore/java/android/security/KeyStoreCryptoOperationUtils.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationUtils.java index c9bdd41676dd..6ae76f13e9f6 100644 --- a/keystore/java/android/security/KeyStoreCryptoOperationUtils.java +++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationUtils.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; +import android.security.KeyStore; import android.security.keymaster.KeymasterDefs; -import android.security.keystore.UserNotAuthenticatedException; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; @@ -41,7 +41,7 @@ abstract class KeyStoreCryptoOperationUtils { * the {@code init} method should succeed. */ static InvalidKeyException getInvalidKeyExceptionForInit( - KeyStore keyStore, KeyStoreKey key, int beginOpResultCode) { + KeyStore keyStore, AndroidKeyStoreKey key, int beginOpResultCode) { if (beginOpResultCode == KeyStore.NO_ERROR) { return null; } @@ -69,8 +69,8 @@ abstract class KeyStoreCryptoOperationUtils { * in response to {@code KeyStore.begin} operation or {@code null} if the {@code init} method * should succeed. */ - static GeneralSecurityException getExceptionForCipherInit( - KeyStore keyStore, KeyStoreKey key, int beginOpResultCode) { + public static GeneralSecurityException getExceptionForCipherInit( + KeyStore keyStore, AndroidKeyStoreKey key, int beginOpResultCode) { if (beginOpResultCode == KeyStore.NO_ERROR) { return null; } diff --git a/keystore/java/android/security/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java index 0f8f1900da96..e7529e12e67d 100644 --- a/keystore/java/android/security/KeymasterUtils.java +++ b/keystore/java/android/security/keystore/KeymasterUtils.java @@ -14,9 +14,11 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; import android.hardware.fingerprint.FingerprintManager; +import android.security.GateKeeper; +import android.security.KeyStore; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; diff --git a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java b/keystore/tests/src/android/security/keystore/AndroidKeyPairGeneratorTest.java index 9c2f3586e03f..cad4e5499bab 100644 --- a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java +++ b/keystore/tests/src/android/security/keystore/AndroidKeyPairGeneratorTest.java @@ -14,8 +14,10 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; +import android.security.Credentials; +import android.security.KeyPairGeneratorSpec; import android.test.AndroidTestCase; import java.io.ByteArrayInputStream; diff --git a/keystore/tests/src/android/security/AndroidKeyStoreTest.java b/keystore/tests/src/android/security/keystore/AndroidKeyStoreTest.java index 4b2b9b5ac243..2d4e4a0a0202 100644 --- a/keystore/tests/src/android/security/AndroidKeyStoreTest.java +++ b/keystore/tests/src/android/security/keystore/AndroidKeyStoreTest.java @@ -14,13 +14,16 @@ * limitations under the License. */ -package android.security; +package android.security.keystore; import com.android.org.bouncycastle.x509.X509V3CertificateGenerator; import com.android.org.conscrypt.NativeConstants; import com.android.org.conscrypt.OpenSSLEngine; +import android.security.Credentials; +import android.security.KeyStore; +import android.security.KeyStoreParameter; import android.test.AndroidTestCase; import java.io.ByteArrayInputStream; @@ -1319,9 +1322,9 @@ public class AndroidKeyStoreTest extends AndroidTestCase { } public void testKeyStore_GetType_Encrypted_Success() throws Exception { - assertEquals(AndroidKeyStore.NAME, mKeyStore.getType()); + assertEquals(AndroidKeyStoreSpi.NAME, mKeyStore.getType()); setupPassword(); - assertEquals(AndroidKeyStore.NAME, mKeyStore.getType()); + assertEquals(AndroidKeyStoreSpi.NAME, mKeyStore.getType()); } public void testKeyStore_IsCertificateEntry_CA_Encrypted_Success() throws Exception { diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index 8f5fea3bb7c1..e4666046fa3f 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -280,6 +280,7 @@ void PathCache::clear() { } void PathCache::generateTexture(SkBitmap& bitmap, Texture* texture) { + ATRACE_NAME("Upload Path Texture"); SkAutoLockPixels alp(bitmap); if (!bitmap.readyToDraw()) { ALOGE("Cannot generate texture from bitmap"); diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java index 4ecb930eeec8..0384d40651ca 100644 --- a/media/java/android/media/AudioDeviceInfo.java +++ b/media/java/android/media/AudioDeviceInfo.java @@ -122,8 +122,9 @@ public final class AudioDeviceInfo { /** * @return The human-readable name of the audio device. */ - public CharSequence getName() { - return mPort.name(); + public CharSequence getProductName() { + String portName = mPort.name(); + return portName.length() != 0 ? portName : android.os.Build.MODEL; } /** diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java index 195c98704e4c..e18e9a395b5a 100644 --- a/media/java/android/media/Image.java +++ b/media/java/android/media/Image.java @@ -163,10 +163,12 @@ public abstract class Image implements AutoCloseable { * Get the timestamp associated with this frame. * <p> * The timestamp is measured in nanoseconds, and is normally monotonically - * increasing. However, the behavior of the timestamp depends on the source - * of this image. See {@link android.hardware.Camera Camera}, - * {@link android.hardware.camera2.CameraDevice CameraDevice}, {@link MediaPlayer} and - * {@link MediaCodec} for more details. + * increasing. The timestamps for the images from different sources may have + * different timebases therefore may not be comparable. The specific meaning and + * timebase of the timestamp depend on the source providing images. See + * {@link android.hardware.Camera Camera}, + * {@link android.hardware.camera2.CameraDevice CameraDevice}, + * {@link MediaPlayer} and {@link MediaCodec} for more details. * </p> */ public abstract long getTimestamp(); @@ -175,9 +177,11 @@ public abstract class Image implements AutoCloseable { * Set the timestamp associated with this frame. * <p> * The timestamp is measured in nanoseconds, and is normally monotonically - * increasing. However, the behavior of the timestamp depends on - * the destination of this image. See {@link android.hardware.Camera Camera} - * , {@link android.hardware.camera2.CameraDevice CameraDevice}, + * increasing. The timestamps for the images from different sources may have + * different timebases therefore may not be comparable. The specific meaning and + * timebase of the timestamp depend on the source providing images. See + * {@link android.hardware.Camera Camera}, + * {@link android.hardware.camera2.CameraDevice CameraDevice}, * {@link MediaPlayer} and {@link MediaCodec} for more details. * </p> * <p> @@ -195,18 +199,6 @@ public abstract class Image implements AutoCloseable { return; } - /** - * <p>Check if the image is opaque.</p> - * - * <p>The pixel data of opaque images are not accessible to the application, - * and therefore {@link #getPlanes} will return an empty array for an opaque image. - * </p> - */ - public boolean isOpaque() { - throwISEIfImageIsInvalid(); - return false; - } - private Rect mCropRect; /** @@ -243,10 +235,11 @@ public abstract class Image implements AutoCloseable { /** * Get the array of pixel planes for this Image. The number of planes is - * determined by the format of the Image. The application will get an - * empty array if the image is opaque because the opaque image pixel data - * is not directly accessible. The application can check if an image is - * opaque by calling {@link Image#isOpaque}. + * determined by the format of the Image. The application will get an empty + * array if the image format is {@link android.graphics.ImageFormat#PRIVATE + * PRIVATE}, because the image pixel data is not directly accessible. The + * application can check the image format by calling + * {@link Image#getFormat()}. */ public abstract Plane[] getPlanes(); diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java index 6d3020808758..9bd721adca0c 100644 --- a/media/java/android/media/ImageReader.java +++ b/media/java/android/media/ImageReader.java @@ -68,76 +68,45 @@ public class ImageReader implements AutoCloseable { private static final int ACQUIRE_MAX_IMAGES = 2; /** - * <p>Create a new reader for images of the desired size and format.</p> - * - * <p>The {@code maxImages} parameter determines the maximum number of {@link Image} - * objects that can be be acquired from the {@code ImageReader} - * simultaneously. Requesting more buffers will use up more memory, so it is - * important to use only the minimum number necessary for the use case.</p> - * - * <p>The valid sizes and formats depend on the source of the image - * data.</p> - * - * @param width - * The default width in pixels of the Images that this reader will produce. - * @param height - * The default height in pixels of the Images that this reader will produce. - * @param format - * The format of the Image that this reader will produce. This - * must be one of the {@link android.graphics.ImageFormat} or - * {@link android.graphics.PixelFormat} constants. Note that - * not all formats is supported, like ImageFormat.NV21. - * @param maxImages - * The maximum number of images the user will want to - * access simultaneously. This should be as small as possible to limit - * memory use. Once maxImages Images are obtained by the user, one of them - * has to be released before a new Image will become available for access - * through {@link #acquireLatestImage()} or {@link #acquireNextImage()}. - * Must be greater than 0. - * - * @see Image - */ - public static ImageReader newInstance(int width, int height, int format, int maxImages) { - if (format == ImageFormat.PRIVATE) { - throw new IllegalArgumentException("To obtain an opaque ImageReader, please use" - + " newOpaqueInstance rather than newInstance"); - } - return new ImageReader(width, height, format, maxImages); - } - - /** - * <p> - * Create a new opaque reader for images of the desired size. - * </p> * <p> - * An opaque {@link ImageReader} produces images that are not directly - * accessible by the application. The application can still acquire images - * from an opaque image reader, and send them to the - * {@link android.hardware.camera2.CameraDevice camera} for reprocessing via - * {@link ImageWriter} interface. However, the {@link Image#getPlanes() - * getPlanes()} will return an empty array for opaque images. The - * application can check if an existing reader is an opaque reader by - * calling {@link #isOpaque()}. + * Create a new reader for images of the desired size and format. * </p> * <p> * The {@code maxImages} parameter determines the maximum number of * {@link Image} objects that can be be acquired from the * {@code ImageReader} simultaneously. Requesting more buffers will use up - * more memory, so it is important to use only the minimum number necessary. + * more memory, so it is important to use only the minimum number necessary + * for the use case. * </p> * <p> * The valid sizes and formats depend on the source of the image data. * </p> * <p> - * Opaque ImageReaders are more efficient to use when application access to - * image data is not necessary, compared to ImageReaders using a non-opaque - * format such as {@link ImageFormat#YUV_420_888 YUV_420_888}. + * If the {@code format} is {@link ImageFormat#PRIVATE PRIVATE}, the created + * {@link ImageReader} will produce images that are not directly accessible + * by the application. The application can still acquire images from this + * {@link ImageReader}, and send them to the + * {@link android.hardware.camera2.CameraDevice camera} for reprocessing via + * {@link ImageWriter} interface. However, the {@link Image#getPlanes() + * getPlanes()} will return an empty array for {@link ImageFormat#PRIVATE + * PRIVATE} format images. The application can check if an existing reader's + * format by calling {@link #getImageFormat()}. + * </p> + * <p> + * {@link ImageFormat#PRIVATE PRIVATE} format {@link ImageReader + * ImageReaders} are more efficient to use when application access to image + * data is not necessary, compared to ImageReaders using other format such + * as {@link ImageFormat#YUV_420_888 YUV_420_888}. * </p> * * @param width The default width in pixels of the Images that this reader * will produce. * @param height The default height in pixels of the Images that this reader * will produce. + * @param format The format of the Image that this reader will produce. This + * must be one of the {@link android.graphics.ImageFormat} or + * {@link android.graphics.PixelFormat} constants. Note that not + * all formats are supported, like ImageFormat.NV21. * @param maxImages The maximum number of images the user will want to * access simultaneously. This should be as small as possible to * limit memory use. Once maxImages Images are obtained by the @@ -147,8 +116,8 @@ public class ImageReader implements AutoCloseable { * Must be greater than 0. * @see Image */ - public static ImageReader newOpaqueInstance(int width, int height, int maxImages) { - return new ImageReader(width, height, ImageFormat.PRIVATE, maxImages); + public static ImageReader newInstance(int width, int height, int format, int maxImages) { + return new ImageReader(width, height, format, maxImages); } /** @@ -248,23 +217,6 @@ public class ImageReader implements AutoCloseable { } /** - * <p> - * Check if the {@link ImageReader} is an opaque reader. - * </p> - * <p> - * An opaque image reader produces opaque images, see {@link Image#isOpaque} - * for more details. - * </p> - * - * @return true if the ImageReader is opaque. - * @see Image#isOpaque - * @see ImageReader#newOpaqueInstance - */ - public boolean isOpaque() { - return mFormat == ImageFormat.PRIVATE; - } - - /** * <p>Get a {@link Surface} that can be used to produce {@link Image Images} for this * {@code ImageReader}.</p> * @@ -540,11 +492,11 @@ public class ImageReader implements AutoCloseable { * </p> * <p> * This method can be used to achieve zero buffer copy for use cases like - * {@link android.hardware.camera2.CameraDevice Camera2 API} OPAQUE and YUV + * {@link android.hardware.camera2.CameraDevice Camera2 API} PRIVATE and YUV * reprocessing, where the application can select an output image from * {@link ImageReader} and transfer this image directly to * {@link ImageWriter}, where this image can be consumed by camera directly. - * For OPAQUE reprocessing, this is the only way to send input buffers to + * For PRIVATE reprocessing, this is the only way to send input buffers to * the {@link android.hardware.camera2.CameraDevice camera} for * reprocessing. * </p> @@ -703,26 +655,26 @@ public class ImageReader implements AutoCloseable { @Override public int getFormat() { throwISEIfImageIsInvalid(); + int readerFormat = ImageReader.this.getImageFormat(); + // Assume opaque reader always produce opaque images. + mFormat = (readerFormat == ImageFormat.PRIVATE) ? readerFormat : + nativeGetFormat(readerFormat); return mFormat; } @Override public int getWidth() { throwISEIfImageIsInvalid(); - if (mWidth == -1) { - mWidth = (getFormat() == ImageFormat.JPEG) ? ImageReader.this.getWidth() : - nativeGetWidth(mFormat); - } + mWidth = (getFormat() == ImageFormat.JPEG) ? ImageReader.this.getWidth() : + nativeGetWidth(mFormat); return mWidth; } @Override public int getHeight() { throwISEIfImageIsInvalid(); - if (mHeight == -1) { - mHeight = (getFormat() == ImageFormat.JPEG) ? ImageReader.this.getHeight() : - nativeGetHeight(mFormat); - } + mHeight = (getFormat() == ImageFormat.JPEG) ? ImageReader.this.getHeight() : + nativeGetHeight(mFormat); return mHeight; } @@ -746,12 +698,6 @@ public class ImageReader implements AutoCloseable { } @Override - public boolean isOpaque() { - throwISEIfImageIsInvalid(); - return mFormat == ImageFormat.PRIVATE; - } - - @Override protected final void finalize() throws Throwable { try { close(); @@ -876,6 +822,7 @@ public class ImageReader implements AutoCloseable { private synchronized native SurfacePlane nativeCreatePlane(int idx, int readerFormat); private synchronized native int nativeGetWidth(int format); private synchronized native int nativeGetHeight(int format); + private synchronized native int nativeGetFormat(int readerFormat); } private synchronized native void nativeInit(Object weakSelf, int w, int h, diff --git a/media/java/android/media/ImageUtils.java b/media/java/android/media/ImageUtils.java index 89313bf30e31..c312525e0cd4 100644 --- a/media/java/android/media/ImageUtils.java +++ b/media/java/android/media/ImageUtils.java @@ -57,7 +57,7 @@ class ImageUtils { case ImageFormat.RAW_SENSOR: case ImageFormat.RAW10: return 1; - case PixelFormat.OPAQUE: + case ImageFormat.PRIVATE: return 0; default: throw new UnsupportedOperationException( @@ -70,10 +70,11 @@ class ImageUtils { * Copy source image data to destination Image. * </p> * <p> - * Only support the copy between two non-opaque images with same properties - * (format, size, etc.). The data from the source image will be copied to - * the byteBuffers from the destination Image starting from position zero, - * and the destination image will be rewound to zero after copy is done. + * Only support the copy between two non-{@link ImageFormat#PRIVATE PRIVATE} format + * images with same properties (format, size, etc.). The data from the + * source image will be copied to the byteBuffers from the destination Image + * starting from position zero, and the destination image will be rewound to + * zero after copy is done. * </p> * * @param src The source image to be copied from. @@ -88,8 +89,9 @@ class ImageUtils { if (src.getFormat() != dst.getFormat()) { throw new IllegalArgumentException("Src and dst images should have the same format"); } - if (src.isOpaque() || dst.isOpaque()) { - throw new IllegalArgumentException("Opaque image is not copyable"); + if (src.getFormat() == ImageFormat.PRIVATE || + dst.getFormat() == ImageFormat.PRIVATE) { + throw new IllegalArgumentException("PRIVATE format images are not copyable"); } if (!(dst.getOwner() instanceof ImageWriter)) { throw new IllegalArgumentException("Destination image is not from ImageWriter. Only" diff --git a/media/java/android/media/ImageWriter.java b/media/java/android/media/ImageWriter.java index f80533914b57..2ef251959a4d 100644 --- a/media/java/android/media/ImageWriter.java +++ b/media/java/android/media/ImageWriter.java @@ -33,8 +33,8 @@ import java.util.List; /** * <p> * The ImageWriter class allows an application to produce Image data into a - * {@link android.view.Surface}, and have it be consumed by another component like - * {@link android.hardware.camera2.CameraDevice CameraDevice}. + * {@link android.view.Surface}, and have it be consumed by another component + * like {@link android.hardware.camera2.CameraDevice CameraDevice}. * </p> * <p> * Several Android API classes can provide input {@link android.view.Surface @@ -54,21 +54,21 @@ import java.util.List; * <p> * If the application already has an Image from {@link ImageReader}, the * application can directly queue this Image into ImageWriter (via - * {@link #queueInputImage}), potentially with zero buffer copies. For the opaque - * Images produced by an opaque ImageReader (created by - * {@link ImageReader#newOpaqueInstance}), this is the only way to send Image - * data to ImageWriter, as the Image data aren't accessible by the application. + * {@link #queueInputImage}), potentially with zero buffer copies. For the + * {@link ImageFormat#PRIVATE PRIVATE} format Images produced by + * {@link ImageReader}, this is the only way to send Image data to ImageWriter, + * as the Image data aren't accessible by the application. * </p> - * Once new input Images are queued into an ImageWriter, it's up to the downstream - * components (e.g. {@link ImageReader} or + * Once new input Images are queued into an ImageWriter, it's up to the + * downstream components (e.g. {@link ImageReader} or * {@link android.hardware.camera2.CameraDevice}) to consume the Images. If the * downstream components cannot consume the Images at least as fast as the - * ImageWriter production rate, the {@link #dequeueInputImage} call will eventually - * block and the application will have to drop input frames. </p> + * ImageWriter production rate, the {@link #dequeueInputImage} call will + * eventually block and the application will have to drop input frames. </p> */ public class ImageWriter implements AutoCloseable { private final Object mListenerLock = new Object(); - private ImageListener mListener; + private OnImageReleasedListener mListener; private ListenerHandler mListenerHandler; private long mNativeContext; @@ -168,32 +168,34 @@ public class ImageWriter implements AutoCloseable { * This call will block if all available input images have been queued by * the application and the downstream consumer has not yet consumed any. * When an Image is consumed by the downstream consumer and released, an - * {@link ImageListener#onInputImageReleased} callback will be fired, which - * indicates that there is one input Image available. For non-opaque formats - * (({@link ImageWriter#getFormat()} != {@link ImageFormat#PRIVATE})), it is + * {@link OnImageReleasedListener#onImageReleased} callback will be fired, + * which indicates that there is one input Image available. For non- + * {@link ImageFormat#PRIVATE PRIVATE} formats ( + * {@link ImageWriter#getFormat()} != {@link ImageFormat#PRIVATE}), it is * recommended to dequeue the next Image only after this callback is fired, * in the steady state. * </p> * <p> - * If the ImageWriter is opaque ({@link ImageWriter#getFormat()} == - * {@link ImageFormat#PRIVATE}), the image buffer is inaccessible to - * the application, and calling this method will result in an - * {@link IllegalStateException}. Instead, the application should acquire - * opaque images from some other component (e.g. an opaque + * If the format of ImageWriter is {@link ImageFormat#PRIVATE PRIVATE} ( + * {@link ImageWriter#getFormat()} == {@link ImageFormat#PRIVATE}), the + * image buffer is inaccessible to the application, and calling this method + * will result in an {@link IllegalStateException}. Instead, the application + * should acquire images from some other component (e.g. an * {@link ImageReader}), and queue them directly to this ImageWriter via the * {@link ImageWriter#queueInputImage queueInputImage()} method. * </p> * * @return The next available input Image from this ImageWriter. * @throws IllegalStateException if {@code maxImages} Images are currently - * dequeued, or the ImageWriter is opaque. + * dequeued, or the ImageWriter format is + * {@link ImageFormat#PRIVATE PRIVATE}. * @see #queueInputImage * @see Image#close */ public Image dequeueInputImage() { if (mWriterFormat == ImageFormat.PRIVATE) { throw new IllegalStateException( - "Opaque ImageWriter doesn't support this operation since opaque images are" + "PRIVATE format ImageWriter doesn't support this operation since the images are" + " inaccessible to the application!"); } @@ -229,10 +231,10 @@ public class ImageWriter implements AutoCloseable { * </p> * <p> * After this method is called and the downstream consumer consumes and - * releases the Image, an {@link ImageListener#onInputImageReleased - * onInputImageReleased()} callback will fire. The application can use this - * callback to avoid sending Images faster than the downstream consumer - * processing rate in steady state. + * releases the Image, an {@link OnImageReleasedListener#onImageReleased} + * callback will fire. The application can use this callback to avoid + * sending Images faster than the downstream consumer processing rate in + * steady state. * </p> * <p> * Passing in an Image from some other component (e.g. an @@ -271,12 +273,12 @@ public class ImageWriter implements AutoCloseable { } ImageReader prevOwner = (ImageReader) image.getOwner(); - // Only do the image attach for opaque images for now. Do the image + // Only do the image attach for PRIVATE format images for now. Do the image // copy for other formats. TODO: use attach for other formats to // improve the performance, and fall back to copy when attach/detach // fails. Right now, detach is guaranteed to fail as the buffer is // locked when ImageReader#acquireNextImage is called. See bug 19962027. - if (image.isOpaque()) { + if (image.getFormat() == ImageFormat.PRIVATE) { prevOwner.detachImage(image); attachAndQueueInputImage(image); // This clears the native reference held by the original owner. @@ -319,8 +321,9 @@ public class ImageWriter implements AutoCloseable { * Get the ImageWriter format. * <p> * This format may be different than the Image format returned by - * {@link Image#getFormat()}. However, if the ImageWriter is opaque (format - * == {@link ImageFormat#PRIVATE}) , the images from it will also be opaque. + * {@link Image#getFormat()}. However, if the ImageWriter format is + * {@link ImageFormat#PRIVATE PRIVATE}, calling {@link #dequeueInputImage()} + * will result in an {@link IllegalStateException}. * </p> * * @return The ImageWriter format. @@ -333,7 +336,7 @@ public class ImageWriter implements AutoCloseable { * ImageWriter callback interface, used to to asynchronously notify the * application of various ImageWriter events. */ - public interface ImageListener { + public interface OnImageReleasedListener { /** * <p> * Callback that is called when an input Image is released back to @@ -361,7 +364,7 @@ public class ImageWriter implements AutoCloseable { * @see ImageWriter * @see Image */ - void onInputImageReleased(ImageWriter writer); + void onImageReleased(ImageWriter writer); } /** @@ -375,7 +378,7 @@ public class ImageWriter implements AutoCloseable { * @throws IllegalArgumentException If no handler specified and the calling * thread has no looper. */ - public void setImageListener(ImageListener listener, Handler handler) { + public void setOnImageReleasedListener(OnImageReleasedListener listener, Handler handler) { synchronized (mListenerLock) { if (listener != null) { Looper looper = handler != null ? handler.getLooper() : Looper.myLooper(); @@ -408,7 +411,7 @@ public class ImageWriter implements AutoCloseable { */ @Override public void close() { - setImageListener(null, null); + setOnImageReleasedListener(null, null); for (Image image : mDequeuedImages) { image.close(); } @@ -431,19 +434,18 @@ public class ImageWriter implements AutoCloseable { * Attach and queue input Image to this ImageWriter. * </p> * <p> - * When an Image is from an opaque source (e.g. an opaque ImageReader - * created by {@link ImageReader#newOpaqueInstance}), or the source Image is - * so large that copying its data is too expensive, this method can be used - * to migrate the source Image into ImageWriter without a data copy, and - * then queue it to this ImageWriter. The source Image must be detached from - * its previous owner already, or this call will throw an + * When the format of an Image is {@link ImageFormat#PRIVATE PRIVATE}, or + * the source Image is so large that copying its data is too expensive, this + * method can be used to migrate the source Image into ImageWriter without a + * data copy, and then queue it to this ImageWriter. The source Image must + * be detached from its previous owner already, or this call will throw an * {@link IllegalStateException}. * </p> * <p> * After this call, the ImageWriter takes ownership of this Image. This * ownership will automatically be removed from this writer after the * consumer releases this Image, that is, after - * {@link ImageListener#onInputImageReleased}. The caller is responsible for + * {@link OnImageReleasedListener#onImageReleased}. The caller is responsible for * closing this Image through {@link Image#close()} to free up the resources * held by this Image. * </p> @@ -492,12 +494,12 @@ public class ImageWriter implements AutoCloseable { @Override public void handleMessage(Message msg) { - ImageListener listener; + OnImageReleasedListener listener; synchronized (mListenerLock) { listener = mListener; } if (listener != null) { - listener.onInputImageReleased(ImageWriter.this); + listener.onImageReleased(ImageWriter.this); } } } @@ -647,13 +649,6 @@ public class ImageWriter implements AutoCloseable { } @Override - public boolean isOpaque() { - throwISEIfImageIsInvalid(); - - return getFormat() == ImageFormat.PRIVATE; - } - - @Override public Plane[] getPlanes() { throwISEIfImageIsInvalid(); diff --git a/media/java/android/media/MediaDataSource.java b/media/java/android/media/MediaDataSource.java index 246c0ef0a3d0..948da0b97910 100644 --- a/media/java/android/media/MediaDataSource.java +++ b/media/java/android/media/MediaDataSource.java @@ -18,6 +18,7 @@ package android.media; import java.io.Closeable; +import java.io.IOException; /** * For supplying media data to the framework. Implement this if your app has @@ -29,34 +30,32 @@ import java.io.Closeable; * you don't need to do your own synchronization unless you're modifying the * MediaDataSource from another thread while it's being used by the framework.</p> */ -public interface MediaDataSource extends Closeable { +public abstract class MediaDataSource implements Closeable { /** * Called to request data from the given position. * * Implementations should should write up to {@code size} bytes into * {@code buffer}, and return the number of bytes written. * - * Return {@code 0} to indicate that {@code position} is at, or beyond, the - * end of the source. + * Return {@code 0} if size is zero (thus no bytes are read). * - * Return {@code -1} to indicate that a fatal error occurred. The failed - * read will not be retried, so transient errors should be handled - * internally. - * - * Throwing an exception from this method will have the same effect as - * returning {@code -1}. + * Return {@code -1} to indicate that end of stream is reached. * * @param position the position in the data source to read from. * @param buffer the buffer to read the data into. + * @param offset the offset within buffer to read the data into. * @param size the number of bytes to read. + * @throws IOException on fatal errors. * @return the number of bytes read, or -1 if there was an error. */ - public int readAt(long position, byte[] buffer, int size); + public abstract int readAt(long position, byte[] buffer, int offset, int size) + throws IOException; /** * Called to get the size of the data source. * + * @throws IOException on fatal errors * @return the size of data source in bytes, or -1 if the size is unknown. */ - public long getSize(); + public abstract long getSize() throws IOException; } diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 256ab29131e8..e3a6a8395421 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -1360,6 +1360,8 @@ public class MediaPlayer implements SubtitleController.Listener * frequency. * When rate is larger than 1.0, pitch becomes higher. * When rate is smaller than 1.0, pitch becomes lower. + * + * @hide */ public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2; @@ -1372,6 +1374,8 @@ public class MediaPlayer implements SubtitleController.Listener * <p> * This mode is only supported for a limited range of playback speed factors, * e.g. between 1/2x and 2x. + * + * @hide */ public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1; @@ -1383,6 +1387,8 @@ public class MediaPlayer implements SubtitleController.Listener * Try to keep audio pitch when changing the playback rate, but allow the * system to determine how to change audio playback if the rate is out * of range. + * + * @hide */ public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0; @@ -1406,8 +1412,11 @@ public class MediaPlayer implements SubtitleController.Listener * @throws IllegalStateException if the internal player engine has not been * initialized. * @throws IllegalArgumentException if audioMode is not supported. + * + * @hide */ - public void setPlaybackRate(float rate, @PlaybackRateAudioMode int audioMode) { + @NonNull + public PlaybackParams easyPlaybackParams(float rate, @PlaybackRateAudioMode int audioMode) { PlaybackParams params = new PlaybackParams(); params.allowDefaults(); switch (audioMode) { @@ -1425,7 +1434,7 @@ public class MediaPlayer implements SubtitleController.Listener final String msg = "Audio playback mode " + audioMode + " is not supported"; throw new IllegalArgumentException(msg); } - setPlaybackParams(params); + return params; } /** @@ -1481,23 +1490,22 @@ public class MediaPlayer implements SubtitleController.Listener public native void seekTo(int msec) throws IllegalStateException; /** - * Get current playback position. + * Get current playback position as a {@link MediaTimestamp}. * <p> * The MediaTimestamp represents how the media time correlates to the system time in - * a linear fashion. It contains the media time and system timestamp of an anchor frame - * ({@link MediaTimestamp#mediaTimeUs} and {@link MediaTimestamp#nanoTime}) - * and the speed of the media clock ({@link MediaTimestamp#clockRate}). + * a linear fashion using an anchor and a clock rate. During regular playback, the media + * time moves fairly constantly (though the anchor frame may be rebased to a current + * system time, the linear correlation stays steady). Therefore, this method does not + * need to be called often. * <p> - * During regular playback, the media time moves fairly constantly (though the - * anchor frame may be rebased to a current system time, the linear correlation stays - * steady). Therefore, this method does not need to be called often. - * <p> - * To help users to get current playback position, this method always returns the timestamp of - * just-rendered frame, i.e., {@link System#nanoTime} and its corresponding media time. They - * can be used as current playback position. + * To help users get current playback position, this method always anchors the timestamp + * to the current {@link System#nanoTime system time}, so + * {@link MediaTimestamp#getAnchorMediaTimeUs} can be used as current playback position. * * @return a MediaTimestamp object if a timestamp is available, or {@code null} if no timestamp * is available, e.g. because the media player has not been initialized. + * + * @see MediaTimestamp */ @Nullable public MediaTimestamp getTimestamp() diff --git a/media/java/android/media/MediaSync.java b/media/java/android/media/MediaSync.java index d9e554c16e3e..b07931d87f1e 100644 --- a/media/java/android/media/MediaSync.java +++ b/media/java/android/media/MediaSync.java @@ -352,89 +352,6 @@ public final class MediaSync { public native final Surface createInputSurface(); /** - * Resample audio data when changing playback speed. - * <p> - * Resample the waveform based on the requested playback rate to get - * a new waveform, and play back the new waveform at the original sampling - * frequency. - * <p><ul> - * <li>When rate is larger than 1.0, pitch becomes higher. - * <li>When rate is smaller than 1.0, pitch becomes lower. - * </ul> - */ - public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2; - - /** - * Time stretch audio when changing playback speed. - * <p> - * Time stretching changes the duration of the audio samples without - * affecting their pitch. This is only supported for a limited range - * of playback speeds, e.g. from 1/2x to 2x. If the rate is adjusted - * beyond this limit, the rate change will fail. - */ - public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1; - - /** - * Time stretch audio when changing playback speed, and may mute if - * stretching is no longer supported. - * <p> - * Time stretching changes the duration of the audio samples without - * affecting their pitch. This is only supported for a limited range - * of playback speeds, e.g. from 1/2x to 2x. When it is no longer - * supported, the audio may be muted. Using this mode will not fail - * for non-negative playback rates. - */ - public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0; - - /** @hide */ - @IntDef( - value = { - PLAYBACK_RATE_AUDIO_MODE_DEFAULT, - PLAYBACK_RATE_AUDIO_MODE_STRETCH, - PLAYBACK_RATE_AUDIO_MODE_RESAMPLE, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface PlaybackRateAudioMode {} - - /** - * Sets playback rate and audio mode. - * - * @param rate the ratio between desired playback rate and normal one. 1.0 means normal - * playback speed. 0.0 means pause. Value larger than 1.0 means faster playback, - * while value between 0.0 and 1.0 for slower playback. <b>Note:</b> the normal rate - * does not change as a result of this call. To restore the original rate at any time, - * use 1.0. - * @param audioMode audio playback mode. Must be one of the supported - * audio modes. - * - * @throws IllegalStateException if the internal sync engine or the audio track has not - * been initialized. - * @throws IllegalArgumentException if audioMode is not supported. - */ - public void setPlaybackRate(float rate, @PlaybackRateAudioMode int audioMode) { - PlaybackParams rateParams = new PlaybackParams(); - rateParams.allowDefaults(); - switch (audioMode) { - case PLAYBACK_RATE_AUDIO_MODE_DEFAULT: - rateParams.setSpeed(rate).setPitch(1.0f); - break; - case PLAYBACK_RATE_AUDIO_MODE_STRETCH: - rateParams.setSpeed(rate).setPitch(1.0f) - .setAudioFallbackMode(rateParams.AUDIO_FALLBACK_MODE_FAIL); - break; - case PLAYBACK_RATE_AUDIO_MODE_RESAMPLE: - rateParams.setSpeed(rate).setPitch(rate); - break; - default: - { - final String msg = "Audio playback mode " + audioMode + " is not supported"; - throw new IllegalArgumentException(msg); - } - } - setPlaybackParams(rateParams); - } - - /** * Sets playback rate using {@link PlaybackParams}. * <p> * When using MediaSync with {@link AudioTrack}, set playback params using this @@ -524,24 +441,23 @@ public final class MediaSync { } /** - * Get current playback position. - * <p> - * The MediaTimestamp represents how the media time correlates to the system time in - * a linear fashion. It contains the media time and system timestamp of an anchor frame - * ({@link MediaTimestamp#mediaTimeUs} and {@link MediaTimestamp#nanoTime}) - * and the speed of the media clock ({@link MediaTimestamp#clockRate}). - * <p> - * During regular playback, the media time moves fairly constantly (though the - * anchor frame may be rebased to a current system time, the linear correlation stays - * steady). Therefore, this method does not need to be called often. - * <p> - * To help users to get current playback position, this method always returns the timestamp of - * just-rendered frame, i.e., {@link System#nanoTime} and its corresponding media time. They - * can be used as current playback position. - * - * @return a MediaTimestamp object if a timestamp is available, or {@code null} if no timestamp - * is available, e.g. because the media sync has not been initialized. - */ + * Get current playback position. + * <p> + * The MediaTimestamp represents how the media time correlates to the system time in + * a linear fashion using an anchor and a clock rate. During regular playback, the media + * time moves fairly constantly (though the anchor frame may be rebased to a current + * system time, the linear correlation stays steady). Therefore, this method does not + * need to be called often. + * <p> + * To help users get current playback position, this method always anchors the timestamp + * to the current {@link System#nanoTime system time}, so + * {@link MediaTimestamp#getAnchorMediaTimeUs} can be used as current playback position. + * + * @return a MediaTimestamp object if a timestamp is available, or {@code null} if no timestamp + * is available, e.g. because the media player has not been initialized. + * + * @see MediaTimestamp + */ @Nullable public MediaTimestamp getTimestamp() { diff --git a/media/java/android/media/MediaTimestamp.java b/media/java/android/media/MediaTimestamp.java index d3d561826125..5ea6bbe8d001 100644 --- a/media/java/android/media/MediaTimestamp.java +++ b/media/java/android/media/MediaTimestamp.java @@ -37,22 +37,36 @@ package android.media; public final class MediaTimestamp { /** - * Media time in microseconds. + * Get the media time of the anchor in microseconds. */ - public final long mediaTimeUs; + public long getAnchorMediaTimeUs() { + return mediaTimeUs; + } /** - * The {@link java.lang.System#nanoTime system time} corresponding to the media time + * Get the {@link java.lang.System#nanoTime system time} corresponding to the media time * in nanoseconds. */ - public final long nanoTime; + public long getAnchorSytemNanoTime() { + return nanoTime; + } /** - * The rate of the media clock in relation to the system time. + * Get the rate of the media clock in relation to the system time. + * <p> * It is 1.0 if media clock advances in sync with the system clock; * greater than 1.0 if media clock is faster than the system clock; * less than 1.0 if media clock is slower than the system clock. */ + public float getMediaClockRate() { + return clockRate; + } + + /** @hide - accessor shorthand */ + public final long mediaTimeUs; + /** @hide - accessor shorthand */ + public final long nanoTime; + /** @hide - accessor shorthand */ public final float clockRate; /** @hide */ diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp index 043e20b895be..49614bdc76fd 100644 --- a/media/jni/android_media_ImageReader.cpp +++ b/media/jni/android_media_ImageReader.cpp @@ -1222,6 +1222,19 @@ static jint Image_getHeight(JNIEnv* env, jobject thiz, jint format) } } +static jint Image_getFormat(JNIEnv* env, jobject thiz, jint readerFormat) +{ + if (isFormatOpaque(readerFormat)) { + // Assuming opaque reader produce opaque images. + return static_cast<jint>(PublicFormat::PRIVATE); + } else { + CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz); + PublicFormat publicFmt = android_view_Surface_mapHalFormatDataspaceToPublicFormat( + buffer->flexFormat, buffer->dataSpace); + return static_cast<jint>(publicFmt); + } +} + } // extern "C" // ---------------------------------------------------------------------------- @@ -1240,8 +1253,9 @@ static JNINativeMethod gImageMethods[] = { {"nativeImageGetBuffer", "(II)Ljava/nio/ByteBuffer;", (void*)Image_getByteBuffer }, {"nativeCreatePlane", "(II)Landroid/media/ImageReader$SurfaceImage$SurfacePlane;", (void*)Image_createSurfacePlane }, - {"nativeGetWidth", "(I)I", (void*)Image_getWidth }, - {"nativeGetHeight", "(I)I", (void*)Image_getHeight }, + {"nativeGetWidth", "(I)I", (void*)Image_getWidth }, + {"nativeGetHeight", "(I)I", (void*)Image_getHeight }, + {"nativeGetFormat", "(I)I", (void*)Image_getFormat }, }; int register_android_media_ImageReader(JNIEnv *env) { diff --git a/media/jni/android_media_MediaDataSource.cpp b/media/jni/android_media_MediaDataSource.cpp index 1e6d2afa84b8..025133f3ff00 100644 --- a/media/jni/android_media_MediaDataSource.cpp +++ b/media/jni/android_media_MediaDataSource.cpp @@ -39,7 +39,7 @@ JMediaDataSource::JMediaDataSource(JNIEnv* env, jobject source) ScopedLocalRef<jclass> mediaDataSourceClass(env, env->GetObjectClass(mMediaDataSourceObj)); CHECK(mediaDataSourceClass.get() != NULL); - mReadMethod = env->GetMethodID(mediaDataSourceClass.get(), "readAt", "(J[BI)I"); + mReadMethod = env->GetMethodID(mediaDataSourceClass.get(), "readAt", "(J[BII)I"); CHECK(mReadMethod != NULL); mGetSizeMethod = env->GetMethodID(mediaDataSourceClass.get(), "getSize", "()J"); CHECK(mGetSizeMethod != NULL); @@ -80,7 +80,7 @@ ssize_t JMediaDataSource::readAt(off64_t offset, size_t size) { JNIEnv* env = AndroidRuntime::getJNIEnv(); jint numread = env->CallIntMethod(mMediaDataSourceObj, mReadMethod, - (jlong)offset, mByteArrayObj, (jint)size); + (jlong)offset, mByteArrayObj, (jint)0, (jint)size); if (env->ExceptionCheck()) { ALOGW("An exception occurred in readAt()"); LOGW_EX(env); @@ -89,9 +89,14 @@ ssize_t JMediaDataSource::readAt(off64_t offset, size_t size) { return -1; } if (numread < 0) { - ALOGW("An error occurred in readAt()"); - mJavaObjStatus = UNKNOWN_ERROR; - return -1; + if (numread != -1) { + ALOGW("An error occurred in readAt()"); + mJavaObjStatus = UNKNOWN_ERROR; + return -1; + } else { + // numread == -1 indicates EOF + return 0; + } } if ((size_t)numread > size) { ALOGE("readAt read too many bytes."); diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp index b6b7a80e6a3f..4e9b72685223 100644 --- a/media/jni/android_media_MediaExtractor.cpp +++ b/media/jni/android_media_MediaExtractor.cpp @@ -715,6 +715,11 @@ static void android_media_MediaExtractor_setDataSourceCallback( status_t err = extractor->setDataSource(bridge); if (err != OK) { + // Clear bridge so that JMediaDataSource::close() is called _before_ + // we throw the IOException. + // Otherwise close() gets called when we go out of scope, it calls + // Java with a pending exception and crashes the process. + bridge.clear(); jniThrowException( env, "java/io/IOException", diff --git a/packages/Keyguard/res/layout/keyguard_status_area.xml b/packages/Keyguard/res/layout/keyguard_status_area.xml index 7d8977c8a17d..8fe283519861 100644 --- a/packages/Keyguard/res/layout/keyguard_status_area.xml +++ b/packages/Keyguard/res/layout/keyguard_status_area.xml @@ -30,6 +30,8 @@ android:layout_height="wrap_content" android:textColor="@color/clock_white" style="@style/widget_label" + android:textAllCaps="true" + android:letterSpacing="0.15" android:gravity="center" /> <TextView android:id="@+id/alarm_status" @@ -38,6 +40,8 @@ android:drawablePadding="6dp" android:drawableStart="@drawable/ic_access_alarms_big" android:textColor="@color/clock_gray" + android:letterSpacing="0.15" + android:textAllCaps="true" style="@style/widget_label" android:layout_marginStart="6dp" android:gravity="center" diff --git a/packages/Keyguard/res/layout/keyguard_status_view.xml b/packages/Keyguard/res/layout/keyguard_status_view.xml index 69f510e320da..fc0b568a9acf 100644 --- a/packages/Keyguard/res/layout/keyguard_status_view.xml +++ b/packages/Keyguard/res/layout/keyguard_status_view.xml @@ -57,6 +57,7 @@ android:layout_gravity="center_horizontal" android:textColor="@color/clock_gray" android:textSize="@dimen/widget_label_font_size" + android:letterSpacing="0.05" android:ellipsize="marquee" android:singleLine="true" /> diff --git a/packages/Keyguard/res/values-h650dp/dimens.xml b/packages/Keyguard/res/values-h650dp/dimens.xml index 48643268a9bd..92035bbc0977 100644 --- a/packages/Keyguard/res/values-h650dp/dimens.xml +++ b/packages/Keyguard/res/values-h650dp/dimens.xml @@ -16,5 +16,5 @@ --> <resources> - <dimen name="widget_big_font_size">112dp</dimen> + <dimen name="widget_big_font_size">104dp</dimen> </resources>
\ No newline at end of file diff --git a/packages/Keyguard/res/values-sw600dp/dimens.xml b/packages/Keyguard/res/values-sw600dp/dimens.xml index 5de1d110e0e2..b181682f90ba 100644 --- a/packages/Keyguard/res/values-sw600dp/dimens.xml +++ b/packages/Keyguard/res/values-sw600dp/dimens.xml @@ -26,7 +26,7 @@ <dimen name="keyguard_security_view_margin">12dp</dimen> <!-- Overload default clock widget parameters --> - <dimen name="widget_big_font_size">140dp</dimen> + <dimen name="widget_big_font_size">125dp</dimen> <dimen name="widget_label_font_size">16sp</dimen> <dimen name="bottom_text_spacing_digital">-16dp</dimen> diff --git a/packages/Keyguard/res/values-sw720dp/dimens.xml b/packages/Keyguard/res/values-sw720dp/dimens.xml index 428c18e795d0..08ab791f856e 100644 --- a/packages/Keyguard/res/values-sw720dp/dimens.xml +++ b/packages/Keyguard/res/values-sw720dp/dimens.xml @@ -24,5 +24,5 @@ <!-- Height of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) --> <dimen name="keyguard_security_height">420dp</dimen> - <dimen name="widget_big_font_size">150dp</dimen> + <dimen name="widget_big_font_size">138dp</dimen> </resources> diff --git a/packages/Keyguard/res/values/colors.xml b/packages/Keyguard/res/values/colors.xml index 3b741eaff8a4..3998c5b8ad57 100644 --- a/packages/Keyguard/res/values/colors.xml +++ b/packages/Keyguard/res/values/colors.xml @@ -17,5 +17,5 @@ <!-- Clock --> <color name="clock_white">#ffffffff</color> - <color name="clock_gray">#99ffffff</color> + <color name="clock_gray">@*android:color/secondary_text_default_material_dark</color> </resources> diff --git a/packages/Keyguard/res/values/dimens.xml b/packages/Keyguard/res/values/dimens.xml index 92902361e71d..18d893a7b3f1 100644 --- a/packages/Keyguard/res/values/dimens.xml +++ b/packages/Keyguard/res/values/dimens.xml @@ -40,7 +40,7 @@ <!-- Default clock parameters --> <dimen name="bottom_text_spacing_digital">-10dp</dimen> - <dimen name="widget_label_font_size">16sp</dimen> + <dimen name="widget_label_font_size">14sp</dimen> <dimen name="widget_big_font_size">88dp</dimen> <!-- The y translation to apply at the start in appear animations. --> diff --git a/packages/Keyguard/res/values/styles.xml b/packages/Keyguard/res/values/styles.xml index 404a17eabd91..943c3eabb69c 100644 --- a/packages/Keyguard/res/values/styles.xml +++ b/packages/Keyguard/res/values/styles.xml @@ -41,7 +41,7 @@ </style> <style name="widget_big_thin"> <item name="android:textSize">@dimen/widget_big_font_size</item> - <item name="android:fontFamily">sans-serif-thin</item> + <item name="android:fontFamily">sans-serif-light</item> </style> <style name="BouncerSecurityContainer"> diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java index db5616136bb8..54bbd5a11139 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java @@ -174,9 +174,16 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout }.start(); } + protected void onUserInput() { + if (mCallback != null) { + mCallback.userActivity(); + } + mSecurityMessageDisplay.setMessage("", false); + } + @Override public boolean onKeyDown(int keyCode, KeyEvent event) { - mCallback.userActivity(); + onUserInput(); return false; } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java index 7ddeab4f5384..40fd92046f7f 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java @@ -88,24 +88,33 @@ class KeyguardMessageArea extends TextView { } } + @Override public void setMessage(CharSequence msg, boolean important) { if (!TextUtils.isEmpty(msg) && important) { mMessageArea.mMessage = msg; mMessageArea.securityMessageChanged(); + } else { + mMessageArea.clearMessage(); } } + @Override public void setMessage(int resId, boolean important) { if (resId != 0 && important) { mMessageArea.mMessage = mMessageArea.getContext().getResources().getText(resId); mMessageArea.securityMessageChanged(); + } else { + mMessageArea.clearMessage(); } } + @Override public void setMessage(int resId, boolean important, Object... formatArgs) { if (resId != 0 && important) { mMessageArea.mMessage = mMessageArea.getContext().getString(resId, formatArgs); mMessageArea.securityMessageChanged(); + } else { + mMessageArea.clearMessage(); } } @@ -176,6 +185,11 @@ class KeyguardMessageArea extends TextView { (SystemClock.uptimeMillis() + ANNOUNCEMENT_DELAY)); } + public void clearMessage() { + mHandler.removeCallbacks(mClearMessageRunnable); + mHandler.post(mClearMessageRunnable); + } + /** * Update the status lines based on these rules: * AlarmStatus: Alarm state always gets it's own line. diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java index 929258d5937a..3fcc3c3180d5 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java @@ -20,6 +20,7 @@ import android.content.Context; import android.graphics.Rect; import android.text.Editable; import android.text.InputType; +import android.text.TextUtils; import android.text.TextWatcher; import android.text.method.TextKeyListener; import android.util.AttributeSet; @@ -138,20 +139,6 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView // Set selected property on so the view can send accessibility events. mPasswordEntry.setSelected(true); - mPasswordEntry.addTextChangedListener(new TextWatcher() { - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - public void afterTextChanged(Editable s) { - if (mCallback != null) { - mCallback.userActivity(); - } - } - }); - mPasswordEntry.requestFocus(); // If there's more than one IME, enable the IME switcher button @@ -293,6 +280,11 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView @Override public void afterTextChanged(Editable s) { + // Poor man's user edit detection, assuming empty text is programmatic and everything else + // is from the user. + if (!TextUtils.isEmpty(s)) { + onUserInput(); + } } @Override diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java index f67b2e707dc7..35c68735d873 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java @@ -208,6 +208,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit public void onPatternStart() { mLockPatternView.removeCallbacks(mCancelPatternRunnable); + mSecurityMessageDisplay.setMessage("", false); } public void onPatternCleared() { diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java index bca030527ac9..84b4cf869d0a 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java @@ -148,7 +148,14 @@ public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView // Poke the wakelock any time the text is selected or modified mPasswordEntry.setOnClickListener(new OnClickListener() { public void onClick(View v) { - mCallback.userActivity(); + onUserInput(); + } + }); + + mPasswordEntry.setUserActivityListener(new PasswordTextView.UserActivityListener() { + @Override + public void onUserActivity() { + onUserInput(); } }); diff --git a/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java index 67ddcfaa2041..50e7ecb92ffc 100644 --- a/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java +++ b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java @@ -92,6 +92,11 @@ public class PasswordTextView extends View { private Interpolator mDisappearInterpolator; private Interpolator mFastOutSlowInInterpolator; private boolean mShowPassword; + private UserActivityListener mUserActivityListener; + + public interface UserActivityListener { + void onUserActivity(); + } public PasswordTextView(Context context) { this(context, null); @@ -206,8 +211,15 @@ public class PasswordTextView extends View { sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length(), 0, 1); } + public void setUserActivityListener(UserActivityListener userActivitiListener) { + mUserActivityListener = userActivitiListener; + } + private void userActivity() { mPM.userActivity(SystemClock.uptimeMillis(), false); + if (mUserActivityListener != null) { + mUserActivityListener.onUserActivity(); + } } public void deleteLastChar() { diff --git a/packages/StatementService/src/com/android/statementservice/retriever/AbstractStatementRetriever.java b/packages/StatementService/src/com/android/statementservice/retriever/AbstractStatementRetriever.java index fb30bc16ccbd..3b59fd6a5d83 100644 --- a/packages/StatementService/src/com/android/statementservice/retriever/AbstractStatementRetriever.java +++ b/packages/StatementService/src/com/android/statementservice/retriever/AbstractStatementRetriever.java @@ -90,7 +90,7 @@ public abstract class AbstractStatementRetriever { * Creates a new StatementRetriever that directly retrieves statements from the asset. * * <p> For web assets, {@link AbstractStatementRetriever} will try to retrieve the statement - * file from URL: {@code [webAsset.site]/.well-known/associations.json"} where {@code + * file from URL: {@code [webAsset.site]/.well-known/statements.json"} where {@code * [webAsset.site]} is in the form {@code http{s}://[hostname]:[optional_port]}. The file * should contain one JSON array of statements. * diff --git a/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java b/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java index 3ad71c44b528..6516516f0847 100644 --- a/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java +++ b/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java @@ -38,7 +38,7 @@ import java.util.List; private static final int HTTP_CONNECTION_TIMEOUT_MILLIS = 5000; private static final long HTTP_CONTENT_SIZE_LIMIT_IN_BYTES = 1024 * 1024; private static final int MAX_INCLUDE_LEVEL = 1; - private static final String WELL_KNOWN_STATEMENT_PATH = "/.well-known/associations.json"; + private static final String WELL_KNOWN_STATEMENT_PATH = "/.well-known/statements.json"; private final URLFetcher mUrlFetcher; private final AndroidPackageInfoFetcher mAndroidFetcher; diff --git a/packages/StatementService/src/com/android/statementservice/retriever/Statement.java b/packages/StatementService/src/com/android/statementservice/retriever/Statement.java index f83edafe0eae..da3c3553d731 100644 --- a/packages/StatementService/src/com/android/statementservice/retriever/Statement.java +++ b/packages/StatementService/src/com/android/statementservice/retriever/Statement.java @@ -21,7 +21,7 @@ import android.annotation.NonNull; /** * An immutable value type representing a statement, consisting of a source, target, and relation. * This reflects an assertion that the relation holds for the source, target pair. For example, if a - * web site has the following in its associations.json file: + * web site has the following in its statements.json file: * * <pre> * { diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml index 539aabf2c0a4..03b6dca8f72e 100644 --- a/packages/SystemUI/res/layout/super_status_bar.xml +++ b/packages/SystemUI/res/layout/super_status_bar.xml @@ -63,7 +63,7 @@ android:layout_gravity="@integer/notification_panel_layout_gravity" android:paddingLeft="@dimen/notification_side_padding" android:paddingRight="@dimen/notification_side_padding" - android:visibility="gone"> + android:visibility="invisible"> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index be33085f68eb..715f4e443d21 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -194,7 +194,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi // we compose the final post-save notification below. mNotificationBuilder.setLargeIcon(croppedIcon); // But we still don't set it for the expanded view, allowing the smallIcon to show here. - mNotificationStyle.bigLargeIcon((Bitmap) null); + mNotificationStyle.bigLargeIcon(null); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 1e488f39ee57..2913c7df1f78 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -1390,9 +1390,9 @@ public abstract class BaseStatusBar extends SystemUI implements final ImageView profileBadge = (ImageView) publicViewLocal.findViewById( R.id.profile_badge_line3); - final StatusBarIcon ic = new StatusBarIcon( + final StatusBarIcon ic = new StatusBarIcon(entry.notification.getPackageName(), entry.notification.getUser(), - entry.notification.getNotification().getSmallIcon(), + entry.notification.getNotification().icon, entry.notification.getNotification().iconLevel, entry.notification.getNotification().number, entry.notification.getNotification().tickerText); @@ -1770,9 +1770,9 @@ public abstract class BaseStatusBar extends SystemUI implements sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), n); iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); - final StatusBarIcon ic = new StatusBarIcon( + final StatusBarIcon ic = new StatusBarIcon(sbn.getPackageName(), sbn.getUser(), - n.getSmallIcon(), + n.icon, n.iconLevel, n.number, n.tickerText); @@ -1916,9 +1916,9 @@ public abstract class BaseStatusBar extends SystemUI implements try { if (entry.icon != null) { // Update the icon - final StatusBarIcon ic = new StatusBarIcon( + final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(), notification.getUser(), - n.getSmallIcon(), + n.icon, n.iconLevel, n.number, n.tickerText); @@ -1938,9 +1938,9 @@ public abstract class BaseStatusBar extends SystemUI implements } if (!updateSuccessful) { if (DEBUG) Log.d(TAG, "not reusing notification for key: " + key); - final StatusBarIcon ic = new StatusBarIcon( + final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(), notification.getUser(), - n.getSmallIcon(), + n.icon, n.iconLevel, n.number, n.tickerText); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index 3294e15ab3a5..e6847d8ce5e2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -24,7 +24,6 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; -import android.graphics.drawable.Icon; import android.os.UserHandle; import android.text.TextUtils; import android.util.AttributeSet; @@ -101,23 +100,13 @@ public class StatusBarIconView extends AnimatedImageView { return a.equals(b); } - public boolean equalIcons(Icon a, Icon b) { - if (a == b) return true; - if (a.getType() != b.getType()) return false; - switch (a.getType()) { - case Icon.TYPE_RESOURCE: - return a.getResPackage().equals(b.getResPackage()) && a.getResId() == b.getResId(); - case Icon.TYPE_URI: - return a.getUriString().equals(b.getUriString()); - default: - return false; - } - } /** * Returns whether the set succeeded. */ public boolean set(StatusBarIcon icon) { - final boolean iconEquals = mIcon != null && equalIcons(mIcon.icon, icon.icon); + final boolean iconEquals = mIcon != null + && streq(mIcon.iconPackage, icon.iconPackage) + && mIcon.iconId == icon.iconId; final boolean levelEquals = iconEquals && mIcon.iconLevel == icon.iconLevel; final boolean visibilityEquals = mIcon != null @@ -178,18 +167,45 @@ public class StatusBarIconView extends AnimatedImageView { } /** - * Returns the right icon to use for this item + * Returns the right icon to use for this item, respecting the iconId and + * iconPackage (if set) * - * @param context Context to use to get resources + * @param context Context to use to get resources if iconPackage is not set * @return Drawable for this item, or null if the package or item could not * be found */ public static Drawable getIcon(Context context, StatusBarIcon icon) { - int userId = icon.user.getIdentifier(); - if (userId == UserHandle.USER_ALL) { - userId = UserHandle.USER_OWNER; + Resources r = null; + + if (icon.iconPackage != null) { + try { + int userId = icon.user.getIdentifier(); + if (userId == UserHandle.USER_ALL) { + userId = UserHandle.USER_OWNER; + } + r = context.getPackageManager() + .getResourcesForApplicationAsUser(icon.iconPackage, userId); + } catch (PackageManager.NameNotFoundException ex) { + Log.e(TAG, "Icon package not found: " + icon.iconPackage); + return null; + } + } else { + r = context.getResources(); } - return icon.icon.loadDrawableAsUser(context, userId); + + if (icon.iconId == 0) { + return null; + } + + try { + return r.getDrawable(icon.iconId); + } catch (RuntimeException e) { + Log.w(TAG, "Icon not found in " + + (icon.iconPackage != null ? icon.iconId : "<system>") + + ": " + Integer.toHexString(icon.iconId)); + } + + return null; } public StatusBarIcon getStatusBarIcon() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java index 26d1c867ab08..44168bc71383 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java @@ -16,7 +16,6 @@ package com.android.systemui.statusbar.phone; -import android.graphics.drawable.Icon; import android.os.Bundle; import android.os.UserHandle; import android.view.Gravity; @@ -133,7 +132,8 @@ public class DemoStatusIcons extends LinearLayout implements DemoMode { break; } else { StatusBarIcon icon = v.getStatusBarIcon(); - icon.icon = Icon.createWithResource(icon.icon.getResPackage(), iconId); + icon.iconPackage = iconPkg; + icon.iconId = iconId; v.set(icon); v.updateDrawable(); return; @@ -152,4 +152,4 @@ public class DemoStatusIcons extends LinearLayout implements DemoMode { v.set(icon); addView(v, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize)); } -} +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java index 38812cede919..c8b8b24bf80e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -616,6 +616,9 @@ public abstract class PanelView extends FrameLayout { boolean expandBecauseOfFalsing) { cancelPeek(); float target = expand ? getMaxPanelHeight() : 0.0f; + if (!expand) { + mClosing = true; + } flingToHeight(vel, expand, target, collapseSpeedUpFactor, expandBecauseOfFalsing); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 808f1ff2edf5..450fdd93e8e7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -45,7 +45,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, public static final long ANIMATION_DURATION = 220; private static final float SCRIM_BEHIND_ALPHA = 0.62f; - private static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.55f; + private static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.45f; private static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f; private static final float SCRIM_IN_FRONT_ALPHA = 0.75f; private static final int TAG_KEY_ANIM = R.id.scrim; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java index 895af628e1d2..03409846ed40 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java @@ -58,7 +58,7 @@ public class BrightnessMirrorController { .withEndAction(new Runnable() { @Override public void run() { - mBrightnessMirror.setVisibility(View.GONE); + mBrightnessMirror.setVisibility(View.INVISIBLE); } }); } @@ -77,12 +77,18 @@ public class BrightnessMirrorController { public void setLocation(View original) { original.getLocationInWindow(mInt2Cache); + + // Original is slightly larger than the mirror, so make sure to use the center for the + // positioning. + int originalX = mInt2Cache[0] + original.getWidth()/2; int originalY = mInt2Cache[1]; + mBrightnessMirror.setTranslationX(0); + mBrightnessMirror.setTranslationY(0); mBrightnessMirror.getLocationInWindow(mInt2Cache); + int mirrorX = mInt2Cache[0] + mBrightnessMirror.getWidth()/2; int mirrorY = mInt2Cache[1]; - - mBrightnessMirror.setTranslationY(mBrightnessMirror.getTranslationY() - + originalY - mirrorY); + mBrightnessMirror.setTranslationX(originalX - mirrorX); + mBrightnessMirror.setTranslationY(originalY - mirrorY); } public View getMirror() { diff --git a/preloaded-classes b/preloaded-classes index d2ed7625d602..41a88579389e 100644 --- a/preloaded-classes +++ b/preloaded-classes @@ -1152,8 +1152,8 @@ android.provider.Settings$SettingNotFoundException android.provider.Settings$System android.provider.Telephony$Mms android.renderscript.RenderScript -android.security.AndroidKeyStoreBCWorkaroundProvider -android.security.AndroidKeyStoreProvider +android.security.keystore.AndroidKeyStoreBCWorkaroundProvider +android.security.keystore.AndroidKeyStoreProvider android.speech.tts.TextToSpeechService android.speech.tts.TextToSpeechService$SpeechItemV1 android.speech.tts.TextToSpeechService$SynthesisSpeechItemV1 diff --git a/rs/java/android/renderscript/Element.java b/rs/java/android/renderscript/Element.java index 4b3e30f3750a..6efb6d6a5735 100644 --- a/rs/java/android/renderscript/Element.java +++ b/rs/java/android/renderscript/Element.java @@ -536,8 +536,8 @@ public class Element extends BaseObj { } public static Element F16_3(RenderScript rs) { - if(rs.mElement_FLOAT_3 == null) { - rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_16, 3); + if(rs.mElement_HALF_3 == null) { + rs.mElement_HALF_3 = createVector(rs, DataType.FLOAT_16, 3); } return rs.mElement_HALF_3; } @@ -911,6 +911,7 @@ public class Element extends BaseObj { switch (dt) { // Support only primitive integer/float/boolean types as vectors. + case FLOAT_16: case FLOAT_32: case FLOAT_64: case SIGNED_8: diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java index 27f2cc8aa9e8..8b1a0324956a 100644 --- a/rs/java/android/renderscript/RenderScript.java +++ b/rs/java/android/renderscript/RenderScript.java @@ -134,6 +134,20 @@ public class RenderScript { static final long sMinorVersion = 1; /** + * @hide + * + * Only exist to be compatible with old version RenderScript Support lib. + * Will eventually be removed. + * + * @return Always return 1 + * + */ + public static long getMinorID() { + return 1; + } + + + /** * Returns an identifier that can be used to identify a particular * minor version of RS. * diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 0961ffe1ffdc..16b3dcfa8b85 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1982,7 +1982,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (msg.arg1 == 0) { setProvNotificationVisibleIntent(false, msg.arg2, 0, null, null); } else { - NetworkAgentInfo nai = null; + final NetworkAgentInfo nai; synchronized (mNetworkForNetId) { nai = mNetworkForNetId.get(msg.arg2); } @@ -1990,6 +1990,7 @@ public class ConnectivityService extends IConnectivityManager.Stub loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor"); break; } + nai.captivePortalDetected = true; setProvNotificationVisibleIntent(true, msg.arg2, nai.networkInfo.getType(), nai.networkInfo.getExtraInfo(), (PendingIntent)msg.obj); } @@ -2384,7 +2385,8 @@ public class ConnectivityService extends IConnectivityManager.Stub // Only prompt if the network is unvalidated and was explicitly selected by the user, and if // we haven't already been told to switch to it regardless of whether it validated or not. - if (nai == null || nai.everValidated || + // Also don't prompt on captive portals because we're already prompting the user to sign in. + if (nai == null || nai.everValidated || nai.captivePortalDetected || !nai.networkMisc.explicitlySelected || nai.networkMisc.acceptUnvalidated) { return; } diff --git a/services/core/java/com/android/server/WiredAccessoryManager.java b/services/core/java/com/android/server/WiredAccessoryManager.java index 0de8c8dd9df5..e0e6070a811a 100644 --- a/services/core/java/com/android/server/WiredAccessoryManager.java +++ b/services/core/java/com/android/server/WiredAccessoryManager.java @@ -216,9 +216,9 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks { mWakeLock.acquire(); - Log.i(TAG, "MSG_NEW_DEVICE_STATE "); + Log.i(TAG, "MSG_NEW_DEVICE_STATE"); Message msg = mHandler.obtainMessage(MSG_NEW_DEVICE_STATE, headsetState, - mHeadsetState, newName); + mHeadsetState, ""); mHandler.sendMessage(msg); mHeadsetState = headsetState; diff --git a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java index d64e39f79e72..925fae0a3431 100644 --- a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java +++ b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java @@ -51,6 +51,7 @@ class ActivityManagerDebugConfig { static final boolean DEBUG_FOCUS = false; static final boolean DEBUG_IMMERSIVE = DEBUG_ALL || false; static final boolean DEBUG_LOCKSCREEN = DEBUG_ALL || false; + static final boolean DEBUG_LOCKTASK = DEBUG_ALL || false; static final boolean DEBUG_LRU = DEBUG_ALL || false; static final boolean DEBUG_MU = DEBUG_ALL || false; static final boolean DEBUG_OOM_ADJ = DEBUG_ALL || false; @@ -82,6 +83,7 @@ class ActivityManagerDebugConfig { static final String POSTFIX_FOCUS = (APPEND_CATEGORY_NAME) ? "_Focus" : ""; static final String POSTFIX_IMMERSIVE = (APPEND_CATEGORY_NAME) ? "_Immersive" : ""; static final String POSTFIX_LOCKSCREEN = (APPEND_CATEGORY_NAME) ? "_LOCKSCREEN" : ""; + static final String POSTFIX_LOCKTASK = (APPEND_CATEGORY_NAME) ? "_LOCKTASK" : ""; static final String POSTFIX_LRU = (APPEND_CATEGORY_NAME) ? "_LRU" : ""; static final String POSTFIX_MU = "_MU"; static final String POSTFIX_OOM_ADJ = (APPEND_CATEGORY_NAME) ? "_OomAdj" : ""; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 9ffb874d2436..215839515a4e 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -265,6 +265,7 @@ public final class ActivityManagerService extends ActivityManagerNative private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS; private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE; private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN; + private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; private static final String TAG_LRU = TAG + POSTFIX_LRU; private static final String TAG_MU = TAG + POSTFIX_MU; private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ; @@ -8762,6 +8763,7 @@ public final class ActivityManagerService extends ActivityManagerNative throw new SecurityException("updateLockTaskPackage called from non-system process"); } synchronized (this) { + if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" + packages); mLockTaskPackages.put(userId, packages); mStackSupervisor.onLockTaskPackagesUpdatedLocked(); } @@ -8769,6 +8771,7 @@ public final class ActivityManagerService extends ActivityManagerNative void startLockTaskModeLocked(TaskRecord task) { + if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task); if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { return; } @@ -8785,6 +8788,7 @@ public final class ActivityManagerService extends ActivityManagerNative task.mLockTaskUid = callingUid; if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) { // startLockTask() called by app and task mode is lockTaskModeDefault. + if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user"); StatusBarManagerInternal statusBarManager = LocalServices.getService(StatusBarManagerInternal.class); if (statusBarManager != null) { @@ -8797,6 +8801,8 @@ public final class ActivityManagerService extends ActivityManagerNative throw new IllegalArgumentException("Invalid task, not in foreground"); } } + if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" : + "Locking fully"); mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ? ActivityManager.LOCK_TASK_MODE_PINNED : ActivityManager.LOCK_TASK_MODE_LOCKED, diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 54ea6d76782c..f30482852108 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -117,6 +117,7 @@ import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Set; @@ -124,6 +125,7 @@ public final class ActivityStackSupervisor implements DisplayListener { private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM; private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS; + private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE; private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS; private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS; @@ -1183,7 +1185,7 @@ public final class ActivityStackSupervisor implements DisplayListener { final TaskRecord task = r.task; if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) { - setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "lockTaskLaunchMode attribute"); + setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE"); } final ActivityStack stack = task.stack; @@ -3327,6 +3329,18 @@ public final class ActivityStackSupervisor implements DisplayListener { } } + private String lockTaskModeToString() { + switch (mLockTaskModeState) { + case LOCK_TASK_MODE_LOCKED: + return "LOCKED"; + case LOCK_TASK_MODE_PINNED: + return "PINNED"; + case LOCK_TASK_MODE_NONE: + return "NONE"; + default: return "unknown=" + mLockTaskModeState; + } + } + public void dump(PrintWriter pw, String prefix) { pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); @@ -3334,7 +3348,16 @@ public final class ActivityStackSupervisor implements DisplayListener { pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId); pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); - pw.print(prefix); pw.println("mLockTaskModeTasks" + mLockTaskModeTasks); + pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString()); + final SparseArray<String[]> packages = mService.mLockTaskPackages; + if (packages.size() > 0) { + pw.println(" mLockTaskPackages (userId:packages)="); + for (int i = 0; i < packages.size(); ++i) { + pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i)); + pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i))); + } + } + pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks); } ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { @@ -3654,6 +3677,8 @@ public final class ActivityStackSupervisor implements DisplayListener { void removeLockedTaskLocked(final TaskRecord task) { if (mLockTaskModeTasks.remove(task) && mLockTaskModeTasks.isEmpty()) { // Last one. + if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task + + " last task, reverting locktask mode. Callers=" + Debug.getCallers(3)); final Message lockTaskMsg = Message.obtain(); lockTaskMsg.arg1 = task.userId; lockTaskMsg.what = LOCK_TASK_END_MSG; @@ -3679,20 +3704,26 @@ public final class ActivityStackSupervisor implements DisplayListener { removeLockedTaskLocked(lockedTask); if (!mLockTaskModeTasks.isEmpty()) { // There are locked tasks remaining, can only finish this task, not unlock it. + if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, + "setLockTaskModeLocked: Tasks remaining, can't unlock"); lockedTask.performClearTaskLocked(); resumeTopActivitiesLocked(); return; } } + if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, + "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4)); return; } // Should have already been checked, but do it again. if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { + if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, + "setLockTaskModeLocked: Can't lock due to auth"); return; } if (isLockTaskModeViolation(task)) { - Slog.e(TAG, "setLockTaskMode: Attempt to start an unauthorized lock task."); + Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task."); return; } @@ -3706,6 +3737,8 @@ public final class ActivityStackSupervisor implements DisplayListener { mHandler.sendMessage(lockTaskMsg); } // Add it or move it to the top. + if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task + + " Callers=" + Debug.getCallers(4)); mLockTaskModeTasks.remove(task); mLockTaskModeTasks.add(task); @@ -3759,6 +3792,13 @@ public final class ActivityStackSupervisor implements DisplayListener { stack.onLockTaskPackagesUpdatedLocked(); } } + final ActivityRecord r = topRunningActivityLocked(); + final TaskRecord task = r != null ? r.task : null; + if (mLockTaskModeTasks.isEmpty() && task != null + && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) { + // This task must have just been authorized. + setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated"); + } if (didSomething) { resumeTopActivitiesLocked(); } diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index 5e9f2b0b321a..f653e9eeaf24 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -63,6 +63,7 @@ import java.util.ArrayList; final class TaskRecord { private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM; private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS; + private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; private static final String TAG_TASKS = TAG + POSTFIX_TASKS; static final String ATTR_TASKID = "task_id"; @@ -134,12 +135,11 @@ final class TaskRecord { /** Can't be put in lockTask mode. */ final static int LOCK_TASK_AUTH_DONT_LOCK = 0; - /** Can enter lockTask with user approval if not already in lockTask. */ + /** Can enter lockTask with user approval. Can never start over existing lockTask task. */ final static int LOCK_TASK_AUTH_PINNABLE = 1; /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */ final static int LOCK_TASK_AUTH_LAUNCHABLE = 2; - /** Enters LOCK_TASK_MODE_LOCKED via startLockTask(), enters LOCK_TASK_MODE_PINNED from - * Overview. Can start over existing lockTask task. */ + /** Can enter lockTask with user approval. Can start over existing lockTask task. */ final static int LOCK_TASK_AUTH_WHITELISTED = 3; int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE; @@ -744,21 +744,31 @@ final class TaskRecord { void setLockTaskAuth() { switch (mLockTaskMode) { case LOCK_TASK_LAUNCH_MODE_DEFAULT: + if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this + + " mLockTaskAuth=" + (isLockTaskWhitelistedLocked() ? + "WHITELISTED" : "PINNABLE")); mLockTaskAuth = isLockTaskWhitelistedLocked() ? LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE; break; case LOCK_TASK_LAUNCH_MODE_NEVER: + if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this + + " mLockTaskAuth=" + (mPrivileged ? "DONT_LOCK" : "PINNABLE")); mLockTaskAuth = mPrivileged ? LOCK_TASK_AUTH_DONT_LOCK : LOCK_TASK_AUTH_PINNABLE; break; case LOCK_TASK_LAUNCH_MODE_ALWAYS: + if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this + + " mLockTaskAuth=" + (mPrivileged ? "LAUNCHABLE" : "PINNABLE")); mLockTaskAuth = mPrivileged ? LOCK_TASK_AUTH_LAUNCHABLE: LOCK_TASK_AUTH_PINNABLE; break; case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED: + if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this + + " mLockTaskAuth=" + (isLockTaskWhitelistedLocked() ? + "LAUNCHABLE" : "PINNABLE")); mLockTaskAuth = isLockTaskWhitelistedLocked() ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE; break; diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 47ddfec747c5..6c83192a43ad 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -564,8 +564,6 @@ public class AudioService extends IAudioService.Stub { return "card=" + card + ";device=" + device + ";"; } - private final String DEVICE_NAME_A2DP = "a2dp-device"; - /////////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////////// @@ -4387,7 +4385,7 @@ public class AudioService extends IAudioService.Stub { } // must be called synchronized on mConnectedDevices - private void makeA2dpDeviceAvailable(String address) { + private void makeA2dpDeviceAvailable(String address, String name) { // enable A2DP before notifying A2DP connection to avoid unecessary processing in // audio policy manager VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC]; @@ -4395,12 +4393,12 @@ public class AudioService extends IAudioService.Stub { AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, streamState, 0); setBluetoothA2dpOnInt(true); AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, - AudioSystem.DEVICE_STATE_AVAILABLE, address, DEVICE_NAME_A2DP); + AudioSystem.DEVICE_STATE_AVAILABLE, address, name); // Reset A2DP suspend state each time a new sink is connected AudioSystem.setParameters("A2dpSuspended=false"); mConnectedDevices.put( makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address), - new DeviceListSpec(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, DEVICE_NAME_A2DP, + new DeviceListSpec(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, name, address)); } @@ -4414,7 +4412,7 @@ public class AudioService extends IAudioService.Stub { mAvrcpAbsVolSupported = false; } AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, - AudioSystem.DEVICE_STATE_UNAVAILABLE, address, DEVICE_NAME_A2DP); + AudioSystem.DEVICE_STATE_UNAVAILABLE, address, ""); mConnectedDevices.remove( makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address)); synchronized (mCurAudioRoutes) { @@ -4444,17 +4442,17 @@ public class AudioService extends IAudioService.Stub { // must be called synchronized on mConnectedDevices private void makeA2dpSrcAvailable(String address) { AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, - AudioSystem.DEVICE_STATE_AVAILABLE, address, DEVICE_NAME_A2DP); + AudioSystem.DEVICE_STATE_AVAILABLE, address, ""); mConnectedDevices.put( makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address), - new DeviceListSpec(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, DEVICE_NAME_A2DP, + new DeviceListSpec(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, "", address)); } // must be called synchronized on mConnectedDevices private void makeA2dpSrcUnavailable(String address) { AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, - AudioSystem.DEVICE_STATE_UNAVAILABLE, address, DEVICE_NAME_A2DP); + AudioSystem.DEVICE_STATE_UNAVAILABLE, address, ""); mConnectedDevices.remove( makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address)); } @@ -4520,7 +4518,7 @@ public class AudioService extends IAudioService.Stub { makeA2dpDeviceUnavailableNow(mDockAddress); } } - makeA2dpDeviceAvailable(address); + makeA2dpDeviceAvailable(address, btDevice.getName()); synchronized (mCurAudioRoutes) { String name = btDevice.getAliasName(); if (!TextUtils.equals(mCurAudioRoutes.bluetoothName, name)) { @@ -4871,7 +4869,7 @@ public class AudioService extends IAudioService.Stub { if (btDevice == null) { return; } - + address = btDevice.getAddress(); BluetoothClass btClass = btDevice.getBluetoothClass(); if (btClass != null) { @@ -4891,9 +4889,11 @@ public class AudioService extends IAudioService.Stub { } boolean connected = (state == BluetoothProfile.STATE_CONNECTED); + + String btDeviceName = btDevice.getName(); boolean success = - handleDeviceConnection(connected, outDevice, address, "Bluetooth Headset") && - handleDeviceConnection(connected, inDevice, address, "Bluetooth Headset"); + handleDeviceConnection(connected, outDevice, address, btDeviceName) && + handleDeviceConnection(connected, inDevice, address, btDeviceName); if (success) { synchronized (mScoClients) { if (connected) { diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index 8a7c9020d952..eac748f4cff7 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -50,12 +50,11 @@ public class NetworkAgentInfo { public final NetworkMisc networkMisc; // Indicates if netd has been told to create this Network. Once created the appropriate routing // rules are setup and routes are added so packets can begin flowing over the Network. - // NOTE: This is a sticky bit; once set it is never cleared. + // This is a sticky bit; once set it is never cleared. public boolean created; // Set to true if this Network successfully passed validation or if it did not satisfy the // default NetworkRequest in which case validation will not be attempted. - // NOTE: This is a sticky bit; once set it is never cleared even if future validation attempts - // fail. + // This is a sticky bit; once set it is never cleared even if future validation attempts fail. public boolean everValidated; // The result of the last validation attempt on this network (true if validated, false if not). @@ -65,6 +64,10 @@ public class NetworkAgentInfo { // TODO: Fix the network scoring code, remove this, and rename everValidated to validated. public boolean lastValidated; + // Whether a captive portal was ever detected on this network. + // This is a sticky bit; once set it is never cleared. + public boolean captivePortalDetected; + // This represents the last score received from the NetworkAgent. private int currentScore; // Penalty applied to scores of Networks that have not been validated. @@ -101,9 +104,6 @@ public class NetworkAgentInfo { currentScore = score; networkMonitor = new NetworkMonitor(context, handler, this, defaultRequest); networkMisc = misc; - created = false; - everValidated = false; - lastValidated = false; } public void addRequest(NetworkRequest networkRequest) { @@ -166,6 +166,7 @@ public class NetworkAgentInfo { "created{" + created + "} " + "explicitlySelected{" + networkMisc.explicitlySelected + "} " + "acceptUnvalidated{" + networkMisc.acceptUnvalidated + "} " + + "captivePortalDetected{" + captivePortalDetected + "} " + "}"; } diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 66f7861e30c0..c37f619fca37 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -392,10 +392,6 @@ public final class HdmiControlService extends SystemService { mCecController = HdmiCecController.create(this); if (mCecController != null) { - // TODO: Remove this as soon as OEM's HAL implementation is corrected. - mCecController.setOption(OPTION_CEC_ENABLE, ENABLED); - - // TODO: load value for mHdmiControlEnabled from preference. if (mHdmiControlEnabled) { initializeCec(INITIATED_BY_BOOT_UP); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 764d08576c61..ec039b00af60 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -2018,7 +2018,7 @@ public class NotificationManagerService extends SystemService { throw new IllegalArgumentException("null not allowed: pkg=" + pkg + " id=" + id + " notification=" + notification); } - if (notification.getSmallIcon() != null) { + if (notification.icon != 0) { if (!notification.isValid()) { throw new IllegalArgumentException("Invalid notification (): pkg=" + pkg + " id=" + id + " notification=" + notification); @@ -2139,11 +2139,11 @@ public class NotificationManagerService extends SystemService { applyZenModeLocked(r); mRankingHelper.sort(mNotificationList); - if (notification.getSmallIcon() != null) { + if (notification.icon != 0) { StatusBarNotification oldSbn = (old != null) ? old.sbn : null; mListeners.notifyPostedLocked(n, oldSbn); } else { - Slog.e(TAG, "Not posting notification without small icon: " + notification); + Slog.e(TAG, "Not posting notification with icon==0: " + notification); if (old != null && !old.isCanceled) { mListeners.notifyRemovedLocked(n); } @@ -2716,7 +2716,7 @@ public class NotificationManagerService extends SystemService { } // status bar - if (r.getNotification().getSmallIcon() != null) { + if (r.getNotification().icon != 0) { r.isCanceled = true; mListeners.notifyRemovedLocked(r.sbn); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 944fa5203fa9..8e0cdf1416ef 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3146,6 +3146,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public void grantRuntimePermission(String packageName, String name, int userId) { if (!sUserManager.exists(userId)) { + Log.e(TAG, "No such user:" + userId); return; } @@ -3203,6 +3204,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public void revokeRuntimePermission(String packageName, String name, int userId) { if (!sUserManager.exists(userId)) { + Log.e(TAG, "No such user:" + userId); return; } diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index 4098698e9497..7784884b6944 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -590,12 +590,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { void switchUser(int userId, IRemoteCallback reply) { synchronized (mLock) { mCurrentUserId = userId; - WallpaperData wallpaper = mWallpaperMap.get(userId); - if (wallpaper == null) { - wallpaper = new WallpaperData(userId); - mWallpaperMap.put(userId, wallpaper); - loadSettingsLocked(userId); - } + WallpaperData wallpaper = getWallpaperSafeLocked(userId); // Not started watching yet, in case wallpaper data was loaded for other reasons. if (wallpaper.wallpaperObserver == null) { wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper); @@ -718,10 +713,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { } synchronized (mLock) { int userId = UserHandle.getCallingUserId(); - WallpaperData wallpaper = mWallpaperMap.get(userId); - if (wallpaper == null) { - throw new IllegalStateException("Wallpaper not yet initialized for user " + userId); - } + WallpaperData wallpaper = getWallpaperSafeLocked(userId); if (width <= 0 || height <= 0) { throw new IllegalArgumentException("width and height must be > 0"); } @@ -783,10 +775,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { } synchronized (mLock) { int userId = UserHandle.getCallingUserId(); - WallpaperData wallpaper = mWallpaperMap.get(userId); - if (wallpaper == null) { - throw new IllegalStateException("Wallpaper not yet initialized for user " + userId); - } + WallpaperData wallpaper = getWallpaperSafeLocked(userId); if (padding.left < 0 || padding.top < 0 || padding.right < 0 || padding.bottom < 0) { throw new IllegalArgumentException("padding must be positive: " + padding); } @@ -867,10 +856,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { synchronized (mLock) { if (DEBUG) Slog.v(TAG, "setWallpaper"); int userId = UserHandle.getCallingUserId(); - WallpaperData wallpaper = mWallpaperMap.get(userId); - if (wallpaper == null) { - throw new IllegalStateException("Wallpaper not yet initialized for user " + userId); - } + WallpaperData wallpaper = getWallpaperSafeLocked(userId); final long ident = Binder.clearCallingIdentity(); try { ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper); @@ -1230,6 +1216,22 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { return Integer.parseInt(value); } + /** + * Sometimes it is expected the wallpaper map may not have a user's data. E.g. This could + * happen during user switch. The async user switch observer may not have received + * the event yet. We use this safe method when we don't care about this ordering and just + * want to update the data. The data is going to be applied when the user switch observer + * is eventually executed. + */ + private WallpaperData getWallpaperSafeLocked(int userId) { + WallpaperData wallpaper = mWallpaperMap.get(userId); + if (wallpaper == null) { + loadSettingsLocked(userId); + wallpaper = mWallpaperMap.get(userId); + } + return wallpaper; + } + private void loadSettingsLocked(int userId) { if (DEBUG) Slog.v(TAG, "loadSettingsLocked"); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index ffdb6233dcd2..9ad7e112e7ca 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -6345,10 +6345,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return; } + ActivityInfo[] receivers = null; try { - ActivityInfo[] receivers = mContext.getPackageManager().getPackageInfo( + receivers = mContext.getPackageManager().getPackageInfo( deviceOwnerPackage, PackageManager.GET_RECEIVERS).receivers; - if (receivers != null) { + } catch (NameNotFoundException e) { + Log.e(LOG_TAG, "Cannot find device owner package", e); + } + if (receivers != null) { + long ident = Binder.clearCallingIdentity(); + try { for (int i = 0; i < receivers.length; i++) { if (permission.BIND_DEVICE_ADMIN.equals(receivers[i].permission)) { intent.setComponent(new ComponentName(deviceOwnerPackage, @@ -6356,9 +6362,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mContext.sendBroadcastAsUser(intent, UserHandle.OWNER); } } + } finally { + Binder.restoreCallingIdentity(ident); } - } catch (NameNotFoundException e) { - Log.e(LOG_TAG, "Cannot find device owner package", e); } } } diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java index d8d9ab614d28..dfbb67a8c3df 100644 --- a/telecomm/java/android/telecom/Conference.java +++ b/telecomm/java/android/telecom/Conference.java @@ -30,7 +30,7 @@ import java.util.concurrent.CopyOnWriteArraySet; /** * Represents a conference call which can contain any number of {@link Connection} objects. */ -public abstract class Conference implements Conferenceable { +public abstract class Conference extends Conferenceable { /** * Used to indicate that the conference connection time is not specified. If not specified, diff --git a/telecomm/java/android/telecom/Conferenceable.java b/telecomm/java/android/telecom/Conferenceable.java index 5c4cbc50a734..bb6f2b8b3455 100644 --- a/telecomm/java/android/telecom/Conferenceable.java +++ b/telecomm/java/android/telecom/Conferenceable.java @@ -21,6 +21,6 @@ package android.telecom; * call with. The {@link ConnectionService} implementation will only recognize * {@link Conferenceable}s which are {@link Connection}s or {@link Conference}s. */ -public interface Conferenceable { - +public abstract class Conferenceable { + Conferenceable() {} } diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index f39f813494f4..fba4e6a1bca4 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -47,7 +47,7 @@ import java.util.concurrent.ConcurrentHashMap; * must call {@link #destroy()} to signal to the framework that the {@code Connection} is no * longer used and associated resources may be recovered. */ -public abstract class Connection implements Conferenceable { +public abstract class Connection extends Conferenceable { public static final int STATE_INITIALIZING = 0; diff --git a/tools/layoutlib/.idea/libraries/framework_jar.xml b/tools/layoutlib/.idea/libraries/framework_jar.xml new file mode 100644 index 000000000000..6695a3631ff1 --- /dev/null +++ b/tools/layoutlib/.idea/libraries/framework_jar.xml @@ -0,0 +1,13 @@ +<component name="libraryTable"> + <library name="framework.jar"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/../../../../out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="file://$PROJECT_DIR$/../../core/java" /> + <root url="file://$PROJECT_DIR$/../../graphics/java" /> + <root url="file://$PROJECT_DIR$/../../../../libcore/luni/src/main/java" /> + </SOURCES> + </library> +</component>
\ No newline at end of file diff --git a/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml b/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml new file mode 100644 index 000000000000..a8736000a513 --- /dev/null +++ b/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml @@ -0,0 +1,11 @@ +<component name="libraryTable"> + <library name="layoutlib_api-prebuilt"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-sources.jar!/" /> + </SOURCES> + </library> +</component>
\ No newline at end of file diff --git a/tools/layoutlib/bridge/bridge.iml b/tools/layoutlib/bridge/bridge.iml index d2b12595190a..af2fe7fc0a30 100644 --- a/tools/layoutlib/bridge/bridge.iml +++ b/tools/layoutlib/bridge/bridge.iml @@ -24,17 +24,7 @@ </content> <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> - <orderEntry type="module-library"> - <library name="layoutlib_api-prebuilt"> - <CLASSES> - <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-sources.jar!/" /> - </SOURCES> - </library> - </orderEntry> + <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" /> <orderEntry type="module-library"> <library name="ninepatch-prebuilt"> <CLASSES> @@ -60,19 +50,7 @@ </SOURCES> </library> </orderEntry> - <orderEntry type="module-library"> - <library name="framework.jar"> - <CLASSES> - <root url="jar://$MODULE_DIR$/../../../../../out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="file://$MODULE_DIR$/../../../core/java" /> - <root url="file://$MODULE_DIR$/../../../graphics/java" /> - <root url="file://$MODULE_DIR$/../../../../../libcore/luni/src/main/java" /> - </SOURCES> - </library> - </orderEntry> + <orderEntry type="library" name="framework.jar" level="project" /> <orderEntry type="module-library" scope="TEST"> <library name="kxml2-2.3.0"> <CLASSES> diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java index 6ca22b023d65..646f960395d5 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java @@ -19,7 +19,6 @@ package com.android.layoutlib.bridge.impl; import com.android.annotations.NonNull; import com.android.annotations.Nullable; -import com.android.ide.common.rendering.api.LayoutlibCallback; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -44,10 +43,11 @@ public class ParserFactory { // Used to get a new XmlPullParser from the client. @Nullable - private static LayoutlibCallback sLayoutlibCallback; + private static com.android.ide.common.rendering.api.ParserFactory sParserFactory; - public static void setLayoutlibCallback(@Nullable LayoutlibCallback callback) { - sLayoutlibCallback = callback; + public static void setParserFactory( + @Nullable com.android.ide.common.rendering.api.ParserFactory parserFactory) { + sParserFactory = parserFactory; } @NonNull @@ -77,10 +77,10 @@ public class ParserFactory { @NonNull public static XmlPullParser instantiateParser(@Nullable String name) throws XmlPullParserException { - if (sLayoutlibCallback == null) { + if (sParserFactory == null) { throw new XmlPullParserException("ParserFactory not initialized."); } - XmlPullParser parser = sLayoutlibCallback.createParser(name); + XmlPullParser parser = sParserFactory.createParser(name); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); return parser; } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java index 66b00238840e..2b95488cd5f3 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java @@ -39,8 +39,6 @@ import android.view.inputmethod.InputMethodManager_Accessor; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; -import javax.swing.text.html.parser.Parser; - import static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED; import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT; import static com.android.ide.common.rendering.api.Result.Status.SUCCESS; @@ -102,7 +100,7 @@ public abstract class RenderAction<T extends RenderParams> extends FrameworkReso } // setup the ParserFactory - ParserFactory.setLayoutlibCallback(mParams.getLayoutlibCallback()); + ParserFactory.setParserFactory(mParams.getLayoutlibCallback().getParserFactory()); HardwareConfig hardwareConfig = mParams.getHardwareConfig(); @@ -276,7 +274,7 @@ public abstract class RenderAction<T extends RenderParams> extends FrameworkReso mContext.getRenderResources().setFrameworkResourceIdProvider(null); mContext.getRenderResources().setLogger(null); } - ParserFactory.setLayoutlibCallback(null); + ParserFactory.setParserFactory(null); } diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java index 509f5eb5d482..4623f69c3d3a 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java @@ -17,15 +17,7 @@ package com.android.layoutlib.bridge.android; import com.android.annotations.NonNull; -import com.android.ide.common.rendering.api.ActionBarCallback; -import com.android.ide.common.rendering.api.AdapterBinding; -import com.android.ide.common.rendering.api.ILayoutPullParser; -import com.android.ide.common.rendering.api.LayoutlibCallback; -import com.android.ide.common.rendering.api.ResourceReference; -import com.android.ide.common.rendering.api.ResourceValue; import com.android.layoutlib.bridge.impl.ParserFactory; -import com.android.resources.ResourceType; -import com.android.util.Pair; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -41,7 +33,7 @@ public class BridgeXmlBlockParserTest { @BeforeClass public static void setUp() { - ParserFactory.setLayoutlibCallback(new LayoutlibTestCallback()); + ParserFactory.setParserFactory(new ParserFactoryImpl()); } @Test @@ -129,78 +121,16 @@ public class BridgeXmlBlockParserTest { @AfterClass public static void tearDown() { - ParserFactory.setLayoutlibCallback(null); + ParserFactory.setParserFactory(null); } - private static class LayoutlibTestCallback extends LayoutlibCallback { + private static class ParserFactoryImpl + extends com.android.ide.common.rendering.api.ParserFactory { @NonNull @Override public XmlPullParser createParser(String displayName) throws XmlPullParserException { return new KXmlParser(); } - - @Override - public boolean supports(int ideFeature) { - throw new AssertionError(); - } - - @Override - public Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs) - throws Exception { - throw new AssertionError(); - } - - @Override - public String getNamespace() { - throw new AssertionError(); - } - - @Override - @SuppressWarnings("deprecation") - public Pair<ResourceType, String> resolveResourceId(int id) { - throw new AssertionError(); - } - - @Override - public String resolveResourceId(int[] id) { - throw new AssertionError(); - } - - @Override - public Integer getResourceId(ResourceType type, String name) { - throw new AssertionError(); - } - - @Override - @SuppressWarnings("deprecation") - public ILayoutPullParser getParser(String layoutName) { - throw new AssertionError(); - } - - @Override - public ILayoutPullParser getParser(ResourceValue layoutResource) { - throw new AssertionError(); - } - - @Override - public Object getAdapterItemValue(ResourceReference adapterView, Object adapterCookie, - ResourceReference itemRef, int fullPosition, int positionPerType, - int fullParentPosition, int parentPositionPerType, ResourceReference viewRef, - ViewAttribute viewAttribute, Object defaultValue) { - throw new AssertionError(); - } - - @Override - public AdapterBinding getAdapterBinding(ResourceReference adapterViewRef, - Object adapterCookie, - Object viewObject) { - throw new AssertionError(); - } - - @Override - public ActionBarCallback getActionBarCallback() { - throw new AssertionError(); - } } } diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java index b1a1f4d318e6..ab682fdc40da 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java @@ -23,6 +23,7 @@ import com.android.ide.common.rendering.api.ActionBarCallback; import com.android.ide.common.rendering.api.AdapterBinding; import com.android.ide.common.rendering.api.ILayoutPullParser; import com.android.ide.common.rendering.api.LayoutlibCallback; +import com.android.ide.common.rendering.api.ParserFactory; import com.android.ide.common.rendering.api.ResourceReference; import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.resources.IntArrayWrapper; @@ -32,6 +33,7 @@ import com.android.utils.ILogger; import org.kxml2.io.KXmlParser; import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.lang.reflect.Constructor; @@ -163,7 +165,14 @@ public class LayoutLibTestCallback extends LayoutlibCallback { @NonNull @Override - public XmlPullParser createParser(@Nullable String name) { - return new KXmlParser(); + public ParserFactory getParserFactory() { + return new ParserFactory() { + @NonNull + @Override + public XmlPullParser createParser(@Nullable String debugName) + throws XmlPullParserException { + return new KXmlParser(); + } + }; } } |