Merge changes from topic 'mwd-merge-042415'

* changes:
  Rename removeVideoCallListener to unregisterCallback
  Bluetooth document fix: remove reference from open API to hidden entities
  Fix build due to merge of 7595842 and renaming due to 8eb87f0
  Merge commit '052a0da' into merge2
  Merge commit 'db1dbb8' into merge2
  Merge commit '7e5e791' into merge2
  Merge commit '170102d' into merge2
  Merge commit '4cb5d80' into merge2
  Merge commit '83cda00' into merge2
  Merge commit 'c91bc62' into merge2
  Merge commit 'cffc360' into merge2
  Merge commit '7f61051' into merge2
  Merge commit '167c3a7' into merge2
  Merge commit '4467b98' into merge2
  Merge commit '25a217c' into merge2
  Merge commit '04b18ec' into merge2
  Merge commit '7595842' into merge2
  Merge commit '2bbd2b6' into merge2
  Merge commit '4890351' into merge2
  Merge commit 'cd405fe' into merge2
  Merge commit '6ddbb5e' into merge2
  Merge commit 'de93575' into merge2
  Merge commit '9561e74' into merge2
diff --git a/api/current.txt b/api/current.txt
index 2f63509..578f808 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -505,7 +505,6 @@
     field public static final int dropDownWidth = 16843362; // 0x1010262
     field public static final int duplicateParentState = 16842985; // 0x10100e9
     field public static final int duration = 16843160; // 0x1010198
-    field public static final int durationScaleHint = 16844014; // 0x10104ee
     field public static final int dynamicResources = 16844019; // 0x10104f3
     field public static final int editTextBackground = 16843602; // 0x1010352
     field public static final int editTextColor = 16843601; // 0x1010351
@@ -996,6 +995,7 @@
     field public static final int readPermission = 16842759; // 0x1010007
     field public static final int recognitionService = 16843932; // 0x101049c
     field public static final int relinquishTaskIdentity = 16843894; // 0x1010476
+    field public static final int removeBeforeMRelease = 16844014; // 0x10104ee
     field public static final int reparent = 16843964; // 0x10104bc
     field public static final int reparentWithOverlay = 16843965; // 0x10104bd
     field public static final int repeatCount = 16843199; // 0x10101bf
@@ -2868,7 +2868,6 @@
     method public void cancel();
     method public android.animation.Animator clone();
     method public void end();
-    method public long getDistanceBasedDuration();
     method public abstract long getDuration();
     method public android.animation.TimeInterpolator getInterpolator();
     method public java.util.ArrayList<android.animation.Animator.AnimatorListener> getListeners();
@@ -2882,16 +2881,12 @@
     method public void removePauseListener(android.animation.Animator.AnimatorPauseListener);
     method public void resume();
     method public abstract android.animation.Animator setDuration(long);
-    method public void setDurationScaleHint(int, android.content.res.Resources);
     method public abstract void setInterpolator(android.animation.TimeInterpolator);
     method public abstract void setStartDelay(long);
     method public void setTarget(java.lang.Object);
     method public void setupEndValues();
     method public void setupStartValues();
     method public void start();
-    field public static final int HINT_DISTANCE_DEFINED_IN_DP = 2; // 0x2
-    field public static final int HINT_DISTANCE_PROPORTIONAL_TO_SCREEN_SIZE = 1; // 0x1
-    field public static final int HINT_NO_SCALE = 0; // 0x0
   }
 
   public static abstract interface Animator.AnimatorListener {
@@ -6132,6 +6127,7 @@
   }
 
   public final class UsageStatsManager {
+    method public boolean isAppIdle(java.lang.String);
     method public java.util.Map<java.lang.String, android.app.usage.UsageStats> queryAndAggregateUsageStats(long, long);
     method public java.util.List<android.app.usage.ConfigurationStats> queryConfigurations(int, long, long);
     method public android.app.usage.UsageEvents queryEvents(long, long);
@@ -14746,7 +14742,8 @@
     field public static final int CHANNEL_IN_Y_AXIS = 4096; // 0x1000
     field public static final int CHANNEL_IN_Z_AXIS = 8192; // 0x2000
     field public static final int CHANNEL_OUT_5POINT1 = 252; // 0xfc
-    field public static final int CHANNEL_OUT_7POINT1 = 1020; // 0x3fc
+    field public static final deprecated int CHANNEL_OUT_7POINT1 = 1020; // 0x3fc
+    field public static final int CHANNEL_OUT_7POINT1_SURROUND = 6396; // 0x18fc
     field public static final int CHANNEL_OUT_BACK_CENTER = 1024; // 0x400
     field public static final int CHANNEL_OUT_BACK_LEFT = 64; // 0x40
     field public static final int CHANNEL_OUT_BACK_RIGHT = 128; // 0x80
@@ -14892,6 +14889,8 @@
     field public static final deprecated int NUM_STREAMS = 5; // 0x5
     field public static final java.lang.String PROPERTY_OUTPUT_FRAMES_PER_BUFFER = "android.media.property.OUTPUT_FRAMES_PER_BUFFER";
     field public static final java.lang.String PROPERTY_OUTPUT_SAMPLE_RATE = "android.media.property.OUTPUT_SAMPLE_RATE";
+    field public static final java.lang.String PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND = "android.media.property.SUPPORT_MIC_NEAR_ULTRASOUND";
+    field public static final java.lang.String PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND = "android.media.property.SUPPORT_SPEAKER_NEAR_ULTRASOUND";
     field public static final java.lang.String RINGER_MODE_CHANGED_ACTION = "android.media.RINGER_MODE_CHANGED";
     field public static final int RINGER_MODE_NORMAL = 2; // 0x2
     field public static final int RINGER_MODE_SILENT = 0; // 0x0
@@ -16392,10 +16391,13 @@
     method public final void release();
     method public void setAudioTrack(android.media.AudioTrack);
     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 setPlaybackRate(float, int);
     method public void setPlaybackSettings(android.media.PlaybackSettings);
     method public void setSurface(android.view.Surface);
     method public void setSyncSettings(android.media.SyncSettings);
+    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
@@ -16403,7 +16405,11 @@
 
   public static abstract class MediaSync.Callback {
     ctor public MediaSync.Callback();
-    method public abstract void onReturnAudioBuffer(android.media.MediaSync, java.nio.ByteBuffer, int);
+    method public abstract void onAudioBufferConsumed(android.media.MediaSync, java.nio.ByteBuffer, int);
+  }
+
+  public static abstract interface MediaSync.OnErrorListener {
+    method public abstract void onError(android.media.MediaSync, int, int);
   }
 
   public class MediaSyncEvent {
@@ -16429,6 +16435,14 @@
     method public abstract void onAudioDeviceConnection();
   }
 
+  public abstract interface OnAudioRecordRoutingListener {
+    method public abstract void onAudioRecordRouting(android.media.AudioRecord);
+  }
+
+  public abstract interface OnAudioTrackRoutingListener {
+    method public abstract void onAudioTrackRouting(android.media.AudioTrack);
+  }
+
   public final class PlaybackSettings {
     ctor public PlaybackSettings();
     method public android.media.PlaybackSettings allowDefaults();
@@ -16447,14 +16461,6 @@
     field public static final int AUDIO_STRETCH_MODE_VOICE = 1; // 0x1
   }
 
-  public abstract interface OnAudioRecordRoutingListener {
-    method public abstract void onAudioRecordRouting(android.media.AudioRecord);
-  }
-
-  public abstract interface OnAudioTrackRoutingListener {
-    method public abstract void onAudioTrackRouting(android.media.AudioTrack);
-  }
-
   public final class Rating implements android.os.Parcelable {
     method public int describeContents();
     method public float getPercentRating();
@@ -17819,6 +17825,7 @@
     method public java.lang.String getRatingSystem();
     method public java.util.List<java.lang.String> getSubRatings();
     method public static android.media.tv.TvContentRating unflattenFromString(java.lang.String);
+    field public static final android.media.tv.TvContentRating UNRATED;
   }
 
   public final class TvContract {
@@ -23404,6 +23411,7 @@
     method public final android.os.IBinder readStrongBinder();
     method public final void readTypedArray(T[], android.os.Parcelable.Creator<T>);
     method public final void readTypedList(java.util.List<T>, android.os.Parcelable.Creator<T>);
+    method public final T readTypedObject(android.os.Parcelable.Creator<T>);
     method public final java.lang.Object readValue(java.lang.ClassLoader);
     method public final void recycle();
     method public final void setDataCapacity(int);
@@ -23448,6 +23456,7 @@
     method public final void writeStrongInterface(android.os.IInterface);
     method public final void writeTypedArray(T[], int);
     method public final void writeTypedList(java.util.List<T>);
+    method public final void writeTypedObject(T, int);
     method public final void writeValue(java.lang.Object);
     field public static final android.os.Parcelable.Creator<java.lang.String> STRING_CREATOR;
   }
@@ -28444,13 +28453,6 @@
 
 package android.security {
 
-  public class CryptoOperationException extends java.lang.RuntimeException {
-    ctor public CryptoOperationException();
-    ctor public CryptoOperationException(java.lang.String);
-    ctor public CryptoOperationException(java.lang.String, java.lang.Throwable);
-    ctor public CryptoOperationException(java.lang.Throwable);
-  }
-
   public class EcIesParameterSpec implements java.security.spec.AlgorithmParameterSpec {
     method public int getDemCipherKeySize();
     method public java.lang.String getDemCipherTransformation();
@@ -28507,7 +28509,7 @@
     ctor public KeyChainException(java.lang.Throwable);
   }
 
-  public class KeyExpiredException extends android.security.CryptoOperationException {
+  public class KeyExpiredException extends java.security.InvalidKeyException {
     ctor public KeyExpiredException();
     ctor public KeyExpiredException(java.lang.String);
     ctor public KeyExpiredException(java.lang.String, java.lang.Throwable);
@@ -28549,7 +28551,7 @@
     method public android.security.KeyGeneratorSpec.Builder setUserAuthenticators(int);
   }
 
-  public class KeyNotYetValidException extends android.security.CryptoOperationException {
+  public class KeyNotYetValidException extends java.security.InvalidKeyException {
     ctor public KeyNotYetValidException();
     ctor public KeyNotYetValidException(java.lang.String);
     ctor public KeyNotYetValidException(java.lang.String, java.lang.Throwable);
@@ -28697,12 +28699,12 @@
     method public boolean isCleartextTrafficPermitted();
   }
 
-  public class NewFingerprintEnrolledException extends android.security.CryptoOperationException {
+  public class NewFingerprintEnrolledException extends java.security.InvalidKeyException {
     ctor public NewFingerprintEnrolledException();
     ctor public NewFingerprintEnrolledException(java.lang.String);
   }
 
-  public class UserNotAuthenticatedException extends android.security.CryptoOperationException {
+  public class UserNotAuthenticatedException extends java.security.InvalidKeyException {
     ctor public UserNotAuthenticatedException();
     ctor public UserNotAuthenticatedException(java.lang.String);
     ctor public UserNotAuthenticatedException(java.lang.String, java.lang.Throwable);
@@ -28915,6 +28917,7 @@
     method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
     method public final void requestInterruptionFilter(int);
     method public final void requestListenerHints(int);
+    method public final void setNotificationsShown(java.lang.String[]);
     field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1
     field public static final int INTERRUPTION_FILTER_ALARMS = 4; // 0x4
     field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1
@@ -30607,6 +30610,7 @@
     method public void cancelMissedCallsNotification();
     method public android.net.Uri getAdnUriForPhoneAccount(android.telecom.PhoneAccountHandle);
     method public java.util.List<android.telecom.PhoneAccountHandle> getCallCapablePhoneAccounts();
+    method public java.lang.String getDefaultDialerPackage();
     method public android.telecom.PhoneAccountHandle getDefaultOutgoingPhoneAccount(java.lang.String);
     method public java.lang.String getLine1Number(android.telecom.PhoneAccountHandle);
     method public android.telecom.PhoneAccount getPhoneAccount(android.telecom.PhoneAccountHandle);
@@ -30621,6 +30625,7 @@
     method public void showInCallScreen(boolean);
     method public void silenceRinger();
     method public void unregisterPhoneAccount(android.telecom.PhoneAccountHandle);
+    field public static final java.lang.String ACTION_CHANGE_DEFAULT_DIALER = "android.telecom.action.CHANGE_DEFAULT_DIALER";
     field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
     field public static final java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
     field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
@@ -30631,6 +30636,7 @@
     field public static final java.lang.String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER";
     field public static final java.lang.String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE";
     field public static final java.lang.String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE";
+    field public static final java.lang.String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME";
     field public static final java.lang.String EXTRA_INCOMING_CALL_EXTRAS = "android.telecom.extra.INCOMING_CALL_EXTRAS";
     field public static final java.lang.String EXTRA_OUTGOING_CALL_EXTRAS = "android.telecom.extra.OUTGOING_CALL_EXTRAS";
     field public static final java.lang.String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telecom.extra.PHONE_ACCOUNT_HANDLE";
diff --git a/api/system-current.txt b/api/system-current.txt
index 5c24e8e..2ea68c6 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -578,7 +578,6 @@
     field public static final int dropDownWidth = 16843362; // 0x1010262
     field public static final int duplicateParentState = 16842985; // 0x10100e9
     field public static final int duration = 16843160; // 0x1010198
-    field public static final int durationScaleHint = 16844014; // 0x10104ee
     field public static final int dynamicResources = 16844019; // 0x10104f3
     field public static final int editTextBackground = 16843602; // 0x1010352
     field public static final int editTextColor = 16843601; // 0x1010351
@@ -1069,6 +1068,7 @@
     field public static final int readPermission = 16842759; // 0x1010007
     field public static final int recognitionService = 16843932; // 0x101049c
     field public static final int relinquishTaskIdentity = 16843894; // 0x1010476
+    field public static final int removeBeforeMRelease = 16844014; // 0x10104ee
     field public static final int reparent = 16843964; // 0x10104bc
     field public static final int reparentWithOverlay = 16843965; // 0x10104bd
     field public static final int repeatCount = 16843199; // 0x10101bf
@@ -2948,7 +2948,6 @@
     method public void cancel();
     method public android.animation.Animator clone();
     method public void end();
-    method public long getDistanceBasedDuration();
     method public abstract long getDuration();
     method public android.animation.TimeInterpolator getInterpolator();
     method public java.util.ArrayList<android.animation.Animator.AnimatorListener> getListeners();
@@ -2962,16 +2961,12 @@
     method public void removePauseListener(android.animation.Animator.AnimatorPauseListener);
     method public void resume();
     method public abstract android.animation.Animator setDuration(long);
-    method public void setDurationScaleHint(int, android.content.res.Resources);
     method public abstract void setInterpolator(android.animation.TimeInterpolator);
     method public abstract void setStartDelay(long);
     method public void setTarget(java.lang.Object);
     method public void setupEndValues();
     method public void setupStartValues();
     method public void start();
-    field public static final int HINT_DISTANCE_DEFINED_IN_DP = 2; // 0x2
-    field public static final int HINT_DISTANCE_PROPORTIONAL_TO_SCREEN_SIZE = 1; // 0x1
-    field public static final int HINT_NO_SCALE = 0; // 0x0
   }
 
   public static abstract interface Animator.AnimatorListener {
@@ -6320,6 +6315,7 @@
   }
 
   public final class UsageStatsManager {
+    method public boolean isAppIdle(java.lang.String);
     method public java.util.Map<java.lang.String, android.app.usage.UsageStats> queryAndAggregateUsageStats(long, long);
     method public java.util.List<android.app.usage.ConfigurationStats> queryConfigurations(int, long, long);
     method public android.app.usage.UsageEvents queryEvents(long, long);
@@ -15947,7 +15943,8 @@
     field public static final int CHANNEL_IN_Y_AXIS = 4096; // 0x1000
     field public static final int CHANNEL_IN_Z_AXIS = 8192; // 0x2000
     field public static final int CHANNEL_OUT_5POINT1 = 252; // 0xfc
-    field public static final int CHANNEL_OUT_7POINT1 = 1020; // 0x3fc
+    field public static final deprecated int CHANNEL_OUT_7POINT1 = 1020; // 0x3fc
+    field public static final int CHANNEL_OUT_7POINT1_SURROUND = 6396; // 0x18fc
     field public static final int CHANNEL_OUT_BACK_CENTER = 1024; // 0x400
     field public static final int CHANNEL_OUT_BACK_LEFT = 64; // 0x40
     field public static final int CHANNEL_OUT_BACK_RIGHT = 128; // 0x80
@@ -16102,6 +16099,8 @@
     field public static final deprecated int NUM_STREAMS = 5; // 0x5
     field public static final java.lang.String PROPERTY_OUTPUT_FRAMES_PER_BUFFER = "android.media.property.OUTPUT_FRAMES_PER_BUFFER";
     field public static final java.lang.String PROPERTY_OUTPUT_SAMPLE_RATE = "android.media.property.OUTPUT_SAMPLE_RATE";
+    field public static final java.lang.String PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND = "android.media.property.SUPPORT_MIC_NEAR_ULTRASOUND";
+    field public static final java.lang.String PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND = "android.media.property.SUPPORT_SPEAKER_NEAR_ULTRASOUND";
     field public static final java.lang.String RINGER_MODE_CHANGED_ACTION = "android.media.RINGER_MODE_CHANGED";
     field public static final int RINGER_MODE_NORMAL = 2; // 0x2
     field public static final int RINGER_MODE_SILENT = 0; // 0x0
@@ -17608,10 +17607,13 @@
     method public final void release();
     method public void setAudioTrack(android.media.AudioTrack);
     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 setPlaybackRate(float, int);
     method public void setPlaybackSettings(android.media.PlaybackSettings);
     method public void setSurface(android.view.Surface);
     method public void setSyncSettings(android.media.SyncSettings);
+    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
@@ -17619,7 +17621,11 @@
 
   public static abstract class MediaSync.Callback {
     ctor public MediaSync.Callback();
-    method public abstract void onReturnAudioBuffer(android.media.MediaSync, java.nio.ByteBuffer, int);
+    method public abstract void onAudioBufferConsumed(android.media.MediaSync, java.nio.ByteBuffer, int);
+  }
+
+  public static abstract interface MediaSync.OnErrorListener {
+    method public abstract void onError(android.media.MediaSync, int, int);
   }
 
   public class MediaSyncEvent {
@@ -17645,6 +17651,14 @@
     method public abstract void onAudioDeviceConnection();
   }
 
+  public abstract interface OnAudioRecordRoutingListener {
+    method public abstract void onAudioRecordRouting(android.media.AudioRecord);
+  }
+
+  public abstract interface OnAudioTrackRoutingListener {
+    method public abstract void onAudioTrackRouting(android.media.AudioTrack);
+  }
+
   public final class PlaybackSettings {
     ctor public PlaybackSettings();
     method public android.media.PlaybackSettings allowDefaults();
@@ -17663,14 +17677,6 @@
     field public static final int AUDIO_STRETCH_MODE_VOICE = 1; // 0x1
   }
 
-  public abstract interface OnAudioRecordRoutingListener {
-    method public abstract void onAudioRecordRouting(android.media.AudioRecord);
-  }
-
-  public abstract interface OnAudioTrackRoutingListener {
-    method public abstract void onAudioTrackRouting(android.media.AudioTrack);
-  }
-
   public final class Rating implements android.os.Parcelable {
     method public int describeContents();
     method public float getPercentRating();
@@ -19104,6 +19110,7 @@
     method public java.lang.String getRatingSystem();
     method public java.util.List<java.lang.String> getSubRatings();
     method public static android.media.tv.TvContentRating unflattenFromString(java.lang.String);
+    field public static final android.media.tv.TvContentRating UNRATED;
   }
 
   public final class TvContentRatingSystemInfo implements android.os.Parcelable {
@@ -25293,6 +25300,7 @@
     method public final android.os.IBinder readStrongBinder();
     method public final void readTypedArray(T[], android.os.Parcelable.Creator<T>);
     method public final void readTypedList(java.util.List<T>, android.os.Parcelable.Creator<T>);
+    method public final T readTypedObject(android.os.Parcelable.Creator<T>);
     method public final java.lang.Object readValue(java.lang.ClassLoader);
     method public final void recycle();
     method public final void setDataCapacity(int);
@@ -25337,6 +25345,7 @@
     method public final void writeStrongInterface(android.os.IInterface);
     method public final void writeTypedArray(T[], int);
     method public final void writeTypedList(java.util.List<T>);
+    method public final void writeTypedObject(T, int);
     method public final void writeValue(java.lang.Object);
     field public static final android.os.Parcelable.Creator<java.lang.String> STRING_CREATOR;
   }
@@ -30448,13 +30457,6 @@
 
 package android.security {
 
-  public class CryptoOperationException extends java.lang.RuntimeException {
-    ctor public CryptoOperationException();
-    ctor public CryptoOperationException(java.lang.String);
-    ctor public CryptoOperationException(java.lang.String, java.lang.Throwable);
-    ctor public CryptoOperationException(java.lang.Throwable);
-  }
-
   public class EcIesParameterSpec implements java.security.spec.AlgorithmParameterSpec {
     method public int getDemCipherKeySize();
     method public java.lang.String getDemCipherTransformation();
@@ -30511,7 +30513,7 @@
     ctor public KeyChainException(java.lang.Throwable);
   }
 
-  public class KeyExpiredException extends android.security.CryptoOperationException {
+  public class KeyExpiredException extends java.security.InvalidKeyException {
     ctor public KeyExpiredException();
     ctor public KeyExpiredException(java.lang.String);
     ctor public KeyExpiredException(java.lang.String, java.lang.Throwable);
@@ -30553,7 +30555,7 @@
     method public android.security.KeyGeneratorSpec.Builder setUserAuthenticators(int);
   }
 
-  public class KeyNotYetValidException extends android.security.CryptoOperationException {
+  public class KeyNotYetValidException extends java.security.InvalidKeyException {
     ctor public KeyNotYetValidException();
     ctor public KeyNotYetValidException(java.lang.String);
     ctor public KeyNotYetValidException(java.lang.String, java.lang.Throwable);
@@ -30701,12 +30703,12 @@
     method public boolean isCleartextTrafficPermitted();
   }
 
-  public class NewFingerprintEnrolledException extends android.security.CryptoOperationException {
+  public class NewFingerprintEnrolledException extends java.security.InvalidKeyException {
     ctor public NewFingerprintEnrolledException();
     ctor public NewFingerprintEnrolledException(java.lang.String);
   }
 
-  public class UserNotAuthenticatedException extends android.security.CryptoOperationException {
+  public class UserNotAuthenticatedException extends java.security.InvalidKeyException {
     ctor public UserNotAuthenticatedException();
     ctor public UserNotAuthenticatedException(java.lang.String);
     ctor public UserNotAuthenticatedException(java.lang.String, java.lang.Throwable);
@@ -30960,6 +30962,7 @@
     method public void registerAsSystemService(android.content.Context, android.content.ComponentName, int) throws android.os.RemoteException;
     method public final void requestInterruptionFilter(int);
     method public final void requestListenerHints(int);
+    method public final void setNotificationsShown(java.lang.String[]);
     method public final void setOnNotificationPostedTrim(int);
     method public void unregisterAsSystemService() throws android.os.RemoteException;
     field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1
@@ -32751,8 +32754,9 @@
     method public java.util.List<android.telecom.PhoneAccountHandle> getCallCapablePhoneAccounts();
     method public int getCallState();
     method public android.telecom.PhoneAccountHandle getConnectionManager();
+    method public java.lang.String getDefaultDialerPackage();
     method public android.telecom.PhoneAccountHandle getDefaultOutgoingPhoneAccount(java.lang.String);
-    method public android.content.ComponentName getDefaultPhoneApp();
+    method public deprecated android.content.ComponentName getDefaultPhoneApp();
     method public java.lang.String getLine1Number(android.telecom.PhoneAccountHandle);
     method public android.telecom.PhoneAccount getPhoneAccount(android.telecom.PhoneAccountHandle);
     method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsForPackage();
@@ -32771,6 +32775,7 @@
     method public void showInCallScreen(boolean);
     method public void silenceRinger();
     method public void unregisterPhoneAccount(android.telecom.PhoneAccountHandle);
+    field public static final java.lang.String ACTION_CHANGE_DEFAULT_DIALER = "android.telecom.action.CHANGE_DEFAULT_DIALER";
     field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
     field public static final java.lang.String ACTION_CONNECTION_SERVICE_CONFIGURE = "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
     field public static final java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
@@ -32783,6 +32788,7 @@
     field public static final java.lang.String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER";
     field public static final java.lang.String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE";
     field public static final java.lang.String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE";
+    field public static final java.lang.String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME";
     field public static final java.lang.String EXTRA_CONNECTION_SERVICE = "android.telecom.extra.CONNECTION_SERVICE";
     field public static final java.lang.String EXTRA_INCOMING_CALL_EXTRAS = "android.telecom.extra.INCOMING_CALL_EXTRAS";
     field public static final java.lang.String EXTRA_OUTGOING_CALL_EXTRAS = "android.telecom.extra.OUTGOING_CALL_EXTRAS";
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 8ba2a5a..219d35b 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -142,6 +142,8 @@
                 "       am task resizeable <TASK_ID> [true|false]\n" +
                 "       am task resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" +
                 "       am get-config\n" +
+                "       am set-idle [--user <USER_ID>] <PACKAGE> true|false\n" +
+                "       am get-idle [--user <USER_ID>] <PACKAGE>\n" +
                 "\n" +
                 "am start: start an Activity.  Options are:\n" +
                 "    -D: enable debugging\n" +
@@ -282,6 +284,11 @@
                 "am get-config: retrieve the configuration and any recent configurations\n" +
                 "  of the device\n" +
                 "\n" +
+                "am set-idle: sets the idle state of an app\n" +
+                "\n" +
+                "am get-idle: returns the idle state of an app\n" +
+                "\n" +
+                "\n" +
                 "<INTENT> specifications include these flags and arguments:\n" +
                 "    [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
                 "    [-c <CATEGORY> [-c <CATEGORY>] ...]\n" +
@@ -388,6 +395,10 @@
             runTask();
         } else if (op.equals("get-config")) {
             runGetConfig();
+        } else if (op.equals("set-idle")) {
+            runSetIdle();
+        } else if (op.equals("get-idle")) {
+            runGetIdle();
         } else {
             showError("Error: unknown command '" + op + "'");
         }
@@ -2019,6 +2030,46 @@
         }
     }
 
+    private void runSetIdle() throws Exception {
+        int userId = UserHandle.USER_OWNER;
+
+        String opt;
+        while ((opt=nextOption()) != null) {
+            if (opt.equals("--user")) {
+                userId = parseUserArg(nextArgRequired());
+            } else {
+                System.err.println("Error: Unknown option: " + opt);
+                return;
+            }
+        }
+        String packageName = nextArgRequired();
+        String value = nextArgRequired();
+
+        IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
+                Context.USAGE_STATS_SERVICE));
+        usm.setAppIdle(packageName, Boolean.parseBoolean(value), userId);
+    }
+
+    private void runGetIdle() throws Exception {
+        int userId = UserHandle.USER_OWNER;
+
+        String opt;
+        while ((opt=nextOption()) != null) {
+            if (opt.equals("--user")) {
+                userId = parseUserArg(nextArgRequired());
+            } else {
+                System.err.println("Error: Unknown option: " + opt);
+                return;
+            }
+        }
+        String packageName = nextArgRequired();
+
+        IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
+                Context.USAGE_STATS_SERVICE));
+        boolean isIdle = usm.isAppIdle(packageName, userId);
+        System.out.println("Idle=" + isIdle);
+    }
+
     /**
      * Open the given file for sending into the system process. This verifies
      * with SELinux that the system will have access to the file.
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 02a329d..da48709 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -16,12 +16,7 @@
 
 package android.animation;
 
-import android.content.res.Configuration;
 import android.content.res.ConstantState;
-import android.content.res.Resources;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.animation.AnimationUtils;
 
 import java.util.ArrayList;
 
@@ -30,29 +25,6 @@
  * started, ended, and have <code>AnimatorListeners</code> added to them.
  */
 public abstract class Animator implements Cloneable {
-    /**
-     * Set this hint when duration for the animation does not need to be scaled. By default, no
-     * scaling is applied to the duration.
-     */
-    public static final int HINT_NO_SCALE = 0;
-
-    /**
-     * Set this scale hint (using {@link #setDurationScaleHint(int, Resources)} when the animation's
-     * moving distance is proportional to the screen size. (e.g. a view coming in from the bottom of
-     * the screen to top/center). With this scale hint set, the animation duration will be
-     * automatically scaled based on screen size.
-     */
-    public static final int HINT_DISTANCE_PROPORTIONAL_TO_SCREEN_SIZE = 1;
-
-    /**
-     * Set this scale hint (using {@link #setDurationScaleHint(int, Resources)}) if the animation
-     * has pre-defined moving distance in dp that does not vary from device to device. This is
-     * extremely useful when the animation needs to run on both phones/tablets and TV, because TV
-     * has inflated dp and therefore will have a longer visual arc for the same animation than on
-     * the phone. This hint is used to calculate a scaling factor to compensate for different
-     * visual arcs while maintaining the same angular velocity for the animation.
-     */
-    public static final int HINT_DISTANCE_DEFINED_IN_DP = 2;
 
     /**
      * The set of listeners to be sent events through the life of an animation.
@@ -83,24 +55,6 @@
     private AnimatorConstantState mConstantState;
 
     /**
-     * Scaling factor for an animation that moves across the whole screen.
-     */
-    float mScreenSizeBasedDurationScale = 1.0f;
-
-    /**
-     * Scaling factor for an animation that is defined to move the same amount of dp across all
-     * devices.
-     */
-    float mDpBasedDurationScale = 1.0f;
-
-    /**
-     * By default, the scaling assumes the animation moves across the entire screen.
-     */
-    int mDurationScaleHint = HINT_NO_SCALE;
-
-    private final static boolean ANIM_DEBUG = false;
-
-    /**
      * Starts this animation. If the animation has a nonzero startDelay, the animation will start
      * running after that delay elapses. A non-delayed animation will have its initial
      * value(s) set immediately, followed by calls to
@@ -230,78 +184,6 @@
     public abstract long getDuration();
 
     /**
-     * Hints how duration scaling factor should be calculated. The duration will not be scaled when
-     * hint is set to {@link #HINT_NO_SCALE}. Otherwise, the duration will be automatically scaled
-     * per device to achieve the same look and feel across different devices. In order to do
-     * that, the same angular velocity of the animation will be needed on different devices in
-     * users' field of view. Therefore, the duration scale factor is determined by the ratio of the
-     * angular movement on current devices to that on the baseline device (i.e. Nexus 5).
-     *
-     * @param hint an indicator on how the animation is defined. The hint could be
-     *             {@link #HINT_NO_SCALE}, {@link #HINT_DISTANCE_PROPORTIONAL_TO_SCREEN_SIZE} or
-     *             {@link #HINT_DISTANCE_DEFINED_IN_DP}.
-     * @param res The resources {@see android.content.res.Resources} for getting display metrics
-     */
-    public void setDurationScaleHint(int hint, Resources res) {
-        if (ANIM_DEBUG) {
-            Log.d("ANIM_DEBUG", "distance based duration hint: " + hint);
-        }
-        if (hint == mDurationScaleHint) {
-            return;
-        }
-        mDurationScaleHint = hint;
-        if (hint != HINT_NO_SCALE) {
-            int uiMode = res.getConfiguration().uiMode & Configuration.UI_MODE_TYPE_MASK;
-            DisplayMetrics metrics = res.getDisplayMetrics();
-            float width = metrics.widthPixels / metrics.xdpi;
-            float height = metrics.heightPixels / metrics.ydpi;
-            float viewingDistance = AnimationUtils.getViewingDistance(width, height, uiMode);
-            if (ANIM_DEBUG) {
-                Log.d("ANIM_DEBUG", "width, height, viewing distance, uimode: "
-                        + width + ", " + height + ", " + viewingDistance + ", " + uiMode);
-            }
-            mScreenSizeBasedDurationScale = AnimationUtils
-                    .getScreenSizeBasedDurationScale(width, height, viewingDistance);
-            mDpBasedDurationScale = AnimationUtils.getDpBasedDurationScale(
-                    metrics.density, metrics.xdpi, viewingDistance);
-            if (ANIM_DEBUG) {
-                Log.d("ANIM_DEBUG", "screen based scale, dp based scale: " +
-                        mScreenSizeBasedDurationScale + ", " + mDpBasedDurationScale);
-            }
-        }
-    }
-
-    // Copies duration scale hint and scaling factors to the new animation.
-    void copyDurationScaleInfoTo(Animator anim) {
-        anim.mDurationScaleHint = mDurationScaleHint;
-        anim.mScreenSizeBasedDurationScale = mScreenSizeBasedDurationScale;
-        anim.mDpBasedDurationScale = mDpBasedDurationScale;
-    }
-
-    /**
-     * @return The scaled duration calculated based on distance of movement (as defined by the
-     * animation) and perceived velocity (derived from the duration set on the animation for
-     * baseline device)
-     */
-    public long getDistanceBasedDuration() {
-        return (long) (getDuration() * getDistanceBasedDurationScale());
-    }
-
-    /**
-     * @return scaling factor of duration based on the duration scale hint. A scaling factor of 1
-     * means no scaling will be applied to the duration.
-     */
-    float getDistanceBasedDurationScale() {
-        if (mDurationScaleHint == HINT_DISTANCE_PROPORTIONAL_TO_SCREEN_SIZE) {
-            return mScreenSizeBasedDurationScale;
-        } else if (mDurationScaleHint == HINT_DISTANCE_DEFINED_IN_DP) {
-            return mDpBasedDurationScale;
-        } else {
-            return 1f;
-        }
-    }
-
-    /**
      * The time interpolator used in calculating the elapsed fraction of the
      * animation. The interpolator determines whether the animation runs with
      * linear or non-linear motion, such as acceleration and deceleration. The
diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java
index e47d017..427ecce 100644
--- a/core/java/android/animation/AnimatorInflater.java
+++ b/core/java/android/animation/AnimatorInflater.java
@@ -70,13 +70,6 @@
     private static final int VALUE_TYPE_COLOR       = 3;
     private static final int VALUE_TYPE_UNDEFINED   = 4;
 
-    /**
-     * Enum values used in XML attributes to indicate the duration scale hint.
-     */
-    private static final int HINT_NO_SCALE                  = 0;
-    private static final int HINT_PROPORTIONAL_TO_SCREEN    = 1;
-    private static final int HINT_DEFINED_IN_DP             = 2;
-
     private static final boolean DBG_ANIMATOR_INFLATER = false;
 
     // used to calculate changing configs for resource references
@@ -698,9 +691,6 @@
                 int ordering = a.getInt(R.styleable.AnimatorSet_ordering, TOGETHER);
                 createAnimatorFromXml(res, theme, parser, attrs, (AnimatorSet) anim, ordering,
                         pixelSize);
-                final int hint = a.getInt(R.styleable.AnimatorSet_durationScaleHint,
-                        HINT_NO_SCALE);
-                anim.setDurationScaleHint(hint, res);
                 a.recycle();
             } else if (name.equals("propertyValuesHolder")) {
                 PropertyValuesHolder[] values = loadValues(res, theme, parser,
@@ -1065,9 +1055,6 @@
             anim.setInterpolator(interpolator);
         }
 
-        final int hint = arrayAnimator.getInt(R.styleable.Animator_durationScaleHint,
-                HINT_NO_SCALE);
-        anim.setDurationScaleHint(hint, res);
         arrayAnimator.recycle();
         if (arrayObjectAnimator != null) {
             arrayObjectAnimator.recycle();
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index f6ad847..6503d89 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -519,7 +519,6 @@
 
         for (Node node : mNodes) {
             node.animation.setAllowRunningAsynchronously(false);
-            copyDurationScaleInfoTo(node.animation);
         }
 
         if (mDuration >= 0) {
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 292507b..a455f8b 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -17,12 +17,9 @@
 package android.animation;
 
 import android.annotation.CallSuper;
-import android.content.res.Configuration;
-import android.content.res.Resources;
 import android.os.Looper;
 import android.os.Trace;
 import android.util.AndroidRuntimeException;
-import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.Choreographer;
 import android.view.animation.AccelerateDecelerateInterpolator;
@@ -564,7 +561,7 @@
     }
 
     private void updateScaledDuration() {
-        mDuration = (long)(mUnscaledDuration * sDurationScale * getDistanceBasedDurationScale());
+        mDuration = (long)(mUnscaledDuration * sDurationScale);
     }
 
     /**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index ab5f811..9bad9bb 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -255,23 +255,18 @@
         }
     }
 
-    static final class AcquiringProviderRecord {
-        IActivityManager.ContentProviderHolder holder;
-        boolean acquiring = true;
-        int requests = 1;
-        // Set if there was a runtime exception when trying to acquire the provider.
-        RuntimeException runtimeException = null;
-    }
-
     // The lock of mProviderMap protects the following variables.
-    final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap = new ArrayMap<>();
-    final ArrayMap<ProviderKey, AcquiringProviderRecord> mAcquiringProviderMap = new ArrayMap<>();
-    final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap = new ArrayMap<>();
-    final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders = new ArrayMap<>();
-    final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName = new ArrayMap<>();
+    final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap
+        = new ArrayMap<ProviderKey, ProviderClientRecord>();
+    final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap
+        = new ArrayMap<IBinder, ProviderRefCount>();
+    final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders
+        = new ArrayMap<IBinder, ProviderClientRecord>();
+    final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
+            = new ArrayMap<ComponentName, ProviderClientRecord>();
 
     final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
-            = new ArrayMap<>();
+        = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>();
 
     final GcIdler mGcIdler = new GcIdler();
     boolean mGcIdlerScheduled = false;
@@ -351,7 +346,7 @@
         }
     }
 
-    static final class ProviderClientRecord {
+    final class ProviderClientRecord {
         final String[] mNames;
         final IContentProvider mProvider;
         final ContentProvider mLocalProvider;
@@ -4716,74 +4711,23 @@
 
     public final IContentProvider acquireProvider(
             Context c, String auth, int userId, boolean stable) {
-        final ProviderKey key = new ProviderKey(auth, userId);
-        final IContentProvider provider = acquireExistingProvider(c, key, stable);
+        final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
         if (provider != null) {
             return provider;
         }
-        AcquiringProviderRecord r;
-        boolean first = false;
-        synchronized (mAcquiringProviderMap) {
-            r = mAcquiringProviderMap.get(key);
-            if (r == null) {
-                r = new AcquiringProviderRecord();
-                mAcquiringProviderMap.put(key, r);
-                first = true;
-            } else {
-                r.requests++;
-            }
-        }
 
+        // There is a possible race here.  Another thread may try to acquire
+        // the same provider at the same time.  When this happens, we want to ensure
+        // that the first one wins.
+        // Note that we cannot hold the lock while acquiring and installing the
+        // provider since it might take a long time to run and it could also potentially
+        // be re-entrant in the case where the provider is in the same process.
         IActivityManager.ContentProviderHolder holder = null;
         try {
-            if (first) {
-                // Multiple threads may try to acquire the same provider at the same time.
-                // When this happens, we only let the first one really gets provider.
-                // Other threads just wait for its result.
-                // Note that we cannot hold the lock while acquiring and installing the
-                // provider since it might take a long time to run and it could also potentially
-                // be re-entrant in the case where the provider is in the same process.
-                holder = ActivityManagerNative.getDefault().getContentProvider(
-                        getApplicationThread(), auth, userId, stable);
-            } else {
-                synchronized (r) {
-                    while (r.acquiring) {
-                        try {
-                            r.wait();
-                        } catch (InterruptedException e) {
-                        }
-                    }
-                    holder = r.holder;
-                }
-            }
+            holder = ActivityManagerNative.getDefault().getContentProvider(
+                    getApplicationThread(), auth, userId, stable);
         } catch (RemoteException ex) {
-        } catch (RuntimeException e) {
-            synchronized (r) {
-                r.runtimeException = e;
-            }
-        } finally {
-            if (first) {
-                synchronized (r) {
-                    r.holder = holder;
-                    r.acquiring = false;
-                    r.notifyAll();
-                }
-            }
-
-            synchronized (mAcquiringProviderMap) {
-                if (--r.requests == 0) {
-                    mAcquiringProviderMap.remove(key);
-                }
-            }
-
-            if (r.runtimeException != null) {
-                // Was set when the first thread tried to acquire the provider,
-                // but we should make sure it is thrown for all threads trying to
-                // acquire the provider.
-                throw r.runtimeException;
-            }
         }
-
         if (holder == null) {
             Slog.e(TAG, "Failed to find provider info for " + auth);
             return null;
@@ -4866,12 +4810,8 @@
 
     public final IContentProvider acquireExistingProvider(
             Context c, String auth, int userId, boolean stable) {
-        return acquireExistingProvider(c, new ProviderKey(auth, userId), stable);
-    }
-
-    final IContentProvider acquireExistingProvider(
-            Context c, ProviderKey key, boolean stable) {
         synchronized (mProviderMap) {
+            final ProviderKey key = new ProviderKey(auth, userId);
             final ProviderClientRecord pr = mProviderMap.get(key);
             if (pr == null) {
                 return null;
@@ -4882,7 +4822,7 @@
             if (!jBinder.isBinderAlive()) {
                 // The hosting process of the provider has died; we can't
                 // use this one.
-                Log.i(TAG, "Acquiring provider " + key.authority + " for user " +  key.userId
+                Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
                         + ": existing object's process dead");
                 handleUnstableProviderDiedLocked(jBinder, true);
                 return null;
@@ -5204,12 +5144,18 @@
                     if (DEBUG_PROVIDER) {
                         Slog.v(TAG, "installProvider: lost the race, updating ref count");
                     }
-                    // The provider has already been installed, so we need
-                    // to increase reference count to the existing one, but
-                    // only if release is needed (that is, it is not running
-                    // in the system process or local to the process).
+                    // We need to transfer our new reference to the existing
+                    // ref count, releasing the old one...  but only if
+                    // release is needed (that is, it is not running in the
+                    // system process).
                     if (!noReleaseNeeded) {
                         incProviderRefLocked(prc, stable);
+                        try {
+                            ActivityManagerNative.getDefault().removeContentProvider(
+                                    holder.connection, stable);
+                        } catch (RemoteException e) {
+                            //do nothing content provider object is dead any way
+                        }
                     }
                 } else {
                     ProviderClientRecord client = installProviderAuthoritiesLocked(
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index e275df04..ac8d5d8 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -67,6 +67,8 @@
     void cancelNotificationFromListener(in INotificationListener token, String pkg, String tag, int id);
     void cancelNotificationsFromListener(in INotificationListener token, in String[] keys);
 
+    void setNotificationsShownFromListener(in INotificationListener token, in String[] keys);
+
     ParceledListSlice getActiveNotificationsFromListener(in INotificationListener token, in String[] keys, int trim);
     void requestHintsFromListener(in INotificationListener token, int hints);
     int getHintsFromListener(in INotificationListener token);
diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl
index 4ed1489..23659e3 100644
--- a/core/java/android/app/usage/IUsageStatsManager.aidl
+++ b/core/java/android/app/usage/IUsageStatsManager.aidl
@@ -30,4 +30,6 @@
     ParceledListSlice queryConfigurationStats(int bucketType, long beginTime, long endTime,
             String callingPackage);
     UsageEvents queryEvents(long beginTime, long endTime, String callingPackage);
+    void setAppIdle(String packageName, boolean idle, int userId);
+    boolean isAppIdle(String packageName, int userId);
 }
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index bc6099a..8a01d66 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.pm.ParceledListSlice;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.ArrayMap;
 
 import java.util.Collections;
@@ -217,4 +218,20 @@
         }
         return aggregatedStats;
     }
+
+    /**
+     * Returns whether the specified app is currently considered idle. This will be true if the
+     * app hasn't been used directly or indirectly for a period of time defined by the system. This
+     * could be of the order of several hours or days.
+     * @param packageName The package name of the app to query
+     * @return whether the app is currently considered idle
+     */
+    public boolean isAppIdle(String packageName) {
+        try {
+            return mService.isAppIdle(packageName, UserHandle.myUserId());
+        } catch (RemoteException e) {
+            // fall through and return default
+        }
+        return false;
+    }
 }
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index 691798f..a4d6be09 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -326,6 +326,9 @@
         }
 
         try {
+            startPreview(); // If preview is not running (i.e. after a JPEG capture), we need to
+                            // explicitely start and stop preview before setting preview surface.
+                            // null.
             stopPreview();
         }  catch (RuntimeException e) {
             Log.e(TAG, "Received device exception in configure call: ", e);
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 481fc2f..1b57055 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -1440,7 +1440,8 @@
 
     void showWindowInner(boolean showInput) {
         boolean doShowInput = false;
-        boolean wasVisible = mWindowVisible;
+        final int previousImeWindowStatus =
+                (mWindowVisible ? IME_ACTIVE : 0) | (isInputViewShown() ? IME_VISIBLE : 0);
         mWindowVisible = true;
         if (!mShowInputRequested) {
             if (mInputStarted) {
@@ -1485,9 +1486,12 @@
             startExtractingText(false);
         }
 
-        if (!wasVisible) {
+        final int nextImeWindowStatus = IME_ACTIVE | (isInputViewShown() ? IME_VISIBLE : 0);
+        if (previousImeWindowStatus != nextImeWindowStatus) {
+            mImm.setImeWindowStatus(mToken, nextImeWindowStatus, mBackDisposition);
+        }
+        if ((previousImeWindowStatus & IME_ACTIVE) == 0) {
             if (DEBUG) Log.v(TAG, "showWindow: showing!");
-            mImm.setImeWindowStatus(mToken, IME_ACTIVE, mBackDisposition);
             onWindowShown();
             mWindow.show();
         }
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 43309c0..8c1f44f 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -115,15 +115,15 @@
  * later reading.</p>
  * 
  * <p>There are also some methods that provide a more efficient way to work
- * with Parcelables: {@link #writeTypedArray},
- * {@link #writeTypedList(List)},
- * {@link #readTypedArray} and {@link #readTypedList}.  These methods
+ * with Parcelables: {@link #writeTypedObject}, {@link #writeTypedArray},
+ * {@link #writeTypedList}, {@link #readTypedObject},
+ * {@link #createTypedArray} and {@link #createTypedArrayList}.  These methods
  * do not write the class information of the original object: instead, the
  * caller of the read function must know what type to expect and pass in the
  * appropriate {@link Parcelable.Creator Parcelable.Creator} instead to
  * properly construct the new object and read its data.  (To more efficient
- * write and read a single Parceable object, you can directly call
- * {@link Parcelable#writeToParcel Parcelable.writeToParcel} and
+ * write and read a single Parceable object that is not null, you can directly
+ * call {@link Parcelable#writeToParcel Parcelable.writeToParcel} and
  * {@link Parcelable.Creator#createFromParcel Parcelable.Creator.createFromParcel}
  * yourself.)</p>
  * 
@@ -1223,6 +1223,24 @@
     }
 
     /**
+     * Flatten the Parcelable object into the parcel.
+     *
+     * @param val The Parcelable object to be written.
+     * @param parcelableFlags Contextual flags as per
+     * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
+     *
+     * @see #readTypedObject
+     */
+    public final <T extends Parcelable> void writeTypedObject(T val, int parcelableFlags) {
+        if (val != null) {
+            writeInt(1);
+            val.writeToParcel(this, parcelableFlags);
+        } else {
+            writeInt(0);
+        }
+    }
+
+    /**
      * Flatten a generic object in to a parcel.  The given Object value may
      * currently be one of the following types:
      *
@@ -2138,6 +2156,25 @@
     }
 
     /**
+     * Read and return a typed Parcelable object from a parcel.
+     * Returns null if the previous written object was null.
+     * The object <em>must</em> have previous been written via
+     * {@link #writeTypedObject} with the same object type.
+     *
+     * @return A newly created object of the type that was previously
+     *         written.
+     *
+     * @see #writeTypedObject
+     */
+    public final <T> T readTypedObject(Parcelable.Creator<T> c) {
+        if (readInt() != 0) {
+            return c.createFromParcel(this);
+        } else {
+            return null;
+        }
+    }
+
+    /**
      * Write a heterogeneous array of Parcelable objects into the Parcel.
      * Each object in the array is written along with its class name, so
      * that the correct class can later be instantiated.  As a result, this
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index cc7f880..35b8819 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -358,6 +358,20 @@
     }
 
     /**
+     * Inform the notification manager that these notifications have been viewed by the
+     * user.
+     * @param keys Notifications to mark as seen.
+     */
+    public final void setNotificationsShown(String[] keys) {
+        if (!isBound()) return;
+        try {
+            getNotificationInterface().setNotificationsShownFromListener(mWrapper, keys);
+        } catch (android.os.RemoteException ex) {
+            Log.v(TAG, "Unable to contact notification manager", ex);
+        }
+    }
+
+    /**
      * Sets the notification trim that will be received via {@link #onNotificationPosted}.
      *
      * <p>
diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java
index 0417921..4d1209a 100644
--- a/core/java/android/view/animation/AnimationUtils.java
+++ b/core/java/android/view/animation/AnimationUtils.java
@@ -16,7 +16,6 @@
 
 package android.view.animation;
 
-import android.content.res.Configuration;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -45,16 +44,6 @@
     private static final int TOGETHER = 0;
     private static final int SEQUENTIALLY = 1;
 
-    private static final float RECOMMENDED_FIELD_OF_VIEW_FOR_TV = 40f;
-    private static final float ESTIMATED_VIEWING_DISTANCE_FOR_WATCH = 11f;
-    private static final float AVERAGE_VIEWING_DISTANCE_FOR_PHONES = 14.2f;
-    private static final float N5_DIAGONAL_VIEW_ANGLE = 19.58f;
-    private static final float N5_DENSITY = 3.0f;
-    private static final float N5_DPI = 443f;
-
-    private static final float COTANGENT_OF_HALF_TV_ANGLE = (float)  (1 / Math.tan(Math.toRadians
-                (RECOMMENDED_FIELD_OF_VIEW_FOR_TV / 2)));
-
 
     /**
      * Returns the current animation time in milliseconds. This time should be used when invoking
@@ -378,78 +367,4 @@
         }
         return interpolator;
     }
-
-    /**
-     * Derives the viewing distance of a device based on the device size (in inches), and the
-     * device type.
-     * @hide
-     */
-    public static float getViewingDistance(float width, float height, int uiMode) {
-        if (uiMode == Configuration.UI_MODE_TYPE_TELEVISION) {
-            // TV
-            return (width / 2) * COTANGENT_OF_HALF_TV_ANGLE;
-        } else if (uiMode == Configuration.UI_MODE_TYPE_WATCH) {
-            // Watch
-            return ESTIMATED_VIEWING_DISTANCE_FOR_WATCH;
-        } else {
-            // Tablet, phone, etc
-            return AVERAGE_VIEWING_DISTANCE_FOR_PHONES;
-        }
-    }
-
-    /**
-     * Calculates the duration scaling factor of an animation based on the hint that the animation
-     * will move across the entire screen. A scaling factor of 1 means the duration on this given
-     * device will be the same as the duration set through
-     * {@link android.animation.Animator#setDuration(long)}. The calculation uses Nexus 5 as a
-     * baseline device. That is, the duration of the animation on a given device will scale its
-     * duration so that it has the same look and feel as the animation on Nexus 5. In order to
-     * achieve the same perceived effect of the animation across different devices, we maintain
-     * the same angular speed of the same animation in users' field of view. Therefore, the
-     * duration scale factor is determined by the ratio of the angular movement on current
-     * devices to that on the baseline device.
-     *
-     * @param width width of the screen (in inches)
-     * @param height height of the screen (in inches)
-     * @param viewingDistance the viewing distance of the device (i.e. watch, phone, TV, etc) in
-     *                        inches
-     * @return scaling factor (or multiplier) of the duration set through
-     * {@link android.animation.Animator#setDuration(long)} on current device.
-     * @hide
-     */
-    public static float getScreenSizeBasedDurationScale(float width, float height,
-            float viewingDistance) {
-        // Animation's moving distance is proportional to the screen size.
-        float diagonal = (float) Math.sqrt(width * width + height * height);
-        float diagonalViewAngle = (float) Math.toDegrees(Math.atan((diagonal / 2f)
-                / viewingDistance) * 2);
-        return diagonalViewAngle / N5_DIAGONAL_VIEW_ANGLE;
-    }
-
-    /**
-     * Calculates the duration scaling factor of an animation under the assumption that the
-     * animation is defined to move the same amount of distance (in dp) across all devices. A
-     * scaling factor of 1 means the duration on this given device will be the same as the
-     * duration set through {@link android.animation.Animator#setDuration(long)}. The calculation
-     * uses Nexus 5 as a baseline device. That is, the duration of the animation on a given
-     * device will scale its duration so that it has the same look and feel as the animation on
-     * Nexus 5. In order to achieve the same perceived effect of the animation across different
-     * devices, we maintain the same angular velocity of the same animation in users' field of
-     * view. Therefore, the duration scale factor is determined by the ratio of the angular
-     * movement on current devices to that on the baseline device.
-     *
-     * @param density logical density of the display. {@link android.util.DisplayMetrics#density}
-     * @param dpi pixels per inch
-     * @param viewingDistance viewing distance of the device (in inches)
-     * @return the scaling factor of duration
-     * @hide
-     */
-    public static float getDpBasedDurationScale(float density, float dpi,
-            float viewingDistance) {
-        // Angle in users' field of view per dp:
-        float anglePerDp = (float) Math.atan2((density / dpi) / 2, viewingDistance) * 2;
-        float baselineAnglePerDp = (float) Math.atan2((N5_DENSITY / N5_DPI) / 2,
-                AVERAGE_VIEWING_DISTANCE_FOR_PHONES) * 2;
-        return anglePerDp / baselineAnglePerDp;
-    }
 }
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 9ecdc9c..c959774 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1854,20 +1854,19 @@
                     moved = true;
                 }
                 break;
-            case FOCUS_LEFT:
-                if (selectedPosition > startOfRowPos) {
-                    mLayoutMode = LAYOUT_MOVE_SELECTION;
-                    setSelectionInt(Math.max(0, selectedPosition - 1));
-                    moved = true;
-                }
-                break;
-            case FOCUS_RIGHT:
-                if (selectedPosition < endOfRowPos) {
-                    mLayoutMode = LAYOUT_MOVE_SELECTION;
-                    setSelectionInt(Math.min(selectedPosition + 1, mItemCount - 1));
-                    moved = true;
-                }
-                break;
+        }
+
+        final boolean isLayoutRtl = isLayoutRtl();
+        if (selectedPosition > startOfRowPos && ((direction == FOCUS_LEFT && !isLayoutRtl) ||
+                (direction == FOCUS_RIGHT && isLayoutRtl))) {
+            mLayoutMode = LAYOUT_MOVE_SELECTION;
+            setSelectionInt(Math.max(0, selectedPosition - 1));
+            moved = true;
+        } else if (selectedPosition < endOfRowPos && ((direction == FOCUS_LEFT && isLayoutRtl) ||
+                (direction == FOCUS_RIGHT && !isLayoutRtl))) {
+            mLayoutMode = LAYOUT_MOVE_SELECTION;
+            setSelectionInt(Math.min(selectedPosition + 1, mItemCount - 1));
+            moved = true;
         }
 
         if (moved) {
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index a50941b..10e4db3 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -1335,10 +1335,6 @@
         // If we are not connected, queue up the notifyDataSetChanged to be handled when we do
         // connect
         if (!mServiceConnection.isConnected()) {
-            if (mNotifyDataSetChangedAfterOnServiceConnected) {
-                return;
-            }
-
             mNotifyDataSetChangedAfterOnServiceConnected = true;
             requestBindService();
             return;
diff --git a/core/java/android/widget/ZoomButtonsController.java b/core/java/android/widget/ZoomButtonsController.java
index f7e9648..c0c8aec 100644
--- a/core/java/android/widget/ZoomButtonsController.java
+++ b/core/java/android/widget/ZoomButtonsController.java
@@ -403,7 +403,7 @@
             // No longer care about configuration changes
             mContext.unregisterReceiver(mConfigurationChangedReceiver);
 
-            mWindowManager.removeView(mContainer);
+            mWindowManager.removeViewImmediate(mContainer);
             mHandler.removeCallbacks(mPostedVisibleInitializer);
 
             if (mCallback != null) {
@@ -490,7 +490,7 @@
                     setVisible(false);
                     return true;
                 }
-                
+
             } else {
                 dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT);
             }
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 8b2c269..2f6a69c 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -189,32 +189,44 @@
     return getAudioTrack(env, audioTrackObj);
 }
 
+// This function converts Java channel masks to a native channel mask.
+// validity should be checked with audio_is_output_channel().
+static inline audio_channel_mask_t nativeChannelMaskFromJavaChannelMasks(
+        jint channelPositionMask, jint channelIndexMask)
+{
+    if (channelIndexMask != 0) {  // channel index mask takes priority
+        // To convert to a native channel mask, the Java channel index mask
+        // requires adding the index representation.
+        return audio_channel_mask_from_representation_and_bits(
+                        AUDIO_CHANNEL_REPRESENTATION_INDEX,
+                        channelIndexMask);
+    }
+    // To convert to a native channel mask, the Java channel position mask
+    // requires a shift by 2 to skip the two deprecated channel
+    // configurations "default" and "mono".
+    return (audio_channel_mask_t)(channelPositionMask >> 2);
+}
+
 // ----------------------------------------------------------------------------
 static jint
 android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject weak_this,
         jobject jaa,
-        jint sampleRateInHertz, jint javaChannelMask,
+        jint sampleRateInHertz, jint channelPositionMask, jint channelIndexMask,
         jint audioFormat, jint buffSizeInBytes, jint memoryMode, jintArray jSession) {
 
-    ALOGV("sampleRate=%d, audioFormat(from Java)=%d, channel mask=%x, buffSize=%d",
-        sampleRateInHertz, audioFormat, javaChannelMask, buffSizeInBytes);
+    ALOGV("sampleRate=%d, channel mask=%x, index mask=%x, audioFormat(Java)=%d, buffSize=%d",
+        sampleRateInHertz, channelPositionMask, channelIndexMask, audioFormat, buffSizeInBytes);
 
     if (jaa == 0) {
         ALOGE("Error creating AudioTrack: invalid audio attributes");
         return (jint) AUDIO_JAVA_ERROR;
     }
 
-    // Java channel masks don't map directly to the native definition for positional
-    // channel masks: it's a shift by 2 to skip the two deprecated channel
-    // configurations "default" and "mono".
     // Invalid channel representations are caught by !audio_is_output_channel() below.
-    audio_channel_mask_t nativeChannelMask =
-            audio_channel_mask_get_representation(javaChannelMask)
-                == AUDIO_CHANNEL_REPRESENTATION_POSITION
-            ? javaChannelMask >> 2 : javaChannelMask;
-
+    audio_channel_mask_t nativeChannelMask = nativeChannelMaskFromJavaChannelMasks(
+            channelPositionMask, channelIndexMask);
     if (!audio_is_output_channel(nativeChannelMask)) {
-        ALOGE("Error creating AudioTrack: invalid channel mask %#x.", javaChannelMask);
+        ALOGE("Error creating AudioTrack: invalid native channel mask %#x.", nativeChannelMask);
         return (jint) AUDIOTRACK_ERROR_SETUP_INVALIDCHANNELMASK;
     }
 
@@ -982,7 +994,7 @@
     {"native_stop",          "()V",      (void *)android_media_AudioTrack_stop},
     {"native_pause",         "()V",      (void *)android_media_AudioTrack_pause},
     {"native_flush",         "()V",      (void *)android_media_AudioTrack_flush},
-    {"native_setup",     "(Ljava/lang/Object;Ljava/lang/Object;IIIII[I)I",
+    {"native_setup",     "(Ljava/lang/Object;Ljava/lang/Object;IIIIII[I)I",
                                          (void *)android_media_AudioTrack_setup},
     {"native_finalize",      "()V",      (void *)android_media_AudioTrack_finalize},
     {"native_release",       "()V",      (void *)android_media_AudioTrack_release},
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4f26eb2..018c1a1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2106,6 +2106,11 @@
         android:protectionLevel="signature|development|appop" />
     <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
 
+    <!-- @hide Allows an application to change the app idle state of an app.
+         <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.CHANGE_APP_IDLE_STATE"
+        android:protectionLevel="signature" />
+
     <!-- @SystemApi Allows an application to collect battery statistics -->
     <permission android:name="android.permission.BATTERY_STATS"
         android:protectionLevel="signature|system|development" />
diff --git a/core/res/res/drawable/list_highlight_material.xml b/core/res/res/drawable/list_choice_background_material.xml
similarity index 100%
rename from core/res/res/drawable/list_highlight_material.xml
rename to core/res/res/drawable/list_choice_background_material.xml
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 00c771d8..887b0a5 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -6038,19 +6038,8 @@
             <!-- values are colors, which are integers starting with "#". -->
             <enum name="colorType"   value="3" />
         </attr>
-        <!-- Defines whether the animation should adjust duration in order to achieve the same
-             perceived effects on different devices. -->
-        <attr name="durationScaleHint" >
-            <!-- Default value for scale hint. When set, duration will not be scaled.-->
-            <enum name="noScale" value="0"/>
-            <!-- This should be used when the animation's moving distance is proportional to screen,
-                 as the scaling is based on screen size. -->
-            <enum name="screenBased" value="1"/>
-            <!-- This is for animations that have a distance defined in dp, which will be the same
-                 across different devices. In this case, scaling is based on the physical distance
-                 per dp on the current device. -->
-            <enum name="dpBased" value="2"/>
-        </attr>
+        <!-- Placeholder for a deleted attribute. This should be removed before M release. -->
+        <attr name="removeBeforeMRelease" format="integer" />
     </declare-styleable>
 
     <declare-styleable name="PropertyValuesHolder">
@@ -6099,7 +6088,6 @@
             <!-- child animations should be played sequentially, in the same order as the xml. -->
             <enum name="sequentially" value="1" />
         </attr>
-        <attr name="durationScaleHint" />
     </declare-styleable>
 
     <!-- ========================== -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index baccafd..875659d 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2664,8 +2664,8 @@
   <public type="attr" name="supportsAssistGesture" />
   <public type="attr" name="thumbPosition" />
 
-  <!-- Animation -->
-  <public type="attr" name="durationScaleHint" />
+  <!-- Placeholder for a removed attribute. Remove this before M release. -->
+  <public type="attr" name="removeBeforeMRelease" />
 
   <public type="attr" name="lockTaskMode" />
 
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index db178fa..f81ee8c 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -614,7 +614,7 @@
     <style name="Widget.Material.GestureOverlayView" parent="Widget.GestureOverlayView"/>
 
     <style name="Widget.Material.GridView" parent="Widget.GridView">
-        <item name="listSelector">?attr/selectableItemBackground</item>
+        <item name="listSelector">?attr/listChoiceBackgroundIndicator</item>
     </style>
 
     <style name="Widget.Material.CalendarView" parent="Widget.CalendarView">
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index a413d91..e8aab07 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -129,8 +129,8 @@
         <item name="listChoiceIndicatorSingle">@drawable/btn_radio_material_anim</item>
         <item name="listChoiceIndicatorMultiple">@drawable/btn_check_material_anim</item>
 
-        <item name="listChoiceBackgroundIndicator">@drawable/list_highlight_material</item>
-        <item name="activatedBackgroundIndicator">@null</item>
+        <item name="listChoiceBackgroundIndicator">@drawable/list_choice_background_material</item>
+        <item name="activatedBackgroundIndicator">@drawable/activated_background_material</item>
 
         <item name="listDividerAlertDialog">@null</item>
 
@@ -485,7 +485,7 @@
         <item name="listChoiceIndicatorSingle">@drawable/btn_radio_material_anim</item>
         <item name="listChoiceIndicatorMultiple">@drawable/btn_check_material_anim</item>
 
-        <item name="listChoiceBackgroundIndicator">?attr/selectableItemBackground</item>
+        <item name="listChoiceBackgroundIndicator">@drawable/list_choice_background_material</item>
         <item name="activatedBackgroundIndicator">@drawable/activated_background_material</item>
 
         <item name="expandableListPreferredItemPaddingLeft">40dip</item>
diff --git a/docs/html/google/play-services/index.jd b/docs/html/google/play-services/index.jd
index d674f7f..5ccdcb9 100644
--- a/docs/html/google/play-services/index.jd
+++ b/docs/html/google/play-services/index.jd
@@ -74,30 +74,8 @@
 <a href="http://android-developers.blogspot.com/2015/04/theres-lot-to-explore-with-google-play.html"
 class="external-link">blog post</a>.</p>
 <ul>
-  <li><strong>Maps</strong> - This release makes the Google Maps Android API v2 available on
-<a href="https://developers.google.com/maps/documentation/android/wear" class="external-link">
-Android Wear</a>, so you can now create map-based apps that run directly on wearable devices. In
-addition, the Maps API now offers a new
-<a href="{@docRoot}reference/com/google/android/gms/maps/StreetViewPanorama.OnStreetViewPanoramaLongClickListener.html">
-{@code OnStreetViewPanoramaLongClickListener}</a> interface, similar to the existing
-<a href="{@docRoot}reference/com/google/android/gms/maps/GoogleMap.OnMapLongClickListener.html">
-{@code OnMapLongClickListener}</a> interface. These listeners are particularly helpful
-for wearable devices, so you can let users exit from the app by long-clicking on a map or panorama.
-On a wearable device, the swipe gesture is used to pan the map instead of exiting the app.
-    <ul>
-      <li><a href="https://developers.google.com/maps/documentation/android/wear"
-        class="external-link">Google Maps on Android Wear developer guide</a>
-      </li>
-      <li><a href="https://github.com/googlemaps/android-samples/tree/master/BasicWearMap"
-        class="external-link">Google Maps on Android Wear sample</a>
-      </li>
-      <li><a href="https://developers.google.com/maps/documentation/android/releases"
-        class="external-link">Release notes</a>
-      </li>
-    </ul>
-  </li>
   <li>
-    <strong>Wear</strong> - In addition to Maps support, this release provides you with the ability
+    <strong>Wear</strong> - This release provides you with the ability
 to advertise and discover the capabilities of devices that are connected in a Wear network, through
 the new <a href="{@docRoot}reference/com/google/android/gms/wearable/CapabilityApi.html">
 {@code CapabilityApi}</a> class. The new
diff --git a/keystore/java/android/security/AndroidKeyPairGenerator.java b/keystore/java/android/security/AndroidKeyPairGenerator.java
index 5fae831..3b25ba6 100644
--- a/keystore/java/android/security/AndroidKeyPairGenerator.java
+++ b/keystore/java/android/security/AndroidKeyPairGenerator.java
@@ -17,7 +17,7 @@
 package android.security;
 
 import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
-import com.android.org.conscrypt.NativeCrypto;
+import com.android.org.conscrypt.NativeConstants;
 import com.android.org.conscrypt.OpenSSLEngine;
 
 import java.security.InvalidAlgorithmParameterException;
@@ -206,9 +206,9 @@
     }
 
     private static int getDefaultKeySize(int keyType) {
-        if (keyType == NativeCrypto.EVP_PKEY_EC) {
+        if (keyType == NativeConstants.EVP_PKEY_EC) {
             return EC_DEFAULT_KEY_SIZE;
-        } else if (keyType == NativeCrypto.EVP_PKEY_RSA) {
+        } else if (keyType == NativeConstants.EVP_PKEY_RSA) {
             return RSA_DEFAULT_KEY_SIZE;
         }
         return -1;
@@ -216,12 +216,12 @@
 
     private static void checkValidKeySize(String keyAlgorithm, int keyType, int keySize)
             throws InvalidAlgorithmParameterException {
-        if (keyType == NativeCrypto.EVP_PKEY_EC) {
+        if (keyType == NativeConstants.EVP_PKEY_EC) {
             if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
                 throw new InvalidAlgorithmParameterException("EC keys must be >= "
                         + EC_MIN_KEY_SIZE + " and <= " + EC_MAX_KEY_SIZE);
             }
-        } else if (keyType == NativeCrypto.EVP_PKEY_RSA) {
+        } else if (keyType == NativeConstants.EVP_PKEY_RSA) {
             if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
                 throw new InvalidAlgorithmParameterException("RSA keys must be >= "
                         + RSA_MIN_KEY_SIZE + " and <= " + RSA_MAX_KEY_SIZE);
@@ -234,7 +234,7 @@
 
     private static void checkCorrectParametersSpec(int keyType, int keySize,
             AlgorithmParameterSpec spec) throws InvalidAlgorithmParameterException {
-        if (keyType == NativeCrypto.EVP_PKEY_RSA && spec != null) {
+        if (keyType == NativeConstants.EVP_PKEY_RSA && spec != null) {
             if (spec instanceof RSAKeyGenParameterSpec) {
                 RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec;
                 if (keySize != -1 && keySize != rsaSpec.getKeysize()) {
@@ -260,7 +260,7 @@
 
     private static byte[][] getArgsForKeyType(int keyType, AlgorithmParameterSpec spec) {
         switch (keyType) {
-            case NativeCrypto.EVP_PKEY_RSA:
+            case NativeConstants.EVP_PKEY_RSA:
                 if (spec instanceof RSAKeyGenParameterSpec) {
                     RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec;
                     return new byte[][] { rsaSpec.getPublicExponent().toByteArray() };
diff --git a/keystore/java/android/security/CryptoOperationException.java b/keystore/java/android/security/CryptoOperationException.java
deleted file mode 100644
index 1c9d005..0000000
--- a/keystore/java/android/security/CryptoOperationException.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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;
-
-/**
- * Base class for exceptions during cryptographic operations which cannot throw a suitable checked
- * exception.
- *
- * <p>The contract of the majority of crypto primitives/operations (e.g. {@code Cipher} or
- * {@code Signature}) is that they can throw a checked exception during initialization, but are not
- * permitted to throw a checked exception during operation. Because crypto operations can fail
- * for a variety of reasons after initialization, this base class provides type-safety for unchecked
- * exceptions that may be thrown in those cases.
- */
-public class CryptoOperationException extends RuntimeException {
-
-    /**
-     * Constructs a new {@code CryptoOperationException} without detail message and cause.
-     */
-    public CryptoOperationException() {
-        super();
-    }
-
-    /**
-     * Constructs a new {@code CryptoOperationException} with the provided detail message and no
-     * cause.
-     */
-    public CryptoOperationException(String message) {
-        super(message);
-    }
-
-    /**
-     * Constructs a new {@code CryptoOperationException} with the provided detail message and cause.
-     */
-    public CryptoOperationException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-    /**
-     * Constructs a new {@code CryptoOperationException} with the provided cause.
-     */
-    public CryptoOperationException(Throwable cause) {
-        super(cause);
-    }
-}
diff --git a/keystore/java/android/security/KeyExpiredException.java b/keystore/java/android/security/KeyExpiredException.java
index a02dc33..f58e48a 100644
--- a/keystore/java/android/security/KeyExpiredException.java
+++ b/keystore/java/android/security/KeyExpiredException.java
@@ -16,11 +16,13 @@
 
 package android.security;
 
+import java.security.InvalidKeyException;
+
 /**
  * Indicates that a cryptographic operation failed because the employed key's validity end date
  * is in the past.
  */
-public class KeyExpiredException extends CryptoOperationException {
+public class KeyExpiredException extends InvalidKeyException {
 
     /**
      * Constructs a new {@code KeyExpiredException} without detail message and cause.
diff --git a/keystore/java/android/security/KeyNotYetValidException.java b/keystore/java/android/security/KeyNotYetValidException.java
index 964cd7e..4ea27ef 100644
--- a/keystore/java/android/security/KeyNotYetValidException.java
+++ b/keystore/java/android/security/KeyNotYetValidException.java
@@ -16,11 +16,13 @@
 
 package android.security;
 
+import java.security.InvalidKeyException;
+
 /**
  * Indicates that a cryptographic operation failed because the employed key's validity start date
  * is in the future.
  */
-public class KeyNotYetValidException extends CryptoOperationException {
+public class KeyNotYetValidException extends InvalidKeyException {
 
     /**
      * Constructs a new {@code KeyNotYetValidException} without detail message and cause.
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 5af0527..8c49ff0 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -16,7 +16,7 @@
 
 package android.security;
 
-import com.android.org.conscrypt.NativeCrypto;
+import com.android.org.conscrypt.NativeConstants;
 
 import android.os.Binder;
 import android.os.IBinder;
@@ -30,6 +30,7 @@
 import android.security.keymaster.OperationResult;
 import android.util.Log;
 
+import java.security.InvalidKeyException;
 import java.util.Locale;
 
 /**
@@ -87,9 +88,9 @@
 
     static int getKeyTypeForAlgorithm(String keyType) {
         if ("RSA".equalsIgnoreCase(keyType)) {
-            return NativeCrypto.EVP_PKEY_RSA;
+            return NativeConstants.EVP_PKEY_RSA;
         } else if ("EC".equalsIgnoreCase(keyType)) {
-            return NativeCrypto.EVP_PKEY_EC;
+            return NativeConstants.EVP_PKEY_EC;
         } else {
             return -1;
         }
@@ -508,7 +509,11 @@
         }
     }
 
-    public static KeyStoreException getKeyStoreException(int errorCode) {
+    /**
+     * Returns a {@link KeyStoreException} corresponding to the provided keystore/keymaster error
+     * code.
+     */
+    static KeyStoreException getKeyStoreException(int errorCode) {
         if (errorCode > 0) {
             // KeyStore layer error
             switch (errorCode) {
@@ -544,7 +549,11 @@
         }
     }
 
-    public static CryptoOperationException getCryptoOperationException(KeyStoreException e) {
+    /**
+     * Returns an {@link InvalidKeyException} corresponding to the provided
+     * {@link KeyStoreException}.
+     */
+    static InvalidKeyException getInvalidKeyException(KeyStoreException e) {
         switch (e.getErrorCode()) {
             case KeymasterDefs.KM_ERROR_KEY_EXPIRED:
                 return new KeyExpiredException();
@@ -556,11 +565,15 @@
             // case KeymasterDefs.KM_ERROR_TBD
             //     return new NewFingerprintEnrolledException();
             default:
-                return new CryptoOperationException("Crypto operation failed", e);
+                return new InvalidKeyException("Keystore operation failed", e);
         }
     }
 
-    public static CryptoOperationException getCryptoOperationException(int errorCode) {
-        return getCryptoOperationException(getKeyStoreException(errorCode));
+    /**
+     * Returns an {@link InvalidKeyException} corresponding to the provided keystore/keymaster error
+     * code.
+     */
+    static InvalidKeyException getInvalidKeyException(int errorCode) {
+        return getInvalidKeyException(getKeyStoreException(errorCode));
     }
 }
diff --git a/keystore/java/android/security/KeyStoreCipherSpi.java b/keystore/java/android/security/KeyStoreCipherSpi.java
index 1f8d8ec..3b13e83 100644
--- a/keystore/java/android/security/KeyStoreCipherSpi.java
+++ b/keystore/java/android/security/KeyStoreCipherSpi.java
@@ -136,6 +136,14 @@
     private Long mOperationHandle;
     private KeyStoreCryptoOperationChunkedStreamer mMainDataStreamer;
 
+    /**
+     * Encountered exception which could not be immediately thrown because it was encountered inside
+     * a method that does not throw checked exception. This exception will be thrown from
+     * {@code engineDoFinal}. Once such an exception is encountered, {@code engineUpdate} and
+     * {@code engineDoFinal} start ignoring input data.
+     */
+    private Exception mCachedException;
+
     protected KeyStoreCipherSpi(
             int keymasterAlgorithm,
             int keymasterBlockMode,
@@ -158,7 +166,11 @@
         try {
             init(opmode, key, random);
             initAlgorithmSpecificParameters();
-            ensureKeystoreOperationInitialized();
+            try {
+                ensureKeystoreOperationInitialized();
+            } catch (InvalidAlgorithmParameterException e) {
+                throw new InvalidKeyException(e);
+            }
             success = true;
         } finally {
             if (!success) {
@@ -236,6 +248,7 @@
         mOperationToken = null;
         mOperationHandle = null;
         mMainDataStreamer = null;
+        mCachedException = null;
     }
 
     private void resetWhilePreservingInitState() {
@@ -247,12 +260,17 @@
         mOperationHandle = null;
         mMainDataStreamer = null;
         mAdditionalEntropyForBegin = null;
+        mCachedException = null;
     }
 
-    private void ensureKeystoreOperationInitialized() {
+    private void ensureKeystoreOperationInitialized() throws InvalidKeyException,
+            InvalidAlgorithmParameterException {
         if (mMainDataStreamer != null) {
             return;
         }
+        if (mCachedException != null) {
+            return;
+        }
         if (mKey == null) {
             throw new IllegalStateException("Not initialized");
         }
@@ -281,11 +299,15 @@
         if (opResult == null) {
             throw new KeyStoreConnectException();
         } else if (opResult.resultCode != KeyStore.NO_ERROR) {
-            throw KeyStore.getCryptoOperationException(opResult.resultCode);
+            switch (opResult.resultCode) {
+                case KeymasterDefs.KM_ERROR_INVALID_NONCE:
+                    throw new InvalidAlgorithmParameterException("Invalid IV");
+            }
+            throw KeyStore.getInvalidKeyException(opResult.resultCode);
         }
 
         if (opResult.token == null) {
-            throw new CryptoOperationException("Keystore returned null operation token");
+            throw new IllegalStateException("Keystore returned null operation token");
         }
         mOperationToken = opResult.token;
         mOperationHandle = opResult.operationHandle;
@@ -299,7 +321,15 @@
 
     @Override
     protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
-        ensureKeystoreOperationInitialized();
+        if (mCachedException != null) {
+            return null;
+        }
+        try {
+            ensureKeystoreOperationInitialized();
+        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
+            mCachedException = e;
+            return null;
+        }
 
         if (inputLen == 0) {
             return null;
@@ -309,7 +339,8 @@
         try {
             output = mMainDataStreamer.update(input, inputOffset, inputLen);
         } catch (KeyStoreException e) {
-            throw KeyStore.getCryptoOperationException(e);
+            mCachedException = e;
+            return null;
         }
 
         if (output.length == 0) {
@@ -338,7 +369,16 @@
     @Override
     protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
             throws IllegalBlockSizeException, BadPaddingException {
-        ensureKeystoreOperationInitialized();
+        if (mCachedException != null) {
+            throw (IllegalBlockSizeException)
+                    new IllegalBlockSizeException().initCause(mCachedException);
+        }
+
+        try {
+            ensureKeystoreOperationInitialized();
+        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
+            throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e);
+        }
 
         byte[] output;
         try {
@@ -352,7 +392,7 @@
                 case KeymasterDefs.KM_ERROR_VERIFICATION_FAILED:
                     throw new AEADBadTagException();
                 default:
-                    throw KeyStore.getCryptoOperationException(e);
+                    throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e);
             }
         }
 
@@ -613,11 +653,11 @@
             if (mIv == null) {
                 mIv = returnedIv;
             } else if ((returnedIv != null) && (!Arrays.equals(returnedIv, mIv))) {
-                throw new CryptoOperationException("IV in use differs from provided IV");
+                throw new IllegalStateException("IV in use differs from provided IV");
             }
         } else {
             if (returnedIv != null) {
-                throw new CryptoOperationException(
+                throw new IllegalStateException(
                         "IV in use despite IV not being used by this transformation");
             }
         }
diff --git a/keystore/java/android/security/KeyStoreConnectException.java b/keystore/java/android/security/KeyStoreConnectException.java
index 8ed6e04..1aa3aec 100644
--- a/keystore/java/android/security/KeyStoreConnectException.java
+++ b/keystore/java/android/security/KeyStoreConnectException.java
@@ -21,7 +21,7 @@
  *
  * @hide
  */
-public class KeyStoreConnectException extends CryptoOperationException {
+public class KeyStoreConnectException extends IllegalStateException {
     public KeyStoreConnectException() {
         super("Failed to communicate with keystore service");
     }
diff --git a/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
index aafd2fa..0619199 100644
--- a/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
+++ b/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
@@ -136,7 +136,7 @@
                     // More input is available, but it wasn't included into the previous chunk
                     // because the chunk reached its maximum permitted size.
                     // Shouldn't have happened.
-                    throw new CryptoOperationException("Nothing consumed from max-sized chunk: "
+                    throw new IllegalStateException("Nothing consumed from max-sized chunk: "
                             + chunk.length + " bytes");
                 }
                 mBuffered = chunk;
@@ -148,7 +148,7 @@
                 mBufferedOffset = opResult.inputConsumed;
                 mBufferedLength = chunk.length - opResult.inputConsumed;
             } else {
-                throw new CryptoOperationException("Consumed more than provided: "
+                throw new IllegalStateException("Consumed more than provided: "
                         + opResult.inputConsumed + ", provided: " + chunk.length);
             }
 
@@ -160,7 +160,7 @@
                         try {
                             bufferedOutput.write(opResult.output);
                         } catch (IOException e) {
-                            throw new CryptoOperationException("Failed to buffer output", e);
+                            throw new IllegalStateException("Failed to buffer output", e);
                         }
                     }
                 } else {
@@ -173,7 +173,7 @@
                         try {
                             bufferedOutput.write(opResult.output);
                         } catch (IOException e) {
-                            throw new CryptoOperationException("Failed to buffer output", e);
+                            throw new IllegalStateException("Failed to buffer output", e);
                         }
                         return bufferedOutput.toByteArray();
                     }
@@ -233,10 +233,10 @@
         }
 
         if (opResult.inputConsumed < chunk.length) {
-            throw new CryptoOperationException("Keystore failed to consume all input. Provided: "
+            throw new IllegalStateException("Keystore failed to consume all input. Provided: "
                     + chunk.length + ", consumed: " + opResult.inputConsumed);
         } else if (opResult.inputConsumed > chunk.length) {
-            throw new CryptoOperationException("Keystore consumed more input than provided"
+            throw new IllegalStateException("Keystore consumed more input than provided"
                     + " . Provided: " + chunk.length + ", consumed: " + opResult.inputConsumed);
         }
 
diff --git a/keystore/java/android/security/KeyStoreHmacSpi.java b/keystore/java/android/security/KeyStoreHmacSpi.java
index f8b6fef..175369c 100644
--- a/keystore/java/android/security/KeyStoreHmacSpi.java
+++ b/keystore/java/android/security/KeyStoreHmacSpi.java
@@ -147,7 +147,7 @@
         resetWhilePreservingInitState();
     }
 
-    private void ensureKeystoreOperationInitialized() {
+    private void ensureKeystoreOperationInitialized() throws InvalidKeyException {
         if (mChunkedStreamer != null) {
             return;
         }
@@ -169,10 +169,10 @@
         if (opResult == null) {
             throw new KeyStoreConnectException();
         } else if (opResult.resultCode != KeyStore.NO_ERROR) {
-            throw KeyStore.getCryptoOperationException(opResult.resultCode);
+            throw KeyStore.getInvalidKeyException(opResult.resultCode);
         }
         if (opResult.token == null) {
-            throw new CryptoOperationException("Keystore returned null operation token");
+            throw new IllegalStateException("Keystore returned null operation token");
         }
         mOperationToken = opResult.token;
         mOperationHandle = opResult.operationHandle;
@@ -188,28 +188,36 @@
 
     @Override
     protected void engineUpdate(byte[] input, int offset, int len) {
-        ensureKeystoreOperationInitialized();
+        try {
+            ensureKeystoreOperationInitialized();
+        } catch (InvalidKeyException e) {
+            throw new IllegalStateException("Failed to reinitialize MAC", e);
+        }
 
         byte[] output;
         try {
             output = mChunkedStreamer.update(input, offset, len);
         } catch (KeyStoreException e) {
-            throw KeyStore.getCryptoOperationException(e);
+            throw new IllegalStateException("Keystore operation failed", e);
         }
         if ((output != null) && (output.length != 0)) {
-            throw new CryptoOperationException("Update operation unexpectedly produced output");
+            throw new IllegalStateException("Update operation unexpectedly produced output");
         }
     }
 
     @Override
     protected byte[] engineDoFinal() {
-        ensureKeystoreOperationInitialized();
+        try {
+            ensureKeystoreOperationInitialized();
+        } catch (InvalidKeyException e) {
+            throw new IllegalStateException("Failed to reinitialize MAC", e);
+        }
 
         byte[] result;
         try {
             result = mChunkedStreamer.doFinal(null, 0, 0);
         } catch (KeyStoreException e) {
-            throw KeyStore.getCryptoOperationException(e);
+            throw new IllegalStateException("Keystore operation failed", e);
         }
 
         resetWhilePreservingInitState();
diff --git a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
index d1abe12..293c4c9 100644
--- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
@@ -210,7 +210,8 @@
         int errorCode = mKeyStore.generateKey(
                 keyAliasInKeystore, args, additionalEntropy, flags, new KeyCharacteristics());
         if (errorCode != KeyStore.NO_ERROR) {
-            throw KeyStore.getCryptoOperationException(errorCode);
+            throw new IllegalStateException(
+                    "Keystore operation failed", KeyStore.getKeyStoreException(errorCode));
         }
         String keyAlgorithmJCA =
                 KeymasterUtils.getJcaSecretKeyAlgorithm(mKeymasterAlgorithm, mKeymasterDigest);
diff --git a/keystore/java/android/security/NewFingerprintEnrolledException.java b/keystore/java/android/security/NewFingerprintEnrolledException.java
index 806b214..4fe210b 100644
--- a/keystore/java/android/security/NewFingerprintEnrolledException.java
+++ b/keystore/java/android/security/NewFingerprintEnrolledException.java
@@ -16,11 +16,13 @@
 
 package android.security;
 
+import java.security.InvalidKeyException;
+
 /**
  * Indicates that a cryptographic operation could not be performed because the key used by the
  * operation is permanently invalid because a new fingerprint was enrolled.
  */
-public class NewFingerprintEnrolledException extends CryptoOperationException {
+public class NewFingerprintEnrolledException extends InvalidKeyException {
 
     /**
      * Constructs a new {@code NewFingerprintEnrolledException} without detail message and cause.
diff --git a/keystore/java/android/security/UserNotAuthenticatedException.java b/keystore/java/android/security/UserNotAuthenticatedException.java
index f5f5f41..66f4dd8 100644
--- a/keystore/java/android/security/UserNotAuthenticatedException.java
+++ b/keystore/java/android/security/UserNotAuthenticatedException.java
@@ -16,11 +16,13 @@
 
 package android.security;
 
+import java.security.InvalidKeyException;
+
 /**
  * Indicates that a cryptographic operation could not be performed because the user has not been
  * authenticated recently enough.
  */
-public class UserNotAuthenticatedException extends CryptoOperationException {
+public class UserNotAuthenticatedException extends InvalidKeyException {
 
     /**
      * Constructs a new {@code UserNotAuthenticatedException} without detail message and cause.
diff --git a/keystore/tests/src/android/security/AndroidKeyStoreTest.java b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
index 7a88dee..a7046dd2 100644
--- a/keystore/tests/src/android/security/AndroidKeyStoreTest.java
+++ b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
@@ -18,7 +18,7 @@
 
 import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
 
-import com.android.org.conscrypt.NativeCrypto;
+import com.android.org.conscrypt.NativeConstants;
 import com.android.org.conscrypt.OpenSSLEngine;
 
 import android.test.AndroidTestCase;
@@ -768,7 +768,7 @@
         assertAliases(new String[] {});
 
         assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
+                KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
                 null));
 
         assertAliases(new String[] { TEST_ALIAS_1 });
@@ -797,7 +797,7 @@
         assertAliases(new String[] {});
 
         assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
+                KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
                 null));
 
         assertTrue("Should contain generated private key", mKeyStore.containsAlias(TEST_ALIAS_1));
@@ -1963,7 +1963,7 @@
         {
             final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
             assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
-                    NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
+                    NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
 
             Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
 
@@ -2019,7 +2019,7 @@
         {
             final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
             assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
-                    NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
+                    NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
 
             X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
                     TEST_SERIAL_1, TEST_DN_1, NOW, NOW_PLUS_10_YEARS);
@@ -2032,7 +2032,7 @@
         {
             final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_2;
             assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
-                    NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
+                    NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
 
             X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_2,
                     TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
@@ -2064,7 +2064,7 @@
         {
             final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
             assertTrue(mAndroidKeyStore.generate(privateKeyAlias,
-                    android.security.KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024,
+                    android.security.KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024,
                     android.security.KeyStore.FLAG_NONE, null));
 
             X509Certificate cert =
@@ -2116,7 +2116,7 @@
         assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
 
         assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3,
-                KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
+                KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
                 null));
 
         assertEquals("The keystore size should match expected", 3, mKeyStore.size());
@@ -2184,7 +2184,7 @@
     private void setupKey() throws Exception {
         final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
         assertTrue(mAndroidKeyStore
-                .generate(privateKeyAlias, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024,
+                .generate(privateKeyAlias, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024,
                         KeyStore.FLAG_ENCRYPTED, null));
 
         X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1, TEST_SERIAL_1,
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index 1a5552a..916b1ba 100644
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -32,7 +32,7 @@
 import android.test.AssertionFailedError;
 import android.test.MoreAsserts;
 import android.test.suitebuilder.annotation.MediumTest;
-import com.android.org.conscrypt.NativeCrypto;
+import com.android.org.conscrypt.NativeConstants;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.Date;
@@ -365,7 +365,7 @@
 
     public void testGenerate_NotInitialized_Fail() throws Exception {
         assertFalse("Should fail when keystore is not initialized",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
     }
 
@@ -373,7 +373,7 @@
         mKeyStore.password(TEST_PASSWD);
         mKeyStore.lock();
         assertFalse("Should fail when keystore is locked",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
     }
 
@@ -381,7 +381,7 @@
         assertTrue(mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key when unlocked",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
@@ -391,7 +391,7 @@
         assertTrue(mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key when unlocked",
-                mKeyStore.generate(TEST_KEYNAME, Process.WIFI_UID, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, Process.WIFI_UID, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
         assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
@@ -401,7 +401,7 @@
         assertTrue(mKeyStore.password(TEST_PASSWD));
 
         assertFalse(mKeyStore.generate(TEST_KEYNAME, Process.BLUETOOTH_UID,
-                    NativeCrypto.EVP_PKEY_RSA, RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
+                    NativeConstants.EVP_PKEY_RSA, RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
@@ -447,7 +447,7 @@
     public void testSign_Success() throws Exception {
         mKeyStore.password(TEST_PASSWD);
 
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                     RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
         final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
@@ -458,7 +458,7 @@
     public void testVerify_Success() throws Exception {
         mKeyStore.password(TEST_PASSWD);
 
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                     RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
         final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
@@ -486,7 +486,7 @@
                 mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue("Should be able to grant key to other user",
@@ -520,7 +520,7 @@
                 mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue("Should be able to grant key to other user",
@@ -554,7 +554,7 @@
                 mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
 
         assertFalse("Should not be able to revoke not existent grant",
@@ -566,7 +566,7 @@
                 mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue("Should be able to grant key to other user",
@@ -584,7 +584,7 @@
                 mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue("Should be able to grant key to other user",
@@ -605,7 +605,7 @@
 
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
 
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                     RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
@@ -644,7 +644,7 @@
 
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
 
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                     RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index ff6fed2..a7e092f 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -55,16 +55,16 @@
     public static final int ENCODING_DTS_HD = 8;
 
     /** Invalid audio channel configuration */
-    /** @deprecated use CHANNEL_INVALID instead  */
+    /** @deprecated Use {@link #CHANNEL_INVALID} instead.  */
     @Deprecated    public static final int CHANNEL_CONFIGURATION_INVALID   = 0;
     /** Default audio channel configuration */
-    /** @deprecated use CHANNEL_OUT_DEFAULT or CHANNEL_IN_DEFAULT instead  */
+    /** @deprecated Use {@link #CHANNEL_OUT_DEFAULT} or {@link #CHANNEL_IN_DEFAULT} instead.  */
     @Deprecated    public static final int CHANNEL_CONFIGURATION_DEFAULT   = 1;
     /** Mono audio configuration */
-    /** @deprecated use CHANNEL_OUT_MONO or CHANNEL_IN_MONO instead  */
+    /** @deprecated Use {@link #CHANNEL_OUT_MONO} or {@link #CHANNEL_IN_MONO} instead.  */
     @Deprecated    public static final int CHANNEL_CONFIGURATION_MONO      = 2;
     /** Stereo (2 channel) audio configuration */
-    /** @deprecated use CHANNEL_OUT_STEREO or CHANNEL_IN_STEREO instead  */
+    /** @deprecated Use {@link #CHANNEL_OUT_STEREO} or {@link #CHANNEL_IN_STEREO} instead.  */
     @Deprecated    public static final int CHANNEL_CONFIGURATION_STEREO    = 3;
 
     /** Invalid audio channel mask */
@@ -117,12 +117,11 @@
     public static final int CHANNEL_OUT_5POINT1_SIDE = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
             CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY |
             CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT);
-    // TODO does this need an @deprecated ?
-    // different from AUDIO_CHANNEL_OUT_7POINT1
-    public static final int CHANNEL_OUT_7POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+    // different from AUDIO_CHANNEL_OUT_7POINT1 used internally, and not accepted by AudioRecord.
+    /** @deprecated Not the typical 7.1 surround configuration. Use {@link #CHANNEL_OUT_7POINT1_SURROUND} instead. */
+    @Deprecated    public static final int CHANNEL_OUT_7POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
             CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
             CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER);
-    /** @hide */
     // matches AUDIO_CHANNEL_OUT_7POINT1
     public static final int CHANNEL_OUT_7POINT1_SURROUND = (
             CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_FRONT_RIGHT |
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index cb70e8b..d851ad7 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3147,6 +3147,20 @@
             "android.media.property.OUTPUT_FRAMES_PER_BUFFER";
 
     /**
+     * Used as a key for {@link #getProperty} to determine if the default microphone audio source
+     * supports near-ultrasound frequencies (range of 18 - 21 kHz).
+     */
+    public static final String PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND =
+            "android.media.property.SUPPORT_MIC_NEAR_ULTRASOUND";
+
+    /**
+     * Used as a key for {@link #getProperty} to determine if the default speaker audio path
+     * supports near-ultrasound frequencies (range of 18 - 21 kHz).
+     */
+    public static final String PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND =
+            "android.media.property.SUPPORT_SPEAKER_NEAR_ULTRASOUND";
+
+    /**
      * Returns the value of the property with the specified key.
      * @param key One of the strings corresponding to a property key: either
      *            {@link #PROPERTY_OUTPUT_SAMPLE_RATE} or
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 3577357..9bd5c55 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -491,7 +491,7 @@
         session[0] = sessionId;
         // native initialization
         int initResult = native_setup(new WeakReference<AudioTrack>(this), mAttributes,
-                mSampleRate, mChannels, mAudioFormat,
+                mSampleRate, mChannels, mChannelIndexMask, mAudioFormat,
                 mNativeBufferSizeInBytes, mDataLoadMode, session);
         if (initResult != SUCCESS) {
             loge("Error code "+initResult+" when initializing AudioTrack.");
@@ -701,48 +701,6 @@
             AudioFormat.CHANNEL_OUT_SIDE_LEFT |
             AudioFormat.CHANNEL_OUT_SIDE_RIGHT;
 
-    // Java channel mask definitions below match those
-    // in /system/core/include/system/audio.h in the JNI code of AudioTrack.
-
-    // internal maximum size for bits parameter, not part of public API
-    private static final int AUDIO_CHANNEL_BITS_LOG2 = 30;
-
-    // log(2) of maximum number of representations, not part of public API
-    private static final int AUDIO_CHANNEL_REPRESENTATION_LOG2 = 2;
-
-    // used to create a channel index mask or channel position mask
-    // with getChannelMaskFromRepresentationAndBits();
-    private static final int CHANNEL_OUT_REPRESENTATION_POSITION = 0;
-    private static final int CHANNEL_OUT_REPRESENTATION_INDEX = 2;
-
-    /**
-     * Return the channel mask from its representation and bits.
-     *
-     * This creates a channel mask for mChannels which combines a
-     * representation field and a bits field.  This is for internal
-     * communication to native code, not part of the public API.
-     *
-     * @param representation the type of channel mask,
-     *   either CHANNEL_OUT_REPRESENTATION_POSITION
-     *   or CHANNEL_OUT_REPRESENTATION_INDEX
-     * @param bits is the channel bits specifying occupancy
-     * @return the channel mask
-     * @throws java.lang.IllegalArgumentException if representation is not recognized or
-     *   the bits field is not acceptable for that representation
-     */
-    private static int getChannelMaskFromRepresentationAndBits(int representation, int bits) {
-        switch (representation) {
-        case CHANNEL_OUT_REPRESENTATION_POSITION:
-        case CHANNEL_OUT_REPRESENTATION_INDEX:
-            if ((bits & ~((1 << AUDIO_CHANNEL_BITS_LOG2) - 1)) != 0) {
-                throw new IllegalArgumentException("invalid bits " + bits);
-            }
-            return representation << AUDIO_CHANNEL_BITS_LOG2 | bits;
-        default:
-            throw new IllegalArgumentException("invalid representation " + representation);
-        }
-    }
-
     // Convenience method for the constructor's parameter checks.
     // This is where constructor IllegalArgumentException-s are thrown
     // postconditions:
@@ -804,11 +762,6 @@
             } else if (mChannelCount != channelIndexCount) {
                 throw new IllegalArgumentException("Channel count must match");
             }
-
-            // AudioTrack prefers to use the channel index configuration
-            // over the channel position configuration if both are specified.
-            mChannels = getChannelMaskFromRepresentationAndBits(
-                    CHANNEL_OUT_REPRESENTATION_INDEX, mChannelIndexMask);
         }
 
         //--------------
@@ -2362,7 +2315,7 @@
     //     AudioAttributes.USAGE_MEDIA will map to AudioManager.STREAM_MUSIC
     private native final int native_setup(Object /*WeakReference<AudioTrack>*/ audiotrack_this,
             Object /*AudioAttributes*/ attributes,
-            int sampleRate, int channelMask, int audioFormat,
+            int sampleRate, int channelMask, int channelIndexMask, int audioFormat,
             int buffSizeInBytes, int mode, int[] sessionId);
 
     private native final void native_finalize();
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index 75901fd..195c987 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -50,10 +50,25 @@
     /**
      * @hide
      */
+    protected boolean mIsImageValid = false;
+
+    /**
+     * @hide
+     */
     protected Image() {
     }
 
     /**
+     * Throw IllegalStateException if the image is invalid (already closed).
+     *
+     * @hide
+     */
+    protected void throwISEIfImageIsInvalid() {
+        if (!mIsImageValid) {
+            throw new IllegalStateException("Image is already closed");
+        }
+    }
+    /**
      * Get the format for this image. This format determines the number of
      * ByteBuffers needed to represent the image, and the general layout of the
      * pixel data in each in ByteBuffer.
@@ -160,7 +175,7 @@
      * Set the timestamp associated with this frame.
      * <p>
      * The timestamp is measured in nanoseconds, and is normally monotonically
-     * increasing. However, However, the behavior of the timestamp depends on
+     * 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},
      * {@link MediaPlayer} and {@link MediaCodec} for more details.
@@ -176,6 +191,7 @@
      * @param timestamp The timestamp to be set for this image.
      */
     public void setTimestamp(long timestamp) {
+        throwISEIfImageIsInvalid();
         return;
     }
 
@@ -187,6 +203,7 @@
      * </p>
      */
     public boolean isOpaque() {
+        throwISEIfImageIsInvalid();
         return false;
     }
 
@@ -199,6 +216,8 @@
      * using coordinates in the largest-resolution plane.
      */
     public Rect getCropRect() {
+        throwISEIfImageIsInvalid();
+
         if (mCropRect == null) {
             return new Rect(0, 0, getWidth(), getHeight());
         } else {
@@ -213,6 +232,8 @@
      * using coordinates in the largest-resolution plane.
      */
     public void setCropRect(Rect cropRect) {
+        throwISEIfImageIsInvalid();
+
         if (cropRect != null) {
             cropRect = new Rect(cropRect);  // make a copy
             cropRect.intersect(0, 0, getWidth(), getHeight());
@@ -260,6 +281,8 @@
      *         a new owner.
      */
     boolean isAttachable() {
+        throwISEIfImageIsInvalid();
+
         return false;
     }
 
@@ -279,6 +302,8 @@
      * @return The owner of the Image.
      */
     Object getOwner() {
+        throwISEIfImageIsInvalid();
+
         return null;
     }
 
@@ -294,6 +319,8 @@
      * @return native context associated with this Image.
      */
     long getNativeContext() {
+        throwISEIfImageIsInvalid();
+
         return 0;
     }
 
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index e54525d..6d30208 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -368,7 +368,7 @@
         switch (status) {
             case ACQUIRE_SUCCESS:
                 si.createSurfacePlanes();
-                si.setImageValid(true);
+                si.mIsImageValid = true;
             case ACQUIRE_NO_BUFS:
             case ACQUIRE_MAX_IMAGES:
                 break;
@@ -444,7 +444,7 @@
 
         si.clearSurfacePlanes();
         nativeReleaseImage(i);
-        si.setImageValid(false);
+        si.mIsImageValid = false;
     }
 
     /**
@@ -686,7 +686,6 @@
 
     private class SurfaceImage extends android.media.Image {
         public SurfaceImage(int format) {
-            mIsImageValid = false;
             mFormat = format;
         }
 
@@ -784,16 +783,6 @@
             mIsDetached.getAndSet(detached);
         }
 
-        private void setImageValid(boolean isValid) {
-            mIsImageValid = isValid;
-        }
-
-        private void throwISEIfImageIsInvalid() {
-            if (!mIsImageValid) {
-                throw new IllegalStateException("Image is already closed");
-            }
-        }
-
         private void clearSurfacePlanes() {
             if (mIsImageValid) {
                 for (int i = 0; i < mPlanes.length; i++) {
@@ -877,7 +866,6 @@
         private long mTimestamp;
 
         private SurfacePlane[] mPlanes;
-        private boolean mIsImageValid;
         private int mHeight = -1;
         private int mWidth = -1;
         private int mFormat = ImageFormat.UNKNOWN;
diff --git a/media/java/android/media/ImageWriter.java b/media/java/android/media/ImageWriter.java
index c18b463..f805339 100644
--- a/media/java/android/media/ImageWriter.java
+++ b/media/java/android/media/ImageWriter.java
@@ -29,7 +29,6 @@
 import java.nio.NioUtils;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * <p>
@@ -204,7 +203,7 @@
         WriterSurfaceImage newImage = new WriterSurfaceImage(this);
         nativeDequeueInputImage(mNativeContext, newImage);
         mDequeuedImages.add(newImage);
-        newImage.setImageValid(true);
+        newImage.mIsImageValid = true;
         return newImage;
     }
 
@@ -260,7 +259,7 @@
             throw new IllegalArgumentException("image shouldn't be null");
         }
         boolean ownedByMe = isImageOwnedByMe(image);
-        if (ownedByMe && !(((WriterSurfaceImage) image).isImageValid())) {
+        if (ownedByMe && !(((WriterSurfaceImage) image).mIsImageValid)) {
             throw new IllegalStateException("Image from ImageWriter is invalid");
         }
 
@@ -312,7 +311,7 @@
             // Do not call close here, as close is essentially cancel image.
             WriterSurfaceImage wi = (WriterSurfaceImage) image;
             wi.clearSurfacePlanes();
-            wi.setImageValid(false);
+            wi.mIsImageValid = false;
         }
     }
 
@@ -555,7 +554,7 @@
 
         WriterSurfaceImage wi = (WriterSurfaceImage) image;
 
-        if (!wi.isImageValid()) {
+        if (!wi.mIsImageValid) {
             throw new IllegalStateException("Image is invalid");
         }
 
@@ -568,7 +567,7 @@
         cancelImage(mNativeContext, image);
         mDequeuedImages.remove(image);
         wi.clearSurfacePlanes();
-        wi.setImageValid(false);
+        wi.mIsImageValid = false;
     }
 
     private boolean isImageOwnedByMe(Image image) {
@@ -585,7 +584,6 @@
 
     private static class WriterSurfaceImage extends android.media.Image {
         private ImageWriter mOwner;
-        private AtomicBoolean mIsImageValid = new AtomicBoolean(false);
         // This field is used by native code, do not access or modify.
         private long mNativeBuffer;
         private int mNativeFenceFd = -1;
@@ -604,9 +602,8 @@
 
         @Override
         public int getFormat() {
-            if (!mIsImageValid.get()) {
-                throw new IllegalStateException("Image is already released");
-            }
+            throwISEIfImageIsInvalid();
+
             if (mFormat == -1) {
                 mFormat = nativeGetFormat();
             }
@@ -615,9 +612,7 @@
 
         @Override
         public int getWidth() {
-            if (!mIsImageValid.get()) {
-                throw new IllegalStateException("Image is already released");
-            }
+            throwISEIfImageIsInvalid();
 
             if (mWidth == -1) {
                 mWidth = nativeGetWidth();
@@ -628,9 +623,7 @@
 
         @Override
         public int getHeight() {
-            if (!mIsImageValid.get()) {
-                throw new IllegalStateException("Image is already released");
-            }
+            throwISEIfImageIsInvalid();
 
             if (mHeight == -1) {
                 mHeight = nativeGetHeight();
@@ -641,36 +634,28 @@
 
         @Override
         public long getTimestamp() {
-            if (!mIsImageValid.get()) {
-                throw new IllegalStateException("Image is already released");
-            }
+            throwISEIfImageIsInvalid();
 
             return mTimestamp;
         }
 
         @Override
         public void setTimestamp(long timestamp) {
-            if (!mIsImageValid.get()) {
-                throw new IllegalStateException("Image is already released");
-            }
+            throwISEIfImageIsInvalid();
 
             mTimestamp = timestamp;
         }
 
         @Override
         public boolean isOpaque() {
-            if (!mIsImageValid.get()) {
-                throw new IllegalStateException("Image is already released");
-            }
+            throwISEIfImageIsInvalid();
 
             return getFormat() == ImageFormat.PRIVATE;
         }
 
         @Override
         public Plane[] getPlanes() {
-            if (!mIsImageValid.get()) {
-                throw new IllegalStateException("Image is already released");
-            }
+            throwISEIfImageIsInvalid();
 
             if (mPlanes == null) {
                 int numPlanes = ImageUtils.getNumPlanesForFormat(getFormat());
@@ -682,9 +667,7 @@
 
         @Override
         boolean isAttachable() {
-            if (!mIsImageValid.get()) {
-                throw new IllegalStateException("Image is already released");
-            }
+            throwISEIfImageIsInvalid();
             // Don't allow Image to be detached from ImageWriter for now, as no
             // detach API is exposed.
             return false;
@@ -692,17 +675,21 @@
 
         @Override
         ImageWriter getOwner() {
+            throwISEIfImageIsInvalid();
+
             return mOwner;
         }
 
         @Override
         long getNativeContext() {
+            throwISEIfImageIsInvalid();
+
             return mNativeBuffer;
         }
 
         @Override
         public void close() {
-            if (mIsImageValid.get()) {
+            if (mIsImageValid) {
                 getOwner().abortImage(this);
             }
         }
@@ -716,16 +703,8 @@
             }
         }
 
-        private boolean isImageValid() {
-            return mIsImageValid.get();
-        }
-
-        private void setImageValid(boolean isValid) {
-            mIsImageValid.getAndSet(isValid);
-        }
-
         private void clearSurfacePlanes() {
-            if (mIsImageValid.get()) {
+            if (mIsImageValid) {
                 for (int i = 0; i < mPlanes.length; i++) {
                     if (mPlanes[i] != null) {
                         mPlanes[i].clearBuffer();
@@ -756,26 +735,19 @@
 
             @Override
             public int getRowStride() {
-                if (WriterSurfaceImage.this.isImageValid() == false) {
-                    throw new IllegalStateException("Image is already released");
-                }
+                throwISEIfImageIsInvalid();
                 return mRowStride;
             }
 
             @Override
             public int getPixelStride() {
-                if (WriterSurfaceImage.this.isImageValid() == false) {
-                    throw new IllegalStateException("Image is already released");
-                }
+                throwISEIfImageIsInvalid();
                 return mPixelStride;
             }
 
             @Override
             public ByteBuffer getBuffer() {
-                if (WriterSurfaceImage.this.isImageValid() == false) {
-                    throw new IllegalStateException("Image is already released");
-                }
-
+                throwISEIfImageIsInvalid();
                 return mBuffer;
             }
 
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 1f00c7b..d22cfda 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -2059,7 +2059,6 @@
     /** @hide */
     public static class MediaImage extends Image {
         private final boolean mIsReadOnly;
-        private boolean mIsValid;
         private final int mWidth;
         private final int mHeight;
         private final int mFormat;
@@ -2072,36 +2071,42 @@
 
         private final static int TYPE_YUV = 1;
 
+        @Override
         public int getFormat() {
-            checkValid();
+            throwISEIfImageIsInvalid();
             return mFormat;
         }
 
+        @Override
         public int getHeight() {
-            checkValid();
+            throwISEIfImageIsInvalid();
             return mHeight;
         }
 
+        @Override
         public int getWidth() {
-            checkValid();
+            throwISEIfImageIsInvalid();
             return mWidth;
         }
 
+        @Override
         public long getTimestamp() {
-            checkValid();
+            throwISEIfImageIsInvalid();
             return mTimestamp;
         }
 
+        @Override
         @NonNull
         public Plane[] getPlanes() {
-            checkValid();
+            throwISEIfImageIsInvalid();
             return Arrays.copyOf(mPlanes, mPlanes.length);
         }
 
+        @Override
         public void close() {
-            if (mIsValid) {
+            if (mIsImageValid) {
                 java.nio.NioUtils.freeDirectBuffer(mBuffer);
-                mIsValid = false;
+                mIsImageValid = false;
             }
         }
 
@@ -2111,6 +2116,7 @@
          * The crop rectangle specifies the region of valid pixels in the image,
          * using coordinates in the largest-resolution plane.
          */
+        @Override
         public void setCropRect(@Nullable Rect cropRect) {
             if (mIsReadOnly) {
                 throw new ReadOnlyBufferException();
@@ -2118,11 +2124,6 @@
             super.setCropRect(cropRect);
         }
 
-        private void checkValid() {
-            if (!mIsValid) {
-                throw new IllegalStateException("Image is already released");
-            }
-        }
 
         private int readInt(@NonNull ByteBuffer buffer, boolean asLong) {
             if (asLong) {
@@ -2137,7 +2138,7 @@
                 long timestamp, int xOffset, int yOffset, @Nullable Rect cropRect) {
             mFormat = ImageFormat.YUV_420_888;
             mTimestamp = timestamp;
-            mIsValid = true;
+            mIsImageValid = true;
             mIsReadOnly = buffer.isReadOnly();
             mBuffer = buffer.duplicate();
 
@@ -2208,20 +2209,20 @@
 
             @Override
             public int getRowStride() {
-                checkValid();
+                throwISEIfImageIsInvalid();
                 return mRowInc;
             }
 
             @Override
             public int getPixelStride() {
-                checkValid();
+                throwISEIfImageIsInvalid();
                 return mColInc;
             }
 
             @Override
             @NonNull
             public ByteBuffer getBuffer() {
-                checkValid();
+                throwISEIfImageIsInvalid();
                 return mData;
             }
 
diff --git a/media/java/android/media/MediaSync.java b/media/java/android/media/MediaSync.java
index 3b4f8e5..dc6760d 100644
--- a/media/java/android/media/MediaSync.java
+++ b/media/java/android/media/MediaSync.java
@@ -49,7 +49,7 @@
  * sync.setAudioTrack(audioTrack);
  * sync.setCallback(new MediaSync.Callback() {
  *     {@literal @Override}
- *     public void onReturnAudioBuffer(MediaSync sync, ByteBuffer audioBuffer, int bufferIndex) {
+ *     public void onAudioBufferConsumed(MediaSync sync, ByteBuffer audioBuffer, int bufferIndex) {
  *         ...
  *     }
  * }, null);
@@ -88,7 +88,7 @@
  * }
  *
  * // This is the callback from MediaSync.
- * onReturnAudioBuffer(MediaSync sync, ByteBuffer buffer, int bufferIndex) {
+ * onAudioBufferConsumed(MediaSync sync, ByteBuffer buffer, int bufferIndex) {
  *     // ...
  *     audioDecoder.releaseBuffer(bufferIndex, false);
  *     // ...
@@ -104,7 +104,7 @@
  * <p>
  * For audio, the client needs to set up audio track correctly, e.g., using {@link
  * AudioTrack#MODE_STREAM}. The audio buffers are sent to MediaSync directly via {@link
- * #queueAudio}, and are returned to the client via {@link Callback#onReturnAudioBuffer}
+ * #queueAudio}, and are returned to the client via {@link Callback#onAudioBufferConsumed}
  * asynchronously. The client should not modify an audio buffer till it's returned.
  * <p>
  * The client can optionally pre-fill audio/video buffers by setting playback rate to 0.0,
@@ -125,10 +125,41 @@
          * @param audioBuffer The returned audio buffer.
          * @param bufferIndex The index associated with the audio buffer
          */
-        public abstract void onReturnAudioBuffer(
+        public abstract void onAudioBufferConsumed(
                 @NonNull MediaSync sync, @NonNull ByteBuffer audioBuffer, int bufferIndex);
     }
 
+    /** Audio track failed.
+     * @see android.media.MediaSync.OnErrorListener
+     */
+    public static final int MEDIASYNC_ERROR_AUDIOTRACK_FAIL = 1;
+
+    /** The surface failed to handle video buffers.
+     * @see android.media.MediaSync.OnErrorListener
+     */
+    public static final int MEDIASYNC_ERROR_SURFACE_FAIL = 2;
+
+    /**
+     * Interface definition of a callback to be invoked when there
+     * has been an error during an asynchronous operation (other errors
+     * will throw exceptions at method call time).
+     */
+    public interface OnErrorListener {
+        /**
+         * Called to indicate an error.
+         *
+         * @param sync The MediaSync the error pertains to
+         * @param what The type of error that has occurred:
+         * <ul>
+         * <li>{@link #MEDIASYNC_ERROR_AUDIOTRACK_FAIL}
+         * <li>{@link #MEDIASYNC_ERROR_SURFACE_FAIL}
+         * </ul>
+         * @param extra an extra code, specific to the error. Typically
+         * implementation dependent.
+         */
+        void onError(@NonNull MediaSync sync, int what, int extra);
+    }
+
     private static final String TAG = "MediaSync";
 
     private static final int EVENT_CALLBACK = 1;
@@ -155,6 +186,10 @@
     private Handler mCallbackHandler = null;
     private MediaSync.Callback mCallback = null;
 
+    private final Object mOnErrorListenerLock = new Object();
+    private Handler mOnErrorListenerHandler = null;
+    private MediaSync.OnErrorListener mOnErrorListener = null;
+
     private Thread mAudioThread = null;
     // Created on mAudioThread when mAudioThread is started. When used on user thread, they should
     // be guarded by checking mAudioThread.
@@ -235,6 +270,39 @@
     }
 
     /**
+     * Sets an asynchronous callback for error events.
+     * <p>
+     * This method can be called multiple times to update a previously set listener. If the
+     * handler is changed, undelivered notifications scheduled for the old handler may be dropped.
+     * <p>
+     * <b>Do not call this inside callback.</b>
+     *
+     * @param listener The callback that will run. Use {@code null} to stop receiving callbacks.
+     * @param handler The Handler that will run the callback. Use {@code null} to use MediaSync's
+     *     internal handler if it exists.
+     */
+    public void setOnErrorListener(@Nullable /* MediaSync. */ OnErrorListener listener,
+            @Nullable Handler handler) {
+        synchronized(mOnErrorListenerLock) {
+            if (handler != null) {
+                mOnErrorListenerHandler = handler;
+            } else {
+                Looper looper;
+                if ((looper = Looper.myLooper()) == null) {
+                    looper = Looper.getMainLooper();
+                }
+                if (looper == null) {
+                    mOnErrorListenerHandler = null;
+                } else {
+                    mOnErrorListenerHandler = new Handler(looper);
+                }
+            }
+
+            mOnErrorListener = listener;
+        }
+    }
+
+    /**
      * Sets the output surface for MediaSync.
      * <p>
      * Currently, this is only supported in the Initialized state.
@@ -614,7 +682,7 @@
                                 return;
                             }
                             if (mCallback != null) {
-                                mCallback.onReturnAudioBuffer(sync, audioBuffer.mByteBuffer,
+                                mCallback.onAudioBufferConsumed(sync, audioBuffer.mByteBuffer,
                                         audioBuffer.mBufferIndex);
                             }
                         }
diff --git a/media/java/android/media/tv/TvContentRating.java b/media/java/android/media/tv/TvContentRating.java
index 754facd..966e41a 100644
--- a/media/java/android/media/tv/TvContentRating.java
+++ b/media/java/android/media/tv/TvContentRating.java
@@ -16,9 +16,12 @@
 
 package android.media.tv;
 
+import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.text.TextUtils;
 
+import com.android.internal.util.Preconditions;
+
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
@@ -693,6 +696,12 @@
     private final int mHashCode;
 
     /**
+     * Rating constant denoting unrated content.
+     */
+    public static final TvContentRating UNRATED = new TvContentRating("com.android.tv", "",
+            "UNRATED", null);
+
+    /**
      * Creates a {@code TvContentRating} object with predefined content rating strings.
      *
      * @param domain The domain string. For example, "com.android.tv".
@@ -833,10 +842,8 @@
      * @hide
      */
     @SystemApi
-    public final boolean contains(TvContentRating rating) {
-        if (rating == null) {
-            throw new IllegalArgumentException("rating cannot be null");
-        }
+    public final boolean contains(@NonNull TvContentRating rating) {
+        Preconditions.checkNotNull(rating);
         if (!rating.getMainRating().equals(mRating)) {
             return false;
         }
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 0f265de..601fa45 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -40,6 +40,8 @@
 import android.view.Surface;
 import android.view.View;
 
+import com.android.internal.util.Preconditions;
+
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -934,9 +936,7 @@
      */
     @Nullable
     public TvInputInfo getTvInputInfo(@NonNull String inputId) {
-        if (inputId == null) {
-            throw new IllegalArgumentException("inputId cannot be null");
-        }
+        Preconditions.checkNotNull(inputId);
         try {
             return mService.getTvInputInfo(inputId, mUserId);
         } catch (RemoteException e) {
@@ -958,9 +958,7 @@
      * @throws IllegalArgumentException if the argument is {@code null}.
      */
     public int getInputState(@NonNull String inputId) {
-        if (inputId == null) {
-            throw new IllegalArgumentException("inputId cannot be null");
-        }
+        Preconditions.checkNotNull(inputId);
         synchronized (mLock) {
             Integer state = mStateMap.get(inputId);
             if (state == null) {
@@ -976,15 +974,10 @@
      *
      * @param callback A callback used to monitor status of the TV inputs.
      * @param handler A {@link Handler} that the status change will be delivered to.
-     * @throws IllegalArgumentException if any of the arguments is {@code null}.
      */
     public void registerCallback(@NonNull TvInputCallback callback, @NonNull Handler handler) {
-        if (callback == null) {
-            throw new IllegalArgumentException("callback cannot be null");
-        }
-        if (handler == null) {
-            throw new IllegalArgumentException("handler cannot be null");
-        }
+        Preconditions.checkNotNull(callback);
+        Preconditions.checkNotNull(handler);
         synchronized (mLock) {
             mCallbackRecords.add(new TvInputCallbackRecord(callback, handler));
         }
@@ -994,12 +987,9 @@
      * Unregisters the existing {@link TvInputCallback}.
      *
      * @param callback The existing callback to remove.
-     * @throws IllegalArgumentException if any of the arguments is {@code null}.
      */
     public void unregisterCallback(@NonNull final TvInputCallback callback) {
-        if (callback == null) {
-            throw new IllegalArgumentException("callback cannot be null");
-        }
+        Preconditions.checkNotNull(callback);
         synchronized (mLock) {
             for (Iterator<TvInputCallbackRecord> it = mCallbackRecords.iterator();
                     it.hasNext(); ) {
@@ -1049,9 +1039,7 @@
      * @return {@code true} if the given TV content rating is blocked, {@code false} otherwise.
      */
     public boolean isRatingBlocked(@NonNull TvContentRating rating) {
-        if (rating == null) {
-            throw new IllegalArgumentException("rating cannot be null");
-        }
+        Preconditions.checkNotNull(rating);
         try {
             return mService.isRatingBlocked(rating.flattenToString(), mUserId);
         } catch (RemoteException e) {
@@ -1087,10 +1075,8 @@
      * @hide
      */
     @SystemApi
-    public void addBlockedRating(TvContentRating rating) {
-        if (rating == null) {
-            throw new IllegalArgumentException("rating cannot be null");
-        }
+    public void addBlockedRating(@NonNull TvContentRating rating) {
+        Preconditions.checkNotNull(rating);
         try {
             mService.addBlockedRating(rating.flattenToString(), mUserId);
         } catch (RemoteException e) {
@@ -1107,10 +1093,8 @@
      * @hide
      */
     @SystemApi
-    public void removeBlockedRating(TvContentRating rating) {
-        if (rating == null) {
-            throw new IllegalArgumentException("rating cannot be null");
-        }
+    public void removeBlockedRating(@NonNull TvContentRating rating) {
+        Preconditions.checkNotNull(rating);
         try {
             mService.removeBlockedRating(rating.flattenToString(), mUserId);
         } catch (RemoteException e) {
@@ -1140,21 +1124,14 @@
      * @param inputId The id of the TV input.
      * @param callback A callback used to receive the created session.
      * @param handler A {@link Handler} that the session creation will be delivered to.
-     * @throws IllegalArgumentException if any of the arguments is {@code null}.
      * @hide
      */
     @SystemApi
-    public void createSession(String inputId, final SessionCallback callback,
-            Handler handler) {
-        if (inputId == null) {
-            throw new IllegalArgumentException("id cannot be null");
-        }
-        if (callback == null) {
-            throw new IllegalArgumentException("callback cannot be null");
-        }
-        if (handler == null) {
-            throw new IllegalArgumentException("handler cannot be null");
-        }
+    public void createSession(@NonNull String inputId, @NonNull final SessionCallback callback,
+            @NonNull Handler handler) {
+        Preconditions.checkNotNull(inputId);
+        Preconditions.checkNotNull(callback);
+        Preconditions.checkNotNull(handler);
         SessionCallbackRecord record = new SessionCallbackRecord(callback, handler);
         synchronized (mSessionCallbackRecordMap) {
             int seq = mNextSeq++;
@@ -1436,7 +1413,6 @@
          * Tunes to a given channel.
          *
          * @param channelUri The URI of a channel.
-         * @throws IllegalArgumentException if the argument is {@code null}.
          */
         public void tune(Uri channelUri) {
             tune(channelUri, null);
@@ -1447,14 +1423,11 @@
          *
          * @param channelUri The URI of a channel.
          * @param params A set of extra parameters which might be handled with this tune event.
-         * @throws IllegalArgumentException if {@code channelUri} is {@code null}.
          * @hide
          */
         @SystemApi
-        public void tune(Uri channelUri, Bundle params) {
-            if (channelUri == null) {
-                throw new IllegalArgumentException("channelUri cannot be null");
-            }
+        public void tune(@NonNull Uri channelUri, Bundle params) {
+            Preconditions.checkNotNull(channelUri);
             if (mToken == null) {
                 Log.w(TAG, "The session has been already released");
                 return;
@@ -1790,16 +1763,11 @@
          *
          * @param view A view playing TV.
          * @param frame A position of the overlay view.
-         * @throws IllegalArgumentException if any of the arguments is {@code null}.
          * @throws IllegalStateException if {@code view} is not attached to a window.
          */
-        void createOverlayView(View view, Rect frame) {
-            if (view == null) {
-                throw new IllegalArgumentException("view cannot be null");
-            }
-            if (frame == null) {
-                throw new IllegalArgumentException("frame cannot be null");
-            }
+        void createOverlayView(@NonNull View view, @NonNull Rect frame) {
+            Preconditions.checkNotNull(view);
+            Preconditions.checkNotNull(frame);
             if (view.getWindowToken() == null) {
                 throw new IllegalStateException("view must be attached to a window");
             }
@@ -1818,12 +1786,9 @@
          * Relayouts the current overlay view.
          *
          * @param frame A new position of the overlay view.
-         * @throws IllegalArgumentException if the arguments is {@code null}.
          */
-        void relayoutOverlayView(Rect frame) {
-            if (frame == null) {
-                throw new IllegalArgumentException("frame cannot be null");
-            }
+        void relayoutOverlayView(@NonNull Rect frame) {
+            Preconditions.checkNotNull(frame);
             if (mToken == null) {
                 Log.w(TAG, "The session has been already released");
                 return;
@@ -1853,14 +1818,12 @@
         /**
          * Requests to unblock content blocked by parental controls.
          */
-        void requestUnblockContent(TvContentRating unblockedRating) {
+        void requestUnblockContent(@NonNull TvContentRating unblockedRating) {
+            Preconditions.checkNotNull(unblockedRating);
             if (mToken == null) {
                 Log.w(TAG, "The session has been already released");
                 return;
             }
-            if (unblockedRating == null) {
-                throw new IllegalArgumentException("unblockedRating cannot be null");
-            }
             try {
                 mService.requestUnblockContent(mToken, unblockedRating.flattenToString(), mUserId);
             } catch (RemoteException e) {
@@ -1871,25 +1834,22 @@
         /**
          * Dispatches an input event to this session.
          *
-         * @param event An {@link InputEvent} to dispatch.
+         * @param event An {@link InputEvent} to dispatch. Cannot be {@code null}.
          * @param token A token used to identify the input event later in the callback.
-         * @param callback A callback used to receive the dispatch result.
-         * @param handler A {@link Handler} that the dispatch result will be delivered to.
+         * @param callback A callback used to receive the dispatch result. Cannot be {@code null}.
+         * @param handler A {@link Handler} that the dispatch result will be delivered to. Cannot be
+         *            {@code null}.
          * @return Returns {@link #DISPATCH_HANDLED} if the event was handled. Returns
          *         {@link #DISPATCH_NOT_HANDLED} if the event was not handled. Returns
          *         {@link #DISPATCH_IN_PROGRESS} if the event is in progress and the callback will
          *         be invoked later.
-         * @throws IllegalArgumentException if any of the necessary arguments is {@code null}.
          * @hide
          */
-        public int dispatchInputEvent(InputEvent event, Object token,
-                FinishedInputEventCallback callback, Handler handler) {
-            if (event == null) {
-                throw new IllegalArgumentException("event cannot be null");
-            }
-            if (callback != null && handler == null) {
-                throw new IllegalArgumentException("handler cannot be null");
-            }
+        public int dispatchInputEvent(@NonNull InputEvent event, Object token,
+                @NonNull FinishedInputEventCallback callback, @NonNull Handler handler) {
+            Preconditions.checkNotNull(event);
+            Preconditions.checkNotNull(callback);
+            Preconditions.checkNotNull(handler);
             synchronized (mHandler) {
                 if (mChannel == null) {
                     return DISPATCH_NOT_HANDLED;
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 4258534..5156ae8 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -51,6 +51,7 @@
 import android.widget.FrameLayout;
 
 import com.android.internal.os.SomeArgs;
+import com.android.internal.util.Preconditions;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -313,10 +314,8 @@
          * @hide
          */
         @SystemApi
-        public void notifySessionEvent(final String eventType, final Bundle eventArgs) {
-            if (eventType == null) {
-                throw new IllegalArgumentException("eventType cannot be null");
-            }
+        public void notifySessionEvent(@NonNull final String eventType, final Bundle eventArgs) {
+            Preconditions.checkNotNull(eventType);
             executeOrPostRunnable(new Runnable() {
                 @Override
                 public void run() {
@@ -546,9 +545,7 @@
          * @see TvInputManager
          */
         public void notifyContentBlocked(@NonNull final TvContentRating rating) {
-            if (rating == null) {
-                throw new IllegalArgumentException("rating cannot be null");
-            }
+            Preconditions.checkNotNull(rating);
             executeOrPostRunnable(new Runnable() {
                 @Override
                 public void run() {
diff --git a/media/java/android/media/tv/TvTrackInfo.java b/media/java/android/media/tv/TvTrackInfo.java
index 6eedeb4..2c956e9 100644
--- a/media/java/android/media/tv/TvTrackInfo.java
+++ b/media/java/android/media/tv/TvTrackInfo.java
@@ -16,10 +16,13 @@
 
 package android.media.tv;
 
+import android.annotation.NonNull;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.internal.util.Preconditions;
+
 /**
  * Encapsulates the format of tracks played in {@link TvInputService}.
  */
@@ -245,15 +248,13 @@
          * @param id The ID of the track that uniquely identifies the current track among all the
          *            other tracks in the same TV program.
          */
-        public Builder(int type, String id) {
+        public Builder(int type, @NonNull String id) {
             if (type != TYPE_AUDIO
                     && type != TYPE_VIDEO
                     && type != TYPE_SUBTITLE) {
                 throw new IllegalArgumentException("Unknown type: " + type);
             }
-            if (id == null) {
-                throw new IllegalArgumentException("id cannot be null");
-            }
+            Preconditions.checkNotNull(id);
             mType = type;
             mId = id;
         }
diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp
index d2c614e..8c76665 100644
--- a/media/jni/android_media_ImageWriter.cpp
+++ b/media/jni/android_media_ImageWriter.cpp
@@ -338,7 +338,7 @@
     status_t res = anw->dequeueBuffer(anw.get(), &anb, &fenceFd);
     if (res != OK) {
         // TODO: handle different error cases here.
-        ALOGE("%s: Set buffer count failed: %s (%d)", __FUNCTION__, strerror(-res), res);
+        ALOGE("%s: Dequeue buffer failed: %s (%d)", __FUNCTION__, strerror(-res), res);
         jniThrowRuntimeException(env, "dequeue buffer failed");
         return;
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
index e0af29d..1cf7248 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
@@ -32,6 +32,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.StorageVolume;
@@ -76,6 +77,9 @@
             Environment.DIRECTORY_DOWNLOADS, Environment.DIRECTORY_ANDROID);
 
     public static class MeasurementDetails {
+        public long totalSize;
+        public long availSize;
+
         /**
          * Total apps disk usage.
          * <p>
@@ -121,7 +125,7 @@
     }
 
     public interface MeasurementReceiver {
-        public void onDetailsChanged(MeasurementDetails details);
+        void onDetailsChanged(MeasurementDetails details);
     }
 
     private WeakReference<MeasurementReceiver> mReceiver;
@@ -370,6 +374,10 @@
             }
         }
 
+        final File file = mVolume.getPath();
+        details.totalSize = file.getTotalSpace();
+        details.availSize = file.getFreeSpace();
+
         // Measure all apps hosted on this volume for all users
         if (mVolume.getType() == VolumeInfo.TYPE_PRIVATE) {
             final List<ApplicationInfo> apps = packageManager.getInstalledApplications(
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 35e9636..5b4b4fd 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -94,6 +94,7 @@
     <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
     <uses-permission android:name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"/>
     <uses-permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS" />
+    <uses-permission android:name="android.permission.CHANGE_APP_IDLE_STATE" />
 
     <application android:label="@string/app_label">
         <provider
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 292c9c2..0d331d1 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -328,7 +328,7 @@
         int fillColor = getFillColor(darkIntensity);
         mIconTint = fillColor;
         mFramePaint.setColor(backgroundColor);
-        mBoltPaint.setColor(backgroundColor);
+        mBoltPaint.setColor(fillColor);
         mChargeColor = fillColor;
         invalidate();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index b828e78..7b555fc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1549,6 +1549,7 @@
             try {
                 callback.onSimSecureStateChanged(mUpdateMonitor.isSimPinSecure());
                 callback.onShowingStateChanged(mShowing);
+                callback.onInputRestrictedStateChanged(mInputRestricted);
             } catch (RemoteException e) {
                 Slog.w(TAG, "Failed to call onShowingStateChanged or onSimSecureStateChanged", e);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index de4874f..e542264 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -700,6 +700,26 @@
         return isCurrentProfile(notificationUserId);
     }
 
+    protected void setNotificationShown(StatusBarNotification n) {
+        mNotificationListener.setNotificationsShown(new String[] { n.getKey() });
+    }
+
+    protected void setNotificationsShown(String[] keys) {
+        mNotificationListener.setNotificationsShown(keys);
+    }
+
+    protected void setNotificationsShownAll() {
+        ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
+        final int N = activeNotifications.size();
+
+        String[] keys = new String[N];
+        for (int i = 0; i < N; i++) {
+            NotificationData.Entry entry = activeNotifications.get(i);
+            keys[i] = entry.key;
+        }
+        setNotificationsShown(keys);
+    }
+
     protected boolean isCurrentProfile(int userId) {
         synchronized (mCurrentProfiles) {
             return userId == UserHandle.USER_ALL || mCurrentProfiles.get(userId) != null;
@@ -1681,6 +1701,7 @@
                 boolean clearNotificationEffects =
                         (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED);
                 mBarService.onPanelRevealed(clearNotificationEffects);
+                setNotificationsShownAll();
             } else {
                 mBarService.onPanelHidden();
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index c854d63..d058892 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1119,6 +1119,8 @@
         boolean isHeadsUped = mUseHeadsUp && shouldInterrupt(notification);
         if (isHeadsUped) {
             mHeadsUpManager.showNotification(shadeEntry);
+            // Mark as seen immediately
+            setNotificationShown(notification);
         }
 
         if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
diff --git a/preloaded-classes b/preloaded-classes
index 95d0b42..c94623a 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -402,6 +402,7 @@
 android.app.SharedPreferencesImpl$EditorImpl$1
 android.app.SharedPreferencesImpl$EditorImpl$2
 android.app.SharedPreferencesImpl$MemoryCommitResult
+android.app.SystemServiceRegistry
 android.app.admin.DevicePolicyManager
 android.app.admin.IDevicePolicyManager$Stub
 android.app.admin.IDevicePolicyManager$Stub$Proxy
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 89a7173..81088c4 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -1758,6 +1758,9 @@
 
     @Override
     public void finishMediaUpdate() {
+        if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
+            throw new SecurityException("no permission to call finishMediaUpdate()");
+        }
         if (mUnmountSignal != null) {
             mUnmountSignal.countDown();
         } else {
@@ -1791,7 +1794,7 @@
         warnOnNotMounted();
 
         final ObbState state;
-        synchronized (mObbPathToStateMap) {
+        synchronized (mObbMounts) {
             state = mObbPathToStateMap.get(rawPath);
         }
         if (state == null) {
@@ -1843,7 +1846,7 @@
         Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
 
         final ObbState existingState;
-        synchronized (mObbPathToStateMap) {
+        synchronized (mObbMounts) {
             existingState = mObbPathToStateMap.get(rawPath);
         }
 
@@ -2093,6 +2096,8 @@
 
     @Override
     public String getPassword() throws RemoteException {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE,
+                "only keyguard can retrieve password");
         if (!isReady()) {
             return new String();
         }
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 1b32f57..999e91b 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -734,12 +734,15 @@
             throw new IllegalArgumentException("account is null");
         }
         checkAuthenticateAccountsPermission(account);
-
-        final UserAccounts accounts = getUserAccountsForCaller();
         int userId = Binder.getCallingUserHandle().getIdentifier();
         if (!canUserModifyAccounts(userId) || !canUserModifyAccountsForType(userId, account.type)) {
             return false;
         }
+        return updateLastAuthenticatedTime(account);
+    }
+
+    private boolean updateLastAuthenticatedTime(Account account) {
+        final UserAccounts accounts = getUserAccountsForCaller();
         synchronized (accounts.cacheLock) {
             final ContentValues values = new ContentValues();
             values.put(ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS, System.currentTimeMillis());
@@ -2022,7 +2025,7 @@
         try {
             new Session(accounts, response, account.type, expectActivityLaunch,
                     true /* stripAuthTokenFromResult */, account.name,
-                    true /* authDetailsRequired */) {
+                    true /* authDetailsRequired */, true /* updateLastAuthenticatedTime */) {
                 @Override
                 public void run() throws RemoteException {
                     mAuthenticator.confirmCredentials(this, account, options);
@@ -2059,7 +2062,7 @@
         try {
             new Session(accounts, response, account.type, expectActivityLaunch,
                     true /* stripAuthTokenFromResult */, account.name,
-                    false /* authDetailsRequired */) {
+                    false /* authDetailsRequired */, true /* updateLastCredentialTime */) {
                 @Override
                 public void run() throws RemoteException {
                     mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions);
@@ -2492,6 +2495,11 @@
         final String mAccountName;
         // Indicates if we need to add auth details(like last credential time)
         final boolean mAuthDetailsRequired;
+        // If set, we need to update the last authenticated time. This is
+        // currently
+        // used on
+        // successful confirming credentials.
+        final boolean mUpdateLastAuthenticatedTime;
 
         public int mNumResults = 0;
         private int mNumRequestContinued = 0;
@@ -2505,6 +2513,13 @@
         public Session(UserAccounts accounts, IAccountManagerResponse response, String accountType,
                 boolean expectActivityLaunch, boolean stripAuthTokenFromResult, String accountName,
                 boolean authDetailsRequired) {
+            this(accounts, response, accountType, expectActivityLaunch, stripAuthTokenFromResult,
+                    accountName, authDetailsRequired, false /* updateLastAuthenticatedTime */);
+        }
+
+        public Session(UserAccounts accounts, IAccountManagerResponse response, String accountType,
+                boolean expectActivityLaunch, boolean stripAuthTokenFromResult, String accountName,
+                boolean authDetailsRequired, boolean updateLastAuthenticatedTime) {
             super();
             //if (response == null) throw new IllegalArgumentException("response is null");
             if (accountType == null) throw new IllegalArgumentException("accountType is null");
@@ -2516,6 +2531,7 @@
             mCreationTime = SystemClock.elapsedRealtime();
             mAccountName = accountName;
             mAuthDetailsRequired = authDetailsRequired;
+            mUpdateLastAuthenticatedTime = updateLastAuthenticatedTime;
 
             synchronized (mSessions) {
                 mSessions.put(toString(), this);
@@ -2651,15 +2667,55 @@
         public void onResult(Bundle result) {
             mNumResults++;
             Intent intent = null;
-            if (result != null && mAuthDetailsRequired) {
-                long lastAuthenticatedTime = DatabaseUtils.longForQuery(
-                        mAccounts.openHelper.getReadableDatabase(),
-                        "select " + ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS + " from " +
-                                TABLE_ACCOUNTS + " WHERE " + ACCOUNTS_NAME + "=? AND "
-                                + ACCOUNTS_TYPE + "=?",
-                        new String[]{mAccountName, mAccountType});
-                result.putLong(AccountManager.KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH,
-                        lastAuthenticatedTime);
+            if (result != null) {
+                boolean isSuccessfulConfirmCreds = result.getBoolean(
+                        AccountManager.KEY_BOOLEAN_RESULT, false);
+                boolean isSuccessfulUpdateCreds = 
+                        result.containsKey(AccountManager.KEY_ACCOUNT_NAME)
+                        && result.containsKey(AccountManager.KEY_ACCOUNT_TYPE);
+                // We should only update lastAuthenticated time, if 
+                // mUpdateLastAuthenticatedTime is true and the confirmRequest
+                // or updateRequest was successful
+                boolean needUpdate = mUpdateLastAuthenticatedTime 
+                        && (isSuccessfulConfirmCreds || isSuccessfulUpdateCreds);
+                if (needUpdate || mAuthDetailsRequired) {
+                    boolean accountPresent = isAccountPresentForCaller(mAccountName, mAccountType);
+                    if (needUpdate && accountPresent) {
+                        updateLastAuthenticatedTime(new Account(mAccountName, mAccountType));
+                    }
+                    if (mAuthDetailsRequired) {
+                        long lastAuthenticatedTime = -1;
+                        if (accountPresent) {
+                            lastAuthenticatedTime = DatabaseUtils.longForQuery(
+                                    mAccounts.openHelper.getReadableDatabase(),
+                                    "select " + ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS
+                                            + " from " +
+                                            TABLE_ACCOUNTS + " WHERE " + ACCOUNTS_NAME + "=? AND "
+                                            + ACCOUNTS_TYPE + "=?",
+                                    new String[] {
+                                            mAccountName, mAccountType
+                                    });
+                        }
+                        result.putLong(AccountManager.KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH,
+                                lastAuthenticatedTime);
+                    }
+                }
+                if (mAuthDetailsRequired) {
+                    long lastAuthenticatedTime = -1;
+                    if (isAccountPresentForCaller(mAccountName, mAccountType)) {
+                        lastAuthenticatedTime = DatabaseUtils.longForQuery(
+                                mAccounts.openHelper.getReadableDatabase(),
+                                "select " + ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS + " from "
+                                        +
+                                        TABLE_ACCOUNTS + " WHERE " + ACCOUNTS_NAME + "=? AND "
+                                        + ACCOUNTS_TYPE + "=?",
+                                new String[] {
+                                        mAccountName, mAccountType
+                                });
+                    }
+                    result.putLong(AccountManager.KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH,
+                            lastAuthenticatedTime);
+                }
             }
             if (result != null
                     && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
@@ -3202,6 +3258,17 @@
         return false;
     }
 
+    private boolean isAccountPresentForCaller(String accountName, String accountType) {
+        if (getUserAccountsForCaller().accountCache.containsKey(accountType)) {
+            for (Account account : getUserAccountsForCaller().accountCache.get(accountType)) {
+                if (account.name.equals(accountName)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     private boolean hasExplicitlyGrantedPermission(Account account, String authTokenType,
             int callerUid) {
         if (callerUid == Process.SYSTEM_UID) {
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 28597c1..6b5908d 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -37,7 +37,6 @@
 import static android.Manifest.permission.MANAGE_FINGERPRINT;
 import static android.Manifest.permission.USE_FINGERPRINT;
 
-import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -364,12 +363,12 @@
 
     private class ClientMonitor implements IBinder.DeathRecipient {
         IBinder token;
-        WeakReference<IFingerprintServiceReceiver> receiver;
+        IFingerprintServiceReceiver receiver;
         int userId;
 
         public ClientMonitor(IBinder token, IFingerprintServiceReceiver receiver, int userId) {
             this.token = token;
-            this.receiver = new WeakReference<IFingerprintServiceReceiver>(receiver);
+            this.receiver = receiver;
             this.userId = userId;
             try {
                 token.linkToDeath(this, 0);
@@ -389,6 +388,7 @@
         public void binderDied() {
             token = null;
             removeClient(this);
+            receiver = null;
         }
 
         protected void finalize() throws Throwable {
@@ -406,10 +406,9 @@
          * @return true if we're done.
          */
         private boolean sendRemoved(int fingerId, int groupId) {
-            IFingerprintServiceReceiver rx = receiver.get();
-            if (rx == null) return true; // client not listening
+            if (receiver == null) return true; // client not listening
             try {
-                rx.onRemoved(mHalDeviceId, fingerId, groupId);
+                receiver.onRemoved(mHalDeviceId, fingerId, groupId);
                 return fingerId == 0;
             } catch (RemoteException e) {
                 Slog.w(TAG, "Failed to notify Removed:", e);
@@ -421,11 +420,10 @@
          * @return true if we're done.
          */
         private boolean sendEnrollResult(int fpId, int groupId, int remaining) {
-            IFingerprintServiceReceiver rx = receiver.get();
-            if (rx == null) return true; // client not listening
+            if (receiver == null) return true; // client not listening
             FingerprintUtils.vibrateFingerprintSuccess(getContext());
             try {
-                rx.onEnrollResult(mHalDeviceId, fpId, groupId, remaining);
+                receiver.onEnrollResult(mHalDeviceId, fpId, groupId, remaining);
                 return remaining == 0;
             } catch (RemoteException e) {
                 Slog.w(TAG, "Failed to notify EnrollResult:", e);
@@ -437,11 +435,10 @@
          * @return true if we're done.
          */
         private boolean sendAuthenticated(int fpId, int groupId) {
-            IFingerprintServiceReceiver rx = receiver.get();
             boolean result = false;
-            if (rx != null) {
+            if (receiver != null) {
                 try {
-                    rx.onAuthenticated(mHalDeviceId, fpId, groupId);
+                    receiver.onAuthenticated(mHalDeviceId, fpId, groupId);
                 } catch (RemoteException e) {
                     Slog.w(TAG, "Failed to notify Authenticated:", e);
                     result = true; // client failed
@@ -464,10 +461,9 @@
          * @return true if we're done.
          */
         private boolean sendAcquired(int acquiredInfo) {
-            IFingerprintServiceReceiver rx = receiver.get();
-            if (rx == null) return true; // client not listening
+            if (receiver == null) return true; // client not listening
             try {
-                rx.onAcquired(mHalDeviceId, acquiredInfo);
+                receiver.onAcquired(mHalDeviceId, acquiredInfo);
                 return false; // acquisition continues...
             } catch (RemoteException e) {
                 Slog.w(TAG, "Failed to invoke sendAcquired:", e);
@@ -479,10 +475,9 @@
          * @return true if we're done.
          */
         private boolean sendError(int error) {
-            IFingerprintServiceReceiver rx = receiver.get();
-            if (rx != null) {
+            if (receiver != null) {
                 try {
-                    rx.onError(mHalDeviceId, error);
+                    receiver.onError(mHalDeviceId, error);
                 } catch (RemoteException e) {
                     Slog.w(TAG, "Failed to invoke sendError:", e);
                 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 1008653..25998da 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -36,6 +36,9 @@
 import android.app.NotificationManager.Policy;
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
+import android.app.usage.UsageEvents;
+import android.app.usage.UsageStats;
+import android.app.usage.UsageStatsManagerInternal;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -97,6 +100,7 @@
 import com.android.internal.R;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.server.EventLogTags;
+import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.lights.Light;
 import com.android.server.lights.LightsManager;
@@ -236,6 +240,7 @@
     ArrayList<String> mLights = new ArrayList<>();
 
     private AppOpsManager mAppOps;
+    private UsageStatsManagerInternal mAppUsageStats;
 
     private Archive mArchive;
 
@@ -871,6 +876,7 @@
         mAm = ActivityManagerNative.getDefault();
         mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
         mVibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
+        mAppUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
 
         mHandler = new WorkerHandler();
         mRankingThread.start();
@@ -1405,6 +1411,41 @@
             }
         }
 
+        @Override
+        public void setNotificationsShownFromListener(INotificationListener token, String[] keys) {
+            final int callingUid = Binder.getCallingUid();
+            final int callingPid = Binder.getCallingPid();
+            long identity = Binder.clearCallingIdentity();
+            try {
+                synchronized (mNotificationList) {
+                    final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
+                    if (keys != null) {
+                        final int N = keys.length;
+                        for (int i = 0; i < N; i++) {
+                            NotificationRecord r = mNotificationsByKey.get(keys[i]);
+                            if (r == null) continue;
+                            final int userId = r.sbn.getUserId();
+                            if (userId != info.userid && userId != UserHandle.USER_ALL &&
+                                    !mUserProfiles.isCurrentProfile(userId)) {
+                                throw new SecurityException("Disallowed call from listener: "
+                                        + info.service);
+                            }
+                            if (!r.isSeen()) {
+                                if (DBG) Slog.d(TAG, "Marking notification as seen " + keys[i]);
+                                mAppUsageStats.reportEvent(r.sbn.getPackageName(),
+                                        userId == UserHandle.USER_ALL ? UserHandle.USER_OWNER
+                                                : userId,
+                                        UsageEvents.Event.INTERACTION);
+                                r.setSeen();
+                            }
+                        }
+                    }
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
         private void cancelNotificationFromListenerLocked(ManagedServiceInfo info,
                 int callingUid, int callingPid, String pkg, String tag, int id, int userId) {
             cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 5569a09..e106a4a 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -50,6 +50,8 @@
     NotificationUsageStats.SingleNotificationStats stats;
     boolean isCanceled;
     int score;
+    /** Whether the notification was seen by the user via one of the notification listeners. */
+    boolean mIsSeen;
 
     // These members are used by NotificationSignalExtractors
     // to communicate with the ranking module.
@@ -301,6 +303,16 @@
         return mGlobalSortKey;
     }
 
+    /** Check if any of the listeners have marked this notification as seen by the user. */
+    public boolean isSeen() {
+        return mIsSeen;
+    }
+
+    /** Mark the notification as seen by the user. */
+    public void setSeen() {
+        mIsSeen = true;
+    }
+
     public void setAuthoritativeRank(int authoritativeRank) {
         mAuthoritativeRank = authoritativeRank;
     }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 25857c5..5536d4d 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2151,6 +2151,16 @@
 
             win.setType(
                 WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
+
+            synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
+                // Assumes it's safe to show starting windows of launched apps while
+                // the keyguard is being hidden. This is okay because starting windows never show
+                // secret information.
+                if (mKeyguardHidden) {
+                    windowFlags |= FLAG_SHOW_WHEN_LOCKED;
+                }
+            }
+
             // Force the window flags: this is a fake window, so it is not really
             // touchable or focusable by the user.  We also add in the ALT_FOCUSABLE_IM
             // flag because we do know that the next window will take input
@@ -4131,6 +4141,12 @@
         if (attrs.type == TYPE_STATUS_BAR && (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
             mForceStatusBarFromKeyguard = true;
         }
+
+        boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
+                && attrs.type < FIRST_SYSTEM_WINDOW;
+        final boolean showWhenLocked = (fl & FLAG_SHOW_WHEN_LOCKED) != 0;
+        final boolean dismissKeyguard = (fl & FLAG_DISMISS_KEYGUARD) != 0;
+
         if (mTopFullscreenOpaqueWindowState == null &&
                 win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()) {
             if ((fl & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
@@ -4143,8 +4159,6 @@
             if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                 mShowingLockscreen = true;
             }
-            boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
-                    && attrs.type < FIRST_SYSTEM_WINDOW;
             if (attrs.type == TYPE_DREAM) {
                 // If the lockscreen was showing when the dream started then wait
                 // for the dream to draw before hiding the lockscreen.
@@ -4155,8 +4169,6 @@
                 }
             }
 
-            final boolean showWhenLocked = (fl & FLAG_SHOW_WHEN_LOCKED) != 0;
-            final boolean dismissKeyguard = (fl & FLAG_DISMISS_KEYGUARD) != 0;
             if (appWindow) {
                 final IApplicationToken appToken = win.getAppToken();
                 if (showWhenLocked) {
@@ -4210,10 +4222,20 @@
                 }
 
                 if (mWinShowWhenLocked != null &&
-                        mWinShowWhenLocked.getAppToken() != win.getAppToken()) {
+                        mWinShowWhenLocked.getAppToken() != win.getAppToken() &&
+                        (attrs.flags & FLAG_SHOW_WHEN_LOCKED) == 0) {
                     win.hideLw(false);
                 }
             }
+        } else if (mTopFullscreenOpaqueWindowState == null && mWinShowWhenLocked == null) {
+            // No TopFullscreenOpaqueWindow is showing, but we found a SHOW_WHEN_LOCKED window
+            // that is being hidden in an animation - keep the
+            // keyguard hidden until the new window shows up and
+            // we know whether to show the keyguard or not.
+            if (win.isAnimatingLw() && appWindow && showWhenLocked) {
+                mHideLockScreen = true;
+                mWinShowWhenLocked = win;
+            }
         }
         if (mTopFullscreenOpaqueOrDimmingWindowState == null
                 && win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 897b865..52071cc 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -201,9 +201,11 @@
                 null : winShowWhenLocked.mAppToken;
         final boolean hideWhenLocked =
                 !(((win.mIsImWindow || imeTarget == win) && showImeOverKeyguard)
-                        || (appShowWhenLocked != null && (appShowWhenLocked == win.mAppToken ||
+                        || (appShowWhenLocked != null && (appShowWhenLocked == win.mAppToken
+                        // Show all SHOW_WHEN_LOCKED windows while they're animating
+                        || (win.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0 && win.isAnimatingLw()
                         // Show error dialogs over apps that dismiss keyguard.
-                        (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0)));
+                        || (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0)));
         return ((mForceHiding == KEYGUARD_ANIMATING_IN)
                 && (!win.mWinAnimator.isAnimating() || hideWhenLocked))
                 || ((mForceHiding == KEYGUARD_SHOWN) && hideWhenLocked);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 3d54dfb..04984d3 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -17,7 +17,10 @@
 package com.android.server.usage;
 
 import android.Manifest;
+import android.app.ActivityManagerNative;
+import android.app.AppGlobals;
 import android.app.AppOpsManager;
+import android.app.admin.DevicePolicyManager;
 import android.app.usage.ConfigurationStats;
 import android.app.usage.IUsageStatsManager;
 import android.app.usage.UsageEvents;
@@ -25,11 +28,13 @@
 import android.app.usage.UsageStats;
 import android.app.usage.UsageStatsManagerInternal;
 import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
+import android.appwidget.AppWidgetManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.UserInfo;
@@ -82,6 +87,7 @@
     static final int MSG_FLUSH_TO_DISK = 1;
     static final int MSG_REMOVE_USER = 2;
     static final int MSG_INFORM_LISTENERS = 3;
+    static final int MSG_RESET_LAST_TIMESTAMP = 4;
 
     private final Object mLock = new Object();
     Handler mHandler;
@@ -279,6 +285,29 @@
     }
 
     /**
+     * Forces the app's timestamp to reflect idle or active. If idle, then it rolls back the
+     * last used timestamp to a point in time thats behind the threshold for idle.
+     */
+    void resetLastTimestamp(String packageName, int userId, boolean idle) {
+        synchronized (mLock) {
+            final long timeNow = checkAndGetTimeLocked();
+            final long lastTimestamp = timeNow - (idle ? mAppIdleDurationMillis : 0);
+
+            final UserUsageStatsService service =
+                    getUserDataAndInitializeIfNeededLocked(userId, timeNow);
+            final long lastUsed = service.getLastPackageAccessTime(packageName);
+            final boolean previouslyIdle = hasPassedIdleDuration(lastUsed);
+            service.setLastTimestamp(packageName, lastTimestamp);
+            // Inform listeners if necessary
+            if (previouslyIdle != idle) {
+                // Slog.d(TAG, "Informing listeners of out-of-idle " + event.mPackage);
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId,
+                        /* idle = */ idle ? 1 : 0, packageName));
+            }
+        }
+    }
+
+    /**
      * Called by the Binder stub.
      */
     void flushToDisk() {
@@ -384,13 +413,39 @@
     }
 
     boolean isAppIdle(String packageName, int userId) {
+        if (packageName == null) return false;
         if (SystemConfig.getInstance().getAllowInPowerSave().contains(packageName)) {
             return false;
         }
+        if (isActiveDeviceAdmin(packageName, userId)) {
+            return false;
+        }
+
         final long lastUsed = getLastPackageAccessTime(packageName, userId);
         return hasPassedIdleDuration(lastUsed);
     }
 
+    void setAppIdle(String packageName, boolean idle, int userId) {
+        if (packageName == null) return;
+
+        mHandler.obtainMessage(MSG_RESET_LAST_TIMESTAMP, userId, idle ? 1 : 0, packageName)
+                .sendToTarget();
+    }
+
+    private boolean isActiveDeviceAdmin(String packageName, int userId) {
+        DevicePolicyManager dpm = getContext().getSystemService(DevicePolicyManager.class);
+        if (dpm == null) return false;
+        List<ComponentName> components = dpm.getActiveAdminsAsUser(userId);
+        if (components == null) return false;
+        final int size = components.size();
+        for (int i = 0; i < size; i++) {
+            if (components.get(i).getPackageName().equals(packageName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     void informListeners(String packageName, int userId, boolean isIdle) {
         for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
             listener.onAppIdleStateChanged(packageName, userId, isIdle);
@@ -459,6 +514,10 @@
                     informListeners((String) msg.obj, msg.arg1, msg.arg2 == 1);
                     break;
 
+                case MSG_RESET_LAST_TIMESTAMP:
+                    resetLastTimestamp((String) msg.obj, msg.arg1, msg.arg2 == 1);
+                    break;
+
                 default:
                     super.handleMessage(msg);
                     break;
@@ -566,6 +625,46 @@
         }
 
         @Override
+        public boolean isAppIdle(String packageName, int userId) {
+            try {
+                userId = ActivityManagerNative.getDefault().handleIncomingUser(Binder.getCallingPid(),
+                        Binder.getCallingUid(), userId, false, true, "isAppIdle", null);
+            } catch (RemoteException re) {
+                return false;
+            }
+            final long token = Binder.clearCallingIdentity();
+            try {
+                return UsageStatsService.this.isAppIdle(packageName, userId);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void setAppIdle(String packageName, boolean idle, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            try {
+                userId = ActivityManagerNative.getDefault().handleIncomingUser(
+                        Binder.getCallingPid(), callingUid, userId, false, true,
+                        "setAppIdle", null);
+            } catch (RemoteException re) {
+                return;
+            }
+            getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE,
+                    "No permission to change app idle state");
+            final long token = Binder.clearCallingIdentity();
+            try {
+                PackageInfo pi = AppGlobals.getPackageManager()
+                        .getPackageInfo(packageName, 0, userId);
+                if (pi == null) return;
+                UsageStatsService.this.setAppIdle(packageName, idle, userId);
+            } catch (RemoteException re) {
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
                     != PackageManager.PERMISSION_GRANTED) {
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 0a9481a..d94759d 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -211,6 +211,17 @@
         notifyStatsChanged();
     }
 
+    /**
+     * Sets the last timestamp for each of the intervals.
+     * @param lastTimestamp
+     */
+    void setLastTimestamp(String packageName, long lastTimestamp) {
+        for (IntervalStats stats : mCurrentStats) {
+            stats.update(packageName, lastTimestamp, UsageEvents.Event.NONE);
+        }
+        notifyStatsChanged();
+    }
+
     private static final StatCombiner<UsageStats> sUsageStatsCombiner =
             new StatCombiner<UsageStats>() {
                 @Override
diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
index 8f0c6c8..daccf95 100644
--- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java
+++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
@@ -142,8 +142,10 @@
 
         // add existing alsa devices
         File[] files = new File(ALSA_DIRECTORY).listFiles();
-        for (int i = 0; i < files.length; i++) {
-            alsaFileAdded(files[i].getName());
+        if (files != null) {
+            for (int i = 0; i < files.length; i++) {
+                alsaFileAdded(files[i].getName());
+            }
         }
     }
 
diff --git a/telecomm/java/android/telecom/DefaultDialerManager.java b/telecomm/java/android/telecom/DefaultDialerManager.java
index eef72fb..bf8fac6 100644
--- a/telecomm/java/android/telecom/DefaultDialerManager.java
+++ b/telecomm/java/android/telecom/DefaultDialerManager.java
@@ -87,15 +87,15 @@
         }
 
         // No user-set dialer found, fallback to system dialer
-        ComponentName systemDialer = getTelecomManager(context).getDefaultPhoneApp();
+        String systemDialer = getTelecomManager(context).getSystemDialerPackage();
 
-        if (systemDialer == null) {
+        if (TextUtils.isEmpty(systemDialer)) {
             // No system dialer configured at build time
             return null;
         }
 
         // Verify that the system dialer has not been disabled.
-        return getComponentName(componentNames, systemDialer.getPackageName());
+        return getComponentName(componentNames, systemDialer);
     }
 
     /**
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index fd95327..8d6bda8 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -110,6 +110,28 @@
             "android.telecom.action.PHONE_ACCOUNT_REGISTERED";
 
     /**
+     * Activity action: Shows a dialog asking the user whether or not they want to replace the
+     * current default Dialer with the one specified in
+     * {@link #EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME}.
+     *
+     * Usage example:
+     * <pre>
+     * Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
+     * intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME,
+     *         getActivity().getPackageName());
+     * startActivity(intent);
+     * </pre>
+     */
+    public static final String ACTION_CHANGE_DEFAULT_DIALER =
+            "android.telecom.action.CHANGE_DEFAULT_DIALER";
+
+    /**
+     * Extra value used to provide the package name for {@link #ACTION_CHANGE_DEFAULT_DIALER}.
+     */
+    public static final String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME =
+            "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME";
+
+    /**
      * Optional extra for {@link android.content.Intent#ACTION_CALL} containing a boolean that
      * determines whether the speakerphone should be automatically turned on for an outgoing call.
      */
@@ -689,7 +711,10 @@
         }
     }
 
+
     /**
+     * @deprecated - Use {@link TelecomManager#getDefaultDialerPackage} to directly access
+     *         the default dialer's package name instead.
      * @hide
      */
     @SystemApi
@@ -705,6 +730,40 @@
     }
 
     /**
+     * Used to determine the currently selected default dialer package.
+     *
+     * @return package name for the default dialer package or null if no package has been
+     *         selected as the default dialer.
+     */
+    public String getDefaultDialerPackage() {
+        try {
+            if (isServiceConnected()) {
+                return getTelecomService().getDefaultDialerPackage();
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException attempting to get the default dialer package name.", e);
+        }
+        return null;
+    }
+
+    /**
+     * Used to determine the dialer package that is preloaded on the system partition.
+     *
+     * @return package name for the system dialer package or null if no system dialer is preloaded.
+     * @hide
+     */
+    public String getSystemDialerPackage() {
+        try {
+            if (isServiceConnected()) {
+                return getTelecomService().getSystemDialerPackage();
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException attempting to get the system dialer package name.", e);
+        }
+        return null;
+    }
+
+    /**
      * Return whether a given phone number is the configured voicemail number for a
      * particular phone account.
      *
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 45b2482..49f2aad 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -137,6 +137,16 @@
      */
     ComponentName getDefaultPhoneApp();
 
+    /**
+     * @see TelecomServiceImpl#getDefaultDialerPackage
+     */
+    String getDefaultDialerPackage();
+
+    /**
+     * @see TelecomServiceImpl#getSystemDialerPackage
+     */
+    String getSystemDialerPackage();
+
     //
     // Internal system apis relating to call management.
     //
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 7d1a2fa..831a194 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -208,13 +208,13 @@
     }
 
     /**
-     * Returns a bundle with the default value for every supported configuration variable.
+     * Returns a new bundle with the default value for every supported configuration variable.
      *
      * @hide
      */
     @SystemApi
     public static Bundle getDefaultConfig() {
-        return sDefaults;
+        return new Bundle(sDefaults);
     }
 
     /** @hide */
diff --git a/tools/obbtool/pbkdf2gen.cpp b/tools/obbtool/pbkdf2gen.cpp
index 98d67c0..f1d8d04 100644
--- a/tools/obbtool/pbkdf2gen.cpp
+++ b/tools/obbtool/pbkdf2gen.cpp
@@ -20,6 +20,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>