Merge "Unfinal getPhone."
diff --git a/Android.mk b/Android.mk
index 1223475..bd8b16a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -209,6 +209,7 @@
 	core/java/android/os/IUserManager.aidl \
 	core/java/android/os/IVibratorService.aidl \
 	core/java/android/security/IKeystoreService.aidl \
+	core/java/android/service/carrier/ICarrierConfigService.aidl \
 	core/java/android/service/carrier/ICarrierMessagingCallback.aidl \
 	core/java/android/service/carrier/ICarrierMessagingService.aidl \
 	core/java/android/service/gatekeeper/IGateKeeperService.aidl \
@@ -390,15 +391,16 @@
 	telephony/java/com/android/ims/internal/IImsVideoCallCallback.aidl \
 	telephony/java/com/android/ims/internal/IImsVideoCallProvider.aidl \
 	telephony/java/com/android/ims/ImsConfigListener.aidl \
+	telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl \
+	telephony/java/com/android/internal/telephony/IMms.aidl \
+	telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl \
 	telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl \
 	telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
+	telephony/java/com/android/internal/telephony/ISms.aidl \
+	telephony/java/com/android/internal/telephony/ISub.aidl \
 	telephony/java/com/android/internal/telephony/ITelephony.aidl \
 	telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
-	telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl \
-	telephony/java/com/android/internal/telephony/ISms.aidl \
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
-	telephony/java/com/android/internal/telephony/ISub.aidl \
-	telephony/java/com/android/internal/telephony/IMms.aidl \
 	wifi/java/android/net/wifi/IWifiManager.aidl \
 	wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl \
 	wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
@@ -549,6 +551,7 @@
 	frameworks/base/core/java/android/view/textservice/SpellCheckerInfo.aidl \
 	frameworks/base/core/java/android/view/textservice/SentenceSuggestionsInfo.aidl \
 	frameworks/base/core/java/android/view/textservice/SuggestionsInfo.aidl \
+	frameworks/base/core/java/android/service/carrier/CarrierIdentifier.aidl \
 	frameworks/base/core/java/android/service/carrier/MessagePdu.aidl \
 	frameworks/base/core/java/android/service/notification/StatusBarNotification.aidl \
 	frameworks/base/core/java/android/service/chooser/ChooserTarget.aidl \
diff --git a/api/current.txt b/api/current.txt
index a6110a5..326ad86 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -20,6 +20,7 @@
     field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
     field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
     field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
+    field public static final java.lang.String BIND_CARRIER_CONFIG_SERVICE = "android.permission.BIND_CARRIER_CONFIG_SERVICE";
     field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
     field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
     field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
@@ -1098,7 +1099,8 @@
     field public static final int showAsAction = 16843481; // 0x10102d9
     field public static final int showDefault = 16843258; // 0x10101fa
     field public static final int showDividers = 16843561; // 0x1010329
-    field public static final int showOnLockScreen = 16843721; // 0x10103c9
+    field public static final int showForAllUsers = 16844018; // 0x10104f2
+    field public static final deprecated int showOnLockScreen = 16843721; // 0x10103c9
     field public static final int showSilent = 16843259; // 0x10101fb
     field public static final int showText = 16843949; // 0x10104ad
     field public static final deprecated int showWeekNumber = 16843582; // 0x101033e
@@ -1978,6 +1980,7 @@
     field public static final int TextAppearance_Material_Widget_ActionMode_Title = 16974355; // 0x1030213
     field public static final int TextAppearance_Material_Widget_ActionMode_Title_Inverse = 16974356; // 0x1030214
     field public static final int TextAppearance_Material_Widget_Button = 16974357; // 0x1030215
+    field public static final int TextAppearance_Material_Widget_Button_Inverse = 16974565; // 0x10302e5
     field public static final int TextAppearance_Material_Widget_DropDownHint = 16974358; // 0x1030216
     field public static final int TextAppearance_Material_Widget_DropDownItem = 16974359; // 0x1030217
     field public static final int TextAppearance_Material_Widget_EditText = 16974360; // 0x1030218
@@ -3633,12 +3636,15 @@
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.ActivityManager.RecentTaskInfo> CREATOR;
     field public int affiliatedTaskId;
+    field public android.content.ComponentName baseActivity;
     field public android.content.Intent baseIntent;
     field public java.lang.CharSequence description;
     field public int id;
+    field public int numActivities;
     field public android.content.ComponentName origActivity;
     field public int persistentId;
     field public android.app.ActivityManager.TaskDescription taskDescription;
+    field public android.content.ComponentName topActivity;
   }
 
   public static class ActivityManager.RunningAppProcessInfo implements android.os.Parcelable {
@@ -7740,6 +7746,7 @@
     field public static final java.lang.String BLUETOOTH_SERVICE = "bluetooth";
     field public static final java.lang.String CAMERA_SERVICE = "camera";
     field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
+    field public static final java.lang.String CARRIER_CONFIG_SERVICE = "carrier_config";
     field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
     field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
     field public static final java.lang.String CONSUMER_IR_SERVICE = "consumer_ir";
@@ -15564,6 +15571,11 @@
     ctor public MediaCryptoException(java.lang.String);
   }
 
+  public abstract interface MediaDataSource implements java.io.Closeable {
+    method public abstract long getSize();
+    method public abstract int readAt(long, byte[], int);
+  }
+
   public class MediaDescription implements android.os.Parcelable {
     method public int describeContents();
     method public java.lang.CharSequence getDescription();
@@ -15699,6 +15711,7 @@
     method public final void release();
     method public void seekTo(long, int);
     method public void selectTrack(int);
+    method public final void setDataSource(android.media.MediaDataSource) throws java.io.IOException, java.lang.IllegalArgumentException;
     method public final void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException;
     method public final void setDataSource(java.lang.String, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException;
     method public final void setDataSource(java.lang.String) throws java.io.IOException;
@@ -15878,6 +15891,7 @@
     method public void setDataSource(java.io.FileDescriptor, long, long) throws java.lang.IllegalArgumentException;
     method public void setDataSource(java.io.FileDescriptor) throws java.lang.IllegalArgumentException;
     method public void setDataSource(android.content.Context, android.net.Uri) throws java.lang.IllegalArgumentException, java.lang.SecurityException;
+    method public void setDataSource(android.media.MediaDataSource) throws java.lang.IllegalArgumentException;
     field public static final int METADATA_KEY_ALBUM = 1; // 0x1
     field public static final int METADATA_KEY_ALBUMARTIST = 13; // 0xd
     field public static final int METADATA_KEY_ARTIST = 2; // 0x2
@@ -15962,6 +15976,7 @@
     method public void setDataSource(java.lang.String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
     method public void setDataSource(java.io.FileDescriptor) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
     method public void setDataSource(java.io.FileDescriptor, long, long) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void setDataSource(android.media.MediaDataSource) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
     method public void setDisplay(android.view.SurfaceHolder);
     method public void setLooping(boolean);
     method public void setNextMediaPlayer(android.media.MediaPlayer);
@@ -16284,7 +16299,7 @@
 
   public final class MediaSync {
     ctor public MediaSync();
-    method public void configureAudioTrack(android.media.AudioTrack, int);
+    method public void configureAudioTrack(android.media.AudioTrack);
     method public void configureSurface(android.view.Surface);
     method public final android.view.Surface createInputSurface();
     method public boolean getTimestamp(android.media.MediaTimestamp);
@@ -22833,6 +22848,8 @@
     method public static long getNativeHeapFreeSize();
     method public static long getNativeHeapSize();
     method public static long getPss();
+    method public static java.lang.String getRuntimeStat(java.lang.String);
+    method public static java.util.Map<java.lang.String, java.lang.String> getRuntimeStats();
     method public static deprecated int getThreadAllocCount();
     method public static deprecated int getThreadAllocSize();
     method public static deprecated int getThreadExternalAllocCount();
@@ -27990,6 +28007,62 @@
     method public void setLUT(android.renderscript.Allocation);
   }
 
+  public final class ScriptIntrinsicBLAS extends android.renderscript.ScriptIntrinsic {
+    method public void BNNM(android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation, int, int);
+    method public void CGEMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+    method public void CHEMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void CHER2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void CHERK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void CSYMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+    method public void CSYR2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+    method public void CSYRK(int, int, float, float, android.renderscript.Allocation, float, float, android.renderscript.Allocation);
+    method public void CTRMM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void CTRSM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void DGEMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void DSYMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void DSYR2K(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void DSYRK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void DTRMM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void DTRSM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void SGEMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void SSYMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void SSYR2K(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void SSYRK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void STRMM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void STRSM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void ZGEMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+    method public void ZHEMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void ZHER2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void ZHERK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void ZSYMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+    method public void ZSYR2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+    method public void ZSYRK(int, int, double, double, android.renderscript.Allocation, double, double, android.renderscript.Allocation);
+    method public void ZTRMM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void ZTRSM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public static android.renderscript.ScriptIntrinsicBLAS create(android.renderscript.RenderScript);
+    field public static final int CONJ_TRANSPOSE = 113; // 0x71
+    field public static final int LEFT = 141; // 0x8d
+    field public static final int LOWER = 122; // 0x7a
+    field public static final int NON_UNIT = 131; // 0x83
+    field public static final int NO_TRANSPOSE = 111; // 0x6f
+    field public static final int RIGHT = 142; // 0x8e
+    field public static final int TRANSPOSE = 112; // 0x70
+    field public static final int UNIT = 132; // 0x84
+    field public static final int UPPER = 121; // 0x79
+  }
+
+  public static abstract class ScriptIntrinsicBLAS.Diag implements java.lang.annotation.Annotation {
+  }
+
+  public static abstract class ScriptIntrinsicBLAS.Side implements java.lang.annotation.Annotation {
+  }
+
+  public static abstract class ScriptIntrinsicBLAS.Transpose implements java.lang.annotation.Annotation {
+  }
+
+  public static abstract class ScriptIntrinsicBLAS.Uplo implements java.lang.annotation.Annotation {
+  }
+
   public class ScriptIntrinsicBlend extends android.renderscript.ScriptIntrinsic {
     method public static android.renderscript.ScriptIntrinsicBlend create(android.renderscript.RenderScript, android.renderscript.Element);
     method public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation);
@@ -28400,6 +28473,7 @@
   public static abstract class KeyStoreKeyProperties.Origin {
     field public static final int GENERATED = 1; // 0x1
     field public static final int IMPORTED = 2; // 0x2
+    field public static final int UNKNOWN = 4; // 0x4
   }
 
   public static abstract class KeyStoreKeyProperties.OriginEnum implements java.lang.annotation.Annotation {
@@ -28498,6 +28572,26 @@
 
 package android.service.carrier {
 
+  public abstract class CarrierConfigService extends android.app.Service {
+    ctor public CarrierConfigService();
+    method public final android.os.IBinder onBind(android.content.Intent);
+    method public abstract android.os.Bundle onLoadConfig(android.service.carrier.CarrierIdentifier);
+    field public static final java.lang.String SERVICE_INTERFACE = "android.service.carrier.CarrierConfigService";
+  }
+
+  public class CarrierIdentifier implements android.os.Parcelable {
+    ctor public CarrierIdentifier(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
+    method public int describeContents();
+    method public java.lang.String getGid1();
+    method public java.lang.String getGid2();
+    method public java.lang.String getImsi();
+    method public java.lang.String getMcc();
+    method public java.lang.String getMnc();
+    method public java.lang.String getSpn();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.service.carrier.CarrierIdentifier> CREATOR;
+  }
+
   public abstract class CarrierMessagingService extends android.app.Service {
     ctor public CarrierMessagingService();
     method public android.os.IBinder onBind(android.content.Intent);
@@ -29871,7 +29965,6 @@
   }
 
   public final class Call {
-    method public void addListener(android.telecom.Call.Listener);
     method public void answer(int);
     method public void conference(android.telecom.Call);
     method public void disconnect();
@@ -29888,12 +29981,13 @@
     method public void phoneAccountSelected(android.telecom.PhoneAccountHandle, boolean);
     method public void playDtmfTone(char);
     method public void postDialContinue(boolean);
+    method public void registerCallback(android.telecom.Call.Callback);
     method public void reject(boolean, java.lang.String);
-    method public void removeListener(android.telecom.Call.Listener);
     method public void splitFromConference();
     method public void stopDtmfTone();
     method public void swapConference();
     method public void unhold();
+    method public void unregisterCallback(android.telecom.Call.Callback);
     field public static final java.lang.String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts";
     field public static final int STATE_ACTIVE = 4; // 0x4
     field public static final int STATE_CONNECTING = 9; // 0x9
@@ -29906,6 +30000,19 @@
     field public static final int STATE_RINGING = 2; // 0x2
   }
 
+  public static abstract class Call.Callback {
+    ctor public Call.Callback();
+    method public void onCallDestroyed(android.telecom.Call);
+    method public void onCannedTextResponsesLoaded(android.telecom.Call, java.util.List<java.lang.String>);
+    method public void onChildrenChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
+    method public void onConferenceableCallsChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
+    method public void onDetailsChanged(android.telecom.Call, android.telecom.Call.Details);
+    method public void onParentChanged(android.telecom.Call, android.telecom.Call);
+    method public void onPostDialWait(android.telecom.Call, java.lang.String);
+    method public void onStateChanged(android.telecom.Call, int);
+    method public void onVideoCallChanged(android.telecom.Call, android.telecom.InCallService.VideoCall);
+  }
+
   public static class Call.Details {
     method public static boolean can(int, int);
     method public boolean can(int);
@@ -29944,19 +30051,6 @@
     field public static final int CAPABILITY_WIFI = 65536; // 0x10000
   }
 
-  public static abstract class Call.Listener {
-    ctor public Call.Listener();
-    method public void onCallDestroyed(android.telecom.Call);
-    method public void onCannedTextResponsesLoaded(android.telecom.Call, java.util.List<java.lang.String>);
-    method public void onChildrenChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
-    method public void onConferenceableCallsChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
-    method public void onDetailsChanged(android.telecom.Call, android.telecom.Call.Details);
-    method public void onParentChanged(android.telecom.Call, android.telecom.Call);
-    method public void onPostDialWait(android.telecom.Call, java.lang.String);
-    method public void onStateChanged(android.telecom.Call, int);
-    method public void onVideoCallChanged(android.telecom.Call, android.telecom.InCallService.VideoCall);
-  }
-
   public class CallProperties {
     ctor public CallProperties();
     field public static final int CONFERENCE = 1; // 0x1
@@ -30205,6 +30299,7 @@
 
   public static abstract class InCallService.VideoCall {
     ctor public InCallService.VideoCall();
+    method public abstract void registerCallback(android.telecom.InCallService.VideoCall.Callback);
     method public abstract void requestCallDataUsage();
     method public abstract void requestCameraCapabilities();
     method public abstract void sendSessionModifyRequest(android.telecom.VideoProfile);
@@ -30214,12 +30309,12 @@
     method public abstract void setDisplaySurface(android.view.Surface);
     method public abstract void setPauseImage(java.lang.String);
     method public abstract void setPreviewSurface(android.view.Surface);
-    method public abstract void setVideoCallListener(android.telecom.InCallService.VideoCall.Listener);
+    method public deprecated void setVideoCallListener(android.telecom.InCallService.VideoCall.Listener);
     method public abstract void setZoom(float);
   }
 
-  public static abstract class InCallService.VideoCall.Listener {
-    ctor public InCallService.VideoCall.Listener();
+  public static abstract class InCallService.VideoCall.Callback {
+    ctor public InCallService.VideoCall.Callback();
     method public abstract void onCallDataUsageChanged(long);
     method public abstract void onCallSessionEvent(int);
     method public abstract void onCameraCapabilitiesChanged(android.telecom.CameraCapabilities);
@@ -30229,6 +30324,10 @@
     method public abstract void onVideoQualityChanged(int);
   }
 
+  public static abstract deprecated class InCallService.VideoCall.Listener extends android.telecom.InCallService.VideoCall.Callback {
+    ctor public InCallService.VideoCall.Listener();
+  }
+
   public class PhoneAccount implements android.os.Parcelable {
     method public static android.telecom.PhoneAccount.Builder builder(android.telecom.PhoneAccountHandle, java.lang.CharSequence);
     method public android.graphics.drawable.Drawable createIconDrawable(android.content.Context);
@@ -30387,9 +30486,9 @@
     method public java.lang.String getLine1Number(android.telecom.PhoneAccountHandle);
     method public android.telecom.PhoneAccount getPhoneAccount(android.telecom.PhoneAccountHandle);
     method public android.telecom.PhoneAccountHandle getSimCallManager();
+    method public java.lang.String getVoiceMailNumber(android.telecom.PhoneAccountHandle);
     method public boolean handleMmi(java.lang.String);
     method public boolean handleMmi(java.lang.String, android.telecom.PhoneAccountHandle);
-    method public boolean hasVoiceMailNumber(android.telecom.PhoneAccountHandle);
     method public boolean isInCall();
     method public boolean isVoiceMailNumber(android.telecom.PhoneAccountHandle, java.lang.String);
     method public void registerPhoneAccount(android.telecom.PhoneAccount);
@@ -30451,6 +30550,18 @@
 
 package android.telephony {
 
+  public class CarrierConfigManager {
+    method public android.os.Bundle getConfig();
+    method public android.os.Bundle getConfigForSubId(int);
+    method public void reloadCarrierConfigForSubId(int);
+    field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
+    field public static final java.lang.String BOOL_CARRIER_VOLTE_AVAILABLE = "bool_carrier_volte_available";
+    field public static final java.lang.String BOOL_CARRIER_VOLTE_PROVISIONED = "bool_carrier_volte_provisioned";
+    field public static final java.lang.String BOOL_CARRIER_VOLTE_TTY_SUPPORTED = "bool_carrier_volte_tty_supported";
+    field public static final java.lang.String BOOL_SHOW_APN_SETTING_CDMA = "bool_show_apn_setting_cdma";
+    field public static final java.lang.String INT_VOLTE_REPLACEMENT_RAT = "int_volte_replacement_rat";
+  }
+
   public final class CellIdentityCdma implements android.os.Parcelable {
     method public int describeContents();
     method public int getBasestationId();
@@ -34456,6 +34567,7 @@
     method public boolean onTouchEvent(android.view.MotionEvent);
     method public void setIsLongpressEnabled(boolean);
     method public void setOnDoubleTapListener(android.view.GestureDetector.OnDoubleTapListener);
+    method public void setOnStylusButtonPressListener(android.view.GestureDetector.OnStylusButtonPressListener);
   }
 
   public static abstract interface GestureDetector.OnDoubleTapListener {
@@ -34473,7 +34585,11 @@
     method public abstract boolean onSingleTapUp(android.view.MotionEvent);
   }
 
-  public static class GestureDetector.SimpleOnGestureListener implements android.view.GestureDetector.OnDoubleTapListener android.view.GestureDetector.OnGestureListener {
+  public static abstract interface GestureDetector.OnStylusButtonPressListener {
+    method public abstract boolean onStylusButtonPress(android.view.MotionEvent);
+  }
+
+  public static class GestureDetector.SimpleOnGestureListener implements android.view.GestureDetector.OnDoubleTapListener android.view.GestureDetector.OnGestureListener android.view.GestureDetector.OnStylusButtonPressListener {
     ctor public GestureDetector.SimpleOnGestureListener();
     method public boolean onDoubleTap(android.view.MotionEvent);
     method public boolean onDoubleTapEvent(android.view.MotionEvent);
@@ -34484,6 +34600,7 @@
     method public void onShowPress(android.view.MotionEvent);
     method public boolean onSingleTapConfirmed(android.view.MotionEvent);
     method public boolean onSingleTapUp(android.view.MotionEvent);
+    method public boolean onStylusButtonPress(android.view.MotionEvent);
   }
 
   public class Gravity {
diff --git a/api/system-current.txt b/api/system-current.txt
index 667b627..bd7e5a8 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -28,6 +28,7 @@
     field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
     field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
     field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
+    field public static final java.lang.String BIND_CARRIER_CONFIG_SERVICE = "android.permission.BIND_CARRIER_CONFIG_SERVICE";
     field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
     field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
     field public static final java.lang.String BIND_CONDITION_PROVIDER_SERVICE = "android.permission.BIND_CONDITION_PROVIDER_SERVICE";
@@ -1175,7 +1176,8 @@
     field public static final int showAsAction = 16843481; // 0x10102d9
     field public static final int showDefault = 16843258; // 0x10101fa
     field public static final int showDividers = 16843561; // 0x1010329
-    field public static final int showOnLockScreen = 16843721; // 0x10103c9
+    field public static final int showForAllUsers = 16844018; // 0x10104f2
+    field public static final deprecated int showOnLockScreen = 16843721; // 0x10103c9
     field public static final int showSilent = 16843259; // 0x10101fb
     field public static final int showText = 16843949; // 0x10104ad
     field public static final deprecated int showWeekNumber = 16843582; // 0x101033e
@@ -2057,6 +2059,7 @@
     field public static final int TextAppearance_Material_Widget_ActionMode_Title = 16974355; // 0x1030213
     field public static final int TextAppearance_Material_Widget_ActionMode_Title_Inverse = 16974356; // 0x1030214
     field public static final int TextAppearance_Material_Widget_Button = 16974357; // 0x1030215
+    field public static final int TextAppearance_Material_Widget_Button_Inverse = 16974565; // 0x10302e5
     field public static final int TextAppearance_Material_Widget_DropDownHint = 16974358; // 0x1030216
     field public static final int TextAppearance_Material_Widget_DropDownItem = 16974359; // 0x1030217
     field public static final int TextAppearance_Material_Widget_EditText = 16974360; // 0x1030218
@@ -3722,12 +3725,15 @@
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.ActivityManager.RecentTaskInfo> CREATOR;
     field public int affiliatedTaskId;
+    field public android.content.ComponentName baseActivity;
     field public android.content.Intent baseIntent;
     field public java.lang.CharSequence description;
     field public int id;
+    field public int numActivities;
     field public android.content.ComponentName origActivity;
     field public int persistentId;
     field public android.app.ActivityManager.TaskDescription taskDescription;
+    field public android.content.ComponentName topActivity;
   }
 
   public static class ActivityManager.RunningAppProcessInfo implements android.os.Parcelable {
@@ -7956,6 +7962,7 @@
     field public static final java.lang.String BLUETOOTH_SERVICE = "bluetooth";
     field public static final java.lang.String CAMERA_SERVICE = "camera";
     field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
+    field public static final java.lang.String CARRIER_CONFIG_SERVICE = "carrier_config";
     field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
     field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
     field public static final java.lang.String CONSUMER_IR_SERVICE = "consumer_ir";
@@ -16776,6 +16783,11 @@
     ctor public MediaCryptoException(java.lang.String);
   }
 
+  public abstract interface MediaDataSource implements java.io.Closeable {
+    method public abstract long getSize();
+    method public abstract int readAt(long, byte[], int);
+  }
+
   public class MediaDescription implements android.os.Parcelable {
     method public int describeContents();
     method public java.lang.CharSequence getDescription();
@@ -16912,6 +16924,7 @@
     method public final void release();
     method public void seekTo(long, int);
     method public void selectTrack(int);
+    method public final void setDataSource(android.media.MediaDataSource) throws java.io.IOException, java.lang.IllegalArgumentException;
     method public final void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException;
     method public final void setDataSource(java.lang.String, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException;
     method public final void setDataSource(java.lang.String) throws java.io.IOException;
@@ -17091,6 +17104,7 @@
     method public void setDataSource(java.io.FileDescriptor, long, long) throws java.lang.IllegalArgumentException;
     method public void setDataSource(java.io.FileDescriptor) throws java.lang.IllegalArgumentException;
     method public void setDataSource(android.content.Context, android.net.Uri) throws java.lang.IllegalArgumentException, java.lang.SecurityException;
+    method public void setDataSource(android.media.MediaDataSource) throws java.lang.IllegalArgumentException;
     field public static final int METADATA_KEY_ALBUM = 1; // 0x1
     field public static final int METADATA_KEY_ALBUMARTIST = 13; // 0xd
     field public static final int METADATA_KEY_ARTIST = 2; // 0x2
@@ -17175,6 +17189,7 @@
     method public void setDataSource(java.lang.String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
     method public void setDataSource(java.io.FileDescriptor) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
     method public void setDataSource(java.io.FileDescriptor, long, long) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void setDataSource(android.media.MediaDataSource) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
     method public void setDisplay(android.view.SurfaceHolder);
     method public void setLooping(boolean);
     method public void setNextMediaPlayer(android.media.MediaPlayer);
@@ -17499,7 +17514,7 @@
 
   public final class MediaSync {
     ctor public MediaSync();
-    method public void configureAudioTrack(android.media.AudioTrack, int);
+    method public void configureAudioTrack(android.media.AudioTrack);
     method public void configureSurface(android.view.Surface);
     method public final android.view.Surface createInputSurface();
     method public boolean getTimestamp(android.media.MediaTimestamp);
@@ -24721,6 +24736,8 @@
     method public static long getNativeHeapFreeSize();
     method public static long getNativeHeapSize();
     method public static long getPss();
+    method public static java.lang.String getRuntimeStat(java.lang.String);
+    method public static java.util.Map<java.lang.String, java.lang.String> getRuntimeStats();
     method public static deprecated int getThreadAllocCount();
     method public static deprecated int getThreadAllocSize();
     method public static deprecated int getThreadExternalAllocCount();
@@ -29993,6 +30010,62 @@
     method public void setLUT(android.renderscript.Allocation);
   }
 
+  public final class ScriptIntrinsicBLAS extends android.renderscript.ScriptIntrinsic {
+    method public void BNNM(android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation, int, int);
+    method public void CGEMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+    method public void CHEMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void CHER2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void CHERK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void CSYMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+    method public void CSYR2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+    method public void CSYRK(int, int, float, float, android.renderscript.Allocation, float, float, android.renderscript.Allocation);
+    method public void CTRMM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void CTRSM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void DGEMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void DSYMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void DSYR2K(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void DSYRK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void DTRMM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void DTRSM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void SGEMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void SSYMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void SSYR2K(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void SSYRK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void STRMM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void STRSM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void ZGEMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+    method public void ZHEMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void ZHER2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void ZHERK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void ZSYMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+    method public void ZSYR2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+    method public void ZSYRK(int, int, double, double, android.renderscript.Allocation, double, double, android.renderscript.Allocation);
+    method public void ZTRMM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void ZTRSM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public static android.renderscript.ScriptIntrinsicBLAS create(android.renderscript.RenderScript);
+    field public static final int CONJ_TRANSPOSE = 113; // 0x71
+    field public static final int LEFT = 141; // 0x8d
+    field public static final int LOWER = 122; // 0x7a
+    field public static final int NON_UNIT = 131; // 0x83
+    field public static final int NO_TRANSPOSE = 111; // 0x6f
+    field public static final int RIGHT = 142; // 0x8e
+    field public static final int TRANSPOSE = 112; // 0x70
+    field public static final int UNIT = 132; // 0x84
+    field public static final int UPPER = 121; // 0x79
+  }
+
+  public static abstract class ScriptIntrinsicBLAS.Diag implements java.lang.annotation.Annotation {
+  }
+
+  public static abstract class ScriptIntrinsicBLAS.Side implements java.lang.annotation.Annotation {
+  }
+
+  public static abstract class ScriptIntrinsicBLAS.Transpose implements java.lang.annotation.Annotation {
+  }
+
+  public static abstract class ScriptIntrinsicBLAS.Uplo implements java.lang.annotation.Annotation {
+  }
+
   public class ScriptIntrinsicBlend extends android.renderscript.ScriptIntrinsic {
     method public static android.renderscript.ScriptIntrinsicBlend create(android.renderscript.RenderScript, android.renderscript.Element);
     method public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation);
@@ -30403,6 +30476,7 @@
   public static abstract class KeyStoreKeyProperties.Origin {
     field public static final int GENERATED = 1; // 0x1
     field public static final int IMPORTED = 2; // 0x2
+    field public static final int UNKNOWN = 4; // 0x4
   }
 
   public static abstract class KeyStoreKeyProperties.OriginEnum implements java.lang.annotation.Annotation {
@@ -30501,6 +30575,26 @@
 
 package android.service.carrier {
 
+  public abstract class CarrierConfigService extends android.app.Service {
+    ctor public CarrierConfigService();
+    method public final android.os.IBinder onBind(android.content.Intent);
+    method public abstract android.os.Bundle onLoadConfig(android.service.carrier.CarrierIdentifier);
+    field public static final java.lang.String SERVICE_INTERFACE = "android.service.carrier.CarrierConfigService";
+  }
+
+  public class CarrierIdentifier implements android.os.Parcelable {
+    ctor public CarrierIdentifier(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
+    method public int describeContents();
+    method public java.lang.String getGid1();
+    method public java.lang.String getGid2();
+    method public java.lang.String getImsi();
+    method public java.lang.String getMcc();
+    method public java.lang.String getMnc();
+    method public java.lang.String getSpn();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.service.carrier.CarrierIdentifier> CREATOR;
+  }
+
   public abstract class CarrierMessagingService extends android.app.Service {
     ctor public CarrierMessagingService();
     method public android.os.IBinder onBind(android.content.Intent);
@@ -31971,7 +32065,7 @@
   }
 
   public final class Call {
-    method public void addListener(android.telecom.Call.Listener);
+    method public deprecated void addListener(android.telecom.Call.Listener);
     method public void answer(int);
     method public void conference(android.telecom.Call);
     method public void disconnect();
@@ -31988,12 +32082,14 @@
     method public void phoneAccountSelected(android.telecom.PhoneAccountHandle, boolean);
     method public void playDtmfTone(char);
     method public void postDialContinue(boolean);
+    method public void registerCallback(android.telecom.Call.Callback);
     method public void reject(boolean, java.lang.String);
-    method public void removeListener(android.telecom.Call.Listener);
+    method public deprecated void removeListener(android.telecom.Call.Listener);
     method public void splitFromConference();
     method public void stopDtmfTone();
     method public void swapConference();
     method public void unhold();
+    method public void unregisterCallback(android.telecom.Call.Callback);
     field public static final java.lang.String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts";
     field public static final int STATE_ACTIVE = 4; // 0x4
     field public static final int STATE_CONNECTING = 9; // 0x9
@@ -32006,6 +32102,19 @@
     field public static final int STATE_RINGING = 2; // 0x2
   }
 
+  public static abstract class Call.Callback {
+    ctor public Call.Callback();
+    method public void onCallDestroyed(android.telecom.Call);
+    method public void onCannedTextResponsesLoaded(android.telecom.Call, java.util.List<java.lang.String>);
+    method public void onChildrenChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
+    method public void onConferenceableCallsChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
+    method public void onDetailsChanged(android.telecom.Call, android.telecom.Call.Details);
+    method public void onParentChanged(android.telecom.Call, android.telecom.Call);
+    method public void onPostDialWait(android.telecom.Call, java.lang.String);
+    method public void onStateChanged(android.telecom.Call, int);
+    method public void onVideoCallChanged(android.telecom.Call, android.telecom.InCallService.VideoCall);
+  }
+
   public static class Call.Details {
     method public static boolean can(int, int);
     method public boolean can(int);
@@ -32044,17 +32153,8 @@
     field public static final int CAPABILITY_WIFI = 65536; // 0x10000
   }
 
-  public static abstract class Call.Listener {
+  public static abstract deprecated class Call.Listener extends android.telecom.Call.Callback {
     ctor public Call.Listener();
-    method public void onCallDestroyed(android.telecom.Call);
-    method public void onCannedTextResponsesLoaded(android.telecom.Call, java.util.List<java.lang.String>);
-    method public void onChildrenChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
-    method public void onConferenceableCallsChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
-    method public void onDetailsChanged(android.telecom.Call, android.telecom.Call.Details);
-    method public void onParentChanged(android.telecom.Call, android.telecom.Call);
-    method public void onPostDialWait(android.telecom.Call, java.lang.String);
-    method public void onStateChanged(android.telecom.Call, int);
-    method public void onVideoCallChanged(android.telecom.Call, android.telecom.InCallService.VideoCall);
   }
 
   public class CallProperties {
@@ -32308,6 +32408,7 @@
 
   public static abstract class InCallService.VideoCall {
     ctor public InCallService.VideoCall();
+    method public abstract void registerCallback(android.telecom.InCallService.VideoCall.Callback);
     method public abstract void requestCallDataUsage();
     method public abstract void requestCameraCapabilities();
     method public abstract void sendSessionModifyRequest(android.telecom.VideoProfile);
@@ -32317,12 +32418,12 @@
     method public abstract void setDisplaySurface(android.view.Surface);
     method public abstract void setPauseImage(java.lang.String);
     method public abstract void setPreviewSurface(android.view.Surface);
-    method public abstract void setVideoCallListener(android.telecom.InCallService.VideoCall.Listener);
+    method public deprecated void setVideoCallListener(android.telecom.InCallService.VideoCall.Listener);
     method public abstract void setZoom(float);
   }
 
-  public static abstract class InCallService.VideoCall.Listener {
-    ctor public InCallService.VideoCall.Listener();
+  public static abstract class InCallService.VideoCall.Callback {
+    ctor public InCallService.VideoCall.Callback();
     method public abstract void onCallDataUsageChanged(long);
     method public abstract void onCallSessionEvent(int);
     method public abstract void onCameraCapabilitiesChanged(android.telecom.CameraCapabilities);
@@ -32332,6 +32433,10 @@
     method public abstract void onVideoQualityChanged(int);
   }
 
+  public static abstract deprecated class InCallService.VideoCall.Listener extends android.telecom.InCallService.VideoCall.Callback {
+    ctor public InCallService.VideoCall.Listener();
+  }
+
   public final deprecated class Phone {
     method public final void addListener(android.telecom.Phone.Listener);
     method public final boolean canAddCall();
@@ -32524,9 +32629,9 @@
     method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsSupportingScheme(java.lang.String);
     method public java.util.List<android.telecom.PhoneAccountHandle> getRegisteredConnectionManagers();
     method public android.telecom.PhoneAccountHandle getSimCallManager();
+    method public java.lang.String getVoiceMailNumber(android.telecom.PhoneAccountHandle);
     method public boolean handleMmi(java.lang.String);
     method public boolean handleMmi(java.lang.String, android.telecom.PhoneAccountHandle);
-    method public boolean hasVoiceMailNumber(android.telecom.PhoneAccountHandle);
     method public boolean isInCall();
     method public boolean isRinging();
     method public boolean isTtySupported();
@@ -32593,6 +32698,24 @@
 
 package android.telephony {
 
+  public class CarrierConfigManager {
+    method public android.os.Bundle getConfig();
+    method public android.os.Bundle getConfigForSubId(int);
+    method public static android.os.Bundle getDefaultConfig();
+    method public void reloadCarrierConfigForSubId(int);
+    method public void updateConfigForPhoneId(int, java.lang.String);
+    field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
+    field public static final java.lang.String BOOL_CARRIER_VOLTE_AVAILABLE = "bool_carrier_volte_available";
+    field public static final java.lang.String BOOL_CARRIER_VOLTE_PROVISIONED = "bool_carrier_volte_provisioned";
+    field public static final java.lang.String BOOL_CARRIER_VOLTE_TTY_SUPPORTED = "bool_carrier_volte_tty_supported";
+    field public static final java.lang.String BOOL_SHOW_APN_SETTING_CDMA = "bool_show_apn_setting_cdma";
+    field public static final java.lang.String INT_VOLTE_REPLACEMENT_RAT = "int_volte_replacement_rat";
+    field public static final java.lang.String SHORT_VVM_PORT_NUMBER = "string_vvm_port_number";
+    field public static final java.lang.String STRING_VVM_DESTINATION_NUMBER = "string_vvm_destination_number";
+    field public static final java.lang.String STRING_VVM_TYPE = "string_vvm_type";
+    field public static final java.lang.String VVM_TYPE_OMTP = "vvm_type_omtp";
+  }
+
   public final class CellIdentityCdma implements android.os.Parcelable {
     method public int describeContents();
     method public int getBasestationId();
@@ -36643,6 +36766,7 @@
     method public boolean onTouchEvent(android.view.MotionEvent);
     method public void setIsLongpressEnabled(boolean);
     method public void setOnDoubleTapListener(android.view.GestureDetector.OnDoubleTapListener);
+    method public void setOnStylusButtonPressListener(android.view.GestureDetector.OnStylusButtonPressListener);
   }
 
   public static abstract interface GestureDetector.OnDoubleTapListener {
@@ -36660,7 +36784,11 @@
     method public abstract boolean onSingleTapUp(android.view.MotionEvent);
   }
 
-  public static class GestureDetector.SimpleOnGestureListener implements android.view.GestureDetector.OnDoubleTapListener android.view.GestureDetector.OnGestureListener {
+  public static abstract interface GestureDetector.OnStylusButtonPressListener {
+    method public abstract boolean onStylusButtonPress(android.view.MotionEvent);
+  }
+
+  public static class GestureDetector.SimpleOnGestureListener implements android.view.GestureDetector.OnDoubleTapListener android.view.GestureDetector.OnGestureListener android.view.GestureDetector.OnStylusButtonPressListener {
     ctor public GestureDetector.SimpleOnGestureListener();
     method public boolean onDoubleTap(android.view.MotionEvent);
     method public boolean onDoubleTapEvent(android.view.MotionEvent);
@@ -36671,6 +36799,7 @@
     method public void onShowPress(android.view.MotionEvent);
     method public boolean onSingleTapConfirmed(android.view.MotionEvent);
     method public boolean onSingleTapUp(android.view.MotionEvent);
+    method public boolean onStylusButtonPress(android.view.MotionEvent);
   }
 
   public class Gravity {
diff --git a/cmds/wm/src/com/android/commands/wm/Wm.java b/cmds/wm/src/com/android/commands/wm/Wm.java
index 815a0ac..64f023f 100644
--- a/cmds/wm/src/com/android/commands/wm/Wm.java
+++ b/cmds/wm/src/com/android/commands/wm/Wm.java
@@ -24,6 +24,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.AndroidException;
+import android.util.DisplayMetrics;
 import android.view.Display;
 import android.view.IWindowManager;
 import com.android.internal.os.BaseCommand;
@@ -45,21 +46,27 @@
         (new Wm()).run(args);
     }
 
+    @Override
     public void onShowUsage(PrintStream out) {
         out.println(
                 "usage: wm [subcommand] [options]\n" +
-                "       wm size [reset|WxH]\n" +
+                "       wm size [reset|WxH|WdpxHdp]\n" +
                 "       wm density [reset|DENSITY]\n" +
                 "       wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM]\n" +
+                "       wm scaling [off|auto]\n" +
                 "\n" +
                 "wm size: return or override display size.\n" +
+                "         width and height in pixels unless suffixed with 'dp'.\n" +
                 "\n" +
                 "wm density: override display density.\n" +
                 "\n" +
-                "wm overscan: set overscan area for display.\n"
+                "wm overscan: set overscan area for display.\n" +
+                "\n" +
+                "wm scaling: set display scaling mode.\n"
                 );
     }
 
+    @Override
     public void onRun() throws Exception {
         mWm = IWindowManager.Stub.asInterface(ServiceManager.checkService(
                         Context.WINDOW_SERVICE));
@@ -76,6 +83,8 @@
             runDisplayDensity();
         } else if (op.equals("overscan")) {
             runDisplayOverscan();
+        } else if (op.equals("scaling")) {
+            runDisplayScaling();
         } else {
             showError("Error: unknown command '" + op + "'");
             return;
@@ -85,6 +94,7 @@
     private void runDisplaySize() throws Exception {
         String size = nextArg();
         int w, h;
+        boolean scale = true;
         if (size == null) {
             Point initialSize = new Point();
             Point baseSize = new Point();
@@ -109,8 +119,8 @@
             String wstr = size.substring(0, div);
             String hstr = size.substring(div+1);
             try {
-                w = Integer.parseInt(wstr);
-                h = Integer.parseInt(hstr);
+                w = parseDimension(wstr);
+                h = parseDimension(hstr);
             } catch (NumberFormatException e) {
                 System.err.println("Error: bad number " + e);
                 return;
@@ -193,4 +203,32 @@
         } catch (RemoteException e) {
         }
     }
+
+    private void runDisplayScaling() throws Exception {
+        String scalingStr = nextArgRequired();
+        if ("auto".equals(scalingStr)) {
+            mWm.setForcedDisplayScalingMode(Display.DEFAULT_DISPLAY, 0);
+        } else if ("off".equals(scalingStr)) {
+            mWm.setForcedDisplayScalingMode(Display.DEFAULT_DISPLAY, 1);
+        } else {
+            System.err.println("Error: scaling must be 'auto' or 'off'");
+        }
+    }
+
+    private int parseDimension(String s) throws NumberFormatException {
+        if (s.endsWith("px")) {
+            return Integer.parseInt(s.substring(0, s.length() - 2));
+        }
+        if (s.endsWith("dp")) {
+            int density;
+            try {
+                density = mWm.getBaseDisplayDensity(Display.DEFAULT_DISPLAY);
+            } catch (RemoteException e) {
+                density = DisplayMetrics.DENSITY_DEFAULT;
+            }
+            return Integer.parseInt(s.substring(0, s.length() - 2)) * density /
+                    DisplayMetrics.DENSITY_DEFAULT;
+        }
+        return Integer.parseInt(s);
+    }
 }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 51ececc..134ecdd 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -862,6 +862,23 @@
          */
         public int affiliatedTaskColor;
 
+        /**
+         * The component launched as the first activity in the task.
+         * This can be considered the "application" of this task.
+         */
+        public ComponentName baseActivity;
+
+        /**
+         * The activity component at the top of the history stack of the task.
+         * This is what the user is currently doing.
+         */
+        public ComponentName topActivity;
+
+        /**
+         * Number of activities in this task.
+         */
+        public int numActivities;
+
         public RecentTaskInfo() {
         }
 
@@ -895,6 +912,9 @@
             dest.writeLong(lastActiveTime);
             dest.writeInt(affiliatedTaskId);
             dest.writeInt(affiliatedTaskColor);
+            ComponentName.writeToParcel(baseActivity, dest);
+            ComponentName.writeToParcel(topActivity, dest);
+            dest.writeInt(numActivities);
         }
 
         public void readFromParcel(Parcel source) {
@@ -911,6 +931,9 @@
             lastActiveTime = source.readLong();
             affiliatedTaskId = source.readInt();
             affiliatedTaskColor = source.readInt();
+            baseActivity = ComponentName.readFromParcel(source);
+            topActivity = ComponentName.readFromParcel(source);
+            numActivities = source.readInt();
         }
 
         public static final Creator<RecentTaskInfo> CREATOR
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 4ede5b1..e446700 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -105,6 +105,7 @@
 import android.service.persistentdata.IPersistentDataBlockService;
 import android.service.persistentdata.PersistentDataBlockManager;
 import android.telecom.TelecomManager;
+import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.util.Log;
@@ -420,6 +421,13 @@
                 return new SubscriptionManager(ctx.getOuterContext());
             }});
 
+        registerService(Context.CARRIER_CONFIG_SERVICE, CarrierConfigManager.class,
+                new CachedServiceFetcher<CarrierConfigManager>() {
+            @Override
+            public CarrierConfigManager createService(ContextImpl ctx) {
+                return new CarrierConfigManager();
+            }});
+
         registerService(Context.TELECOM_SERVICE, TelecomManager.class,
                 new CachedServiceFetcher<TelecomManager>() {
             @Override
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 0cbf960..370f61c 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2193,6 +2193,7 @@
             MEDIA_ROUTER_SERVICE,
             TELEPHONY_SERVICE,
             TELEPHONY_SUBSCRIPTION_SERVICE,
+            CARRIER_CONFIG_SERVICE,
             TELECOM_SERVICE,
             CLIPBOARD_SERVICE,
             INPUT_METHOD_SERVICE,
@@ -2338,6 +2339,8 @@
      * @see android.telephony.TelephonyManager
      * @see #TELEPHONY_SUBSCRIPTION_SERVICE
      * @see android.telephony.SubscriptionManager
+     * @see #CARRIER_CONFIG_SERVICE
+     * @see android.telephony.CarrierConfigManager
      * @see #INPUT_METHOD_SERVICE
      * @see android.view.inputmethod.InputMethodManager
      * @see #UI_MODE_SERVICE
@@ -2755,6 +2758,16 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a
+     * {@link android.telephony.CarrierConfigManager} for reading carrier configuration values.
+     *
+     * @see #getSystemService
+     * @see android.telephony.CarrierConfigManager
+     */
+    public static final String CARRIER_CONFIG_SERVICE = "carrier_config";
+
+    /**
+     * Use with {@link #getSystemService} to retrieve a
+     * {@link android.text.ClipboardManager} for accessing and modifying
      * {@link android.content.ClipboardManager} for accessing and modifying
      * the contents of the global clipboard.
      *
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 8d82aa2..16f6b1e 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -223,11 +223,12 @@
      */
     public static final int FLAG_HARDWARE_ACCELERATED = 0x0200;
     /**
-     * Value for {@link #flags}: true when the application can be displayed over the lockscreen
-     * and consequently over all users' windows.
+     * Value for {@link #flags}: true when the application can be displayed for all users
+     * regardless of if the user of the application is the current user. Set from the
+     * {@link android.R.attr#showForAllUsers} attribute.
      * @hide
      */
-    public static final int FLAG_SHOW_ON_LOCK_SCREEN = 0x0400;
+    public static final int FLAG_SHOW_FOR_ALL_USERS = 0x0400;
     /**
      * Bit in {@link #flags} corresponding to an immersive activity
      * that wishes not to be interrupted by notifications.
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index caf069f..e2701ee 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -339,8 +339,8 @@
      * (e.g., HTTP rather than HTTPS; WebSockets rather than WebSockets Secure; XMPP, IMAP, STMP
      * without STARTTLS or TLS). If {@code false}, the app declares that it does not intend to use
      * cleartext network traffic, in which case platform components (e.g., HTTP stacks,
-     * {@code WebView}, {@code MediaPlayer}) will refuse app's requests to use cleartext traffic.
-     * Third-party libraries are encouraged to honor this flag as well.
+     * {@code WebView}, {@code DownloadManager}, {@code MediaPlayer}) will refuse app's requests to
+     * use cleartext traffic. Third-party libraries are encouraged to honor this flag as well.
      */
     public static final int FLAG_USES_CLEARTEXT_TRAFFIC = 1<<27;
 
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 40f4e8f..fed9261 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3099,8 +3099,9 @@
             a.info.flags |= ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
         }
 
-        if (sa.getBoolean(R.styleable.AndroidManifestActivity_showOnLockScreen, false)) {
-            a.info.flags |= ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN;
+        if (sa.getBoolean(R.styleable.AndroidManifestActivity_showOnLockScreen, false)
+                || sa.getBoolean(R.styleable.AndroidManifestActivity_showForAllUsers, false)) {
+            a.info.flags |= ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
         }
 
         if (sa.getBoolean(R.styleable.AndroidManifestActivity_immersive, false)) {
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 75b1101..4aff7a1 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -1173,7 +1173,6 @@
      *            the name of the runtime statistic to look up.
      * @return the value of the specified runtime statistic or {@code null} if the
      *         runtime statistic doesn't exist.
-     * @hide
      */
     public static String getRuntimeStat(String statName) {
         return VMDebug.getRuntimeStat(statName);
@@ -1184,7 +1183,6 @@
      * that {@link #getRuntimeStat(String)} supports.
      *
      * @return a map of the names/values of the supported runtime statistics.
-     * @hide
      */
     public static Map<String, String> getRuntimeStats() {
         return VMDebug.getRuntimeStats();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 793971f..a622a21 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6033,6 +6033,13 @@
        public static final String DISPLAY_SIZE_FORCED = "display_size_forced";
 
        /**
+        * The saved value for WindowManagerService.setForcedDisplayScalingMode().
+        * 0 or unset if scaling is automatic, 1 if scaling is disabled.
+        * @hide
+        */
+       public static final String DISPLAY_SCALING_FORCE = "display_scaling_force";
+
+       /**
         * The maximum size, in bytes, of a download that the download manager will transfer over
         * a non-wifi connection.
         * @hide
diff --git a/core/java/android/security/NetworkSecurityPolicy.java b/core/java/android/security/NetworkSecurityPolicy.java
index 0b3bf453..70cd388 100644
--- a/core/java/android/security/NetworkSecurityPolicy.java
+++ b/core/java/android/security/NetworkSecurityPolicy.java
@@ -46,9 +46,9 @@
      * without TLS or STARTTLS) is permitted for this process.
      *
      * <p>When cleartext network traffic is not permitted, the platform's components (e.g. HTTP and
-     * FTP stacks, {@link android.webkit.WebView}, {@link android.media.MediaPlayer}) will refuse
-     * this process's requests to use cleartext traffic. Third-party libraries are strongly
-     * encouraged to honor this setting as well.
+     * FTP stacks, {@link android.webkit.WebView}, {@link android.app.DownloadManager},
+     * {@link android.media.MediaPlayer}) will refuse this process's requests to use cleartext
+     * traffic. Third-party libraries are strongly encouraged to honor this setting as well.
      *
      * <p>This flag is honored on a best effort basis because it's impossible to prevent all
      * cleartext traffic from Android applications given the level of access provided to them. For
diff --git a/core/java/android/security/keymaster/KeymasterArgument.java b/core/java/android/security/keymaster/KeymasterArgument.java
index 9a1c894..9adde35 100644
--- a/core/java/android/security/keymaster/KeymasterArgument.java
+++ b/core/java/android/security/keymaster/KeymasterArgument.java
@@ -42,6 +42,7 @@
                         case KeymasterDefs.KM_INT_REP:
                             return new KeymasterIntArgument(tag, in);
                         case KeymasterDefs.KM_LONG:
+                        case KeymasterDefs.KM_LONG_REP:
                             return new KeymasterLongArgument(tag, in);
                         case KeymasterDefs.KM_DATE:
                             return new KeymasterDateArgument(tag, in);
diff --git a/core/java/android/security/keymaster/KeymasterArguments.java b/core/java/android/security/keymaster/KeymasterArguments.java
index 8ed288c..82f65c7 100644
--- a/core/java/android/security/keymaster/KeymasterArguments.java
+++ b/core/java/android/security/keymaster/KeymasterArguments.java
@@ -63,6 +63,12 @@
         }
     }
 
+    public void addLongs(int tag, long... values) {
+        for (long value : values) {
+            addLong(tag, value);
+        }
+    }
+
     public void addBoolean(int tag) {
         mArguments.add(new KeymasterBooleanArgument(tag));
     }
@@ -111,8 +117,13 @@
     }
 
     public long getLong(int tag, long defaultValue) {
-        if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_LONG) {
-            throw new IllegalArgumentException("Tag is not a long type: " + tag);
+        switch (KeymasterDefs.getTagType(tag)) {
+            case KeymasterDefs.KM_LONG:
+                break; // Accepted type
+            case KeymasterDefs.KM_LONG_REP:
+                throw new IllegalArgumentException("Repeatable tags must use getLongs: " + tag);
+            default:
+                throw new IllegalArgumentException("Tag is not a long type: " + tag);
         }
         KeymasterArgument arg = getArgumentByTag(tag);
         if (arg == null) {
@@ -175,6 +186,19 @@
         return values;
     }
 
+    public List<Long> getLongs(int tag) {
+        if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_LONG_REP) {
+            throw new IllegalArgumentException("Tag is not a repeating long: " + tag);
+        }
+        List<Long> values = new ArrayList<Long>();
+        for (KeymasterArgument arg : mArguments) {
+            if (arg.tag == tag) {
+                values.add(((KeymasterLongArgument) arg).value);
+            }
+        }
+        return values;
+    }
+
     public int size() {
         return mArguments.size();
     }
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index ea53c0d..40baf9c 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -118,9 +118,9 @@
     public static final int KM_DIGEST_SHA_2_512 = 6;
 
     // Key origins.
-    public static final int KM_ORIGIN_HARDWARE = 0;
-    public static final int KM_ORIGIN_SOFTWARE = 1;
+    public static final int KM_ORIGIN_GENERATED = 0;
     public static final int KM_ORIGIN_IMPORTED = 2;
+    public static final int KM_ORIGIN_UNKNOWN = 3;
 
     // Key usability requirements.
     public static final int KM_BLOB_STANDALONE = 0;
@@ -192,6 +192,8 @@
     public static final int KM_ERROR_SECURE_HW_BUSY = -48;
     public static final int KM_ERROR_SECURE_HW_COMMUNICATION_FAILED = -49;
     public static final int KM_ERROR_UNSUPPORTED_EC_FIELD = -50;
+    public static final int KM_ERROR_MISSING_NONCE = -51;
+    public static final int KM_ERROR_INVALID_NONCE = -52;
     public static final int KM_ERROR_UNIMPLEMENTED = -100;
     public static final int KM_ERROR_VERSION_MISMATCH = -101;
     public static final int KM_ERROR_UNKNOWN_ERROR = -1000;
@@ -231,6 +233,8 @@
         sErrorCodeToString.put(KM_ERROR_INVALID_TAG, "Invalid tag");
         sErrorCodeToString.put(KM_ERROR_MEMORY_ALLOCATION_FAILED, "Memory allocation failed");
         sErrorCodeToString.put(KM_ERROR_UNSUPPORTED_EC_FIELD, "Unsupported EC field");
+        sErrorCodeToString.put(KM_ERROR_MISSING_NONCE, "Required IV missing");
+        sErrorCodeToString.put(KM_ERROR_INVALID_NONCE, "Invalid IV");
         sErrorCodeToString.put(KM_ERROR_UNIMPLEMENTED, "Not implemented");
         sErrorCodeToString.put(KM_ERROR_UNKNOWN_ERROR, "Unknown error");
     }
diff --git a/core/java/android/security/keymaster/KeymasterLongArgument.java b/core/java/android/security/keymaster/KeymasterLongArgument.java
index 9d2be09..eb17b7e 100644
--- a/core/java/android/security/keymaster/KeymasterLongArgument.java
+++ b/core/java/android/security/keymaster/KeymasterLongArgument.java
@@ -28,6 +28,7 @@
         super(tag);
         switch (KeymasterDefs.getTagType(tag)) {
             case KeymasterDefs.KM_LONG:
+            case KeymasterDefs.KM_LONG_REP:
                 break; // OK.
             default:
                 throw new IllegalArgumentException("Bad long tag " + tag);
diff --git a/core/java/android/service/carrier/CarrierConfigService.java b/core/java/android/service/carrier/CarrierConfigService.java
new file mode 100644
index 0000000..1880d16
--- /dev/null
+++ b/core/java/android/service/carrier/CarrierConfigService.java
@@ -0,0 +1,104 @@
+/*
+ * 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.service.carrier;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+
+/**
+ * A service that sets carrier configuration for telephony services.
+ * <p>
+ * To extend this class, you must declare the service in your manifest file to require the
+ * {@link android.Manifest.permission#BIND_CARRIER_CONFIG_SERVICE} permission and include an intent
+ * filter with the {@link #SERVICE_INTERFACE} action. For example:
+ * </p>
+ *
+ * <pre>{@code
+ * <service android:name=".MyCarrierConfigService"
+ *       android:label="@string/service_name"
+ *       android:permission="android.permission.BIND_CARRIER_CONFIG_SERVICE">
+ *  <intent-filter>
+ *      <action android:name="android.service.carrier.CarrierConfigService" />
+ *  </intent-filter>
+ * </service>
+ * }</pre>
+ */
+public abstract class CarrierConfigService extends Service {
+
+    public static final String SERVICE_INTERFACE = "android.service.carrier.CarrierConfigService";
+
+    private final ICarrierConfigService.Stub mStubWrapper;
+
+    public CarrierConfigService() {
+        mStubWrapper = new ICarrierConfigServiceWrapper();
+    }
+
+    /**
+     * Override this method to set carrier configuration.
+     * <p>
+     * This method will be called by telephony services to get carrier-specific configuration
+     * values. The returned config will be saved by the system until,
+     * <ol>
+     * <li>The carrier app package is updated, or</li>
+     * <li>The carrier app requests a reload with
+     * {@link android.telephony.CarrierConfigManager#reloadCarrierConfigForSubId
+     * reloadCarrierConfigForSubId}.</li>
+     * </ol>
+     * This method can be called after a SIM card loads, which may be before or after boot.
+     * </p>
+     * <p>
+     * This method should not block for a long time. If expensive operations (e.g. network access)
+     * are required, this method can schedule the work and return null. Then, use
+     * {@link android.telephony.CarrierConfigManager#reloadCarrierConfigForSubId
+     * reloadCarrierConfigForSubId} to trigger a reload when the config is ready.
+     * </p>
+     * <p>
+     * Implementations should use the keys defined in {@link android.telephony.CarrierConfigManager
+     * CarrierConfigManager}. Any configuration values not set in the returned {@link Bundle} may be
+     * overridden by the system's default configuration service.
+     * </p>
+     *
+     * @param id contains details about the current carrier that can be used do decide what
+     *            configuration values to return.
+     * @return a {@link Bundle} object containing the configuration or null if default values should
+     *         be used.
+     */
+    public abstract Bundle onLoadConfig(CarrierIdentifier id);
+
+    /** @hide */
+    @Override
+    public final IBinder onBind(Intent intent) {
+        if (!SERVICE_INTERFACE.equals(intent.getAction())) {
+            return null;
+        }
+        return mStubWrapper;
+    }
+
+    /**
+     * A wrapper around ICarrierConfigService that forwards calls to implementations of
+     * {@link CarrierConfigService}.
+     *
+     * @hide
+     */
+    private class ICarrierConfigServiceWrapper extends ICarrierConfigService.Stub {
+
+        @Override
+        public Bundle getCarrierConfig(CarrierIdentifier id) {
+            return CarrierConfigService.this.onLoadConfig(id);
+        }
+    }
+}
diff --git a/packages/SystemUI/res/drawable/ic_audio_phone.xml b/core/java/android/service/carrier/CarrierIdentifier.aidl
similarity index 65%
rename from packages/SystemUI/res/drawable/ic_audio_phone.xml
rename to core/java/android/service/carrier/CarrierIdentifier.aidl
index 64147f2b..48b1398 100644
--- a/packages/SystemUI/res/drawable/ic_audio_phone.xml
+++ b/core/java/android/service/carrier/CarrierIdentifier.aidl
@@ -1,7 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright 2014, The Android Open Source Project
+/**
+ * Copyright (c) 2015, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,9 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
--->
 
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@*android:drawable/ic_audio_phone_am_alpha"
-    android:autoMirrored="true"
-    android:tint="#ffffffff" />
\ No newline at end of file
+package android.service.carrier;
+
+parcelable CarrierIdentifier;
diff --git a/core/java/android/service/carrier/CarrierIdentifier.java b/core/java/android/service/carrier/CarrierIdentifier.java
new file mode 100644
index 0000000..495fea6
--- /dev/null
+++ b/core/java/android/service/carrier/CarrierIdentifier.java
@@ -0,0 +1,117 @@
+/**
+ * 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.service.carrier;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Used to pass info to CarrierConfigService implementations so they can decide what values to
+ * return.
+ */
+public class CarrierIdentifier implements Parcelable {
+
+    /** Used to create a {@link CarrierIdentifier} from a {@link Parcel}. */
+    public static final Creator<CarrierIdentifier> CREATOR = new Creator<CarrierIdentifier>() {
+            @Override
+        public CarrierIdentifier createFromParcel(Parcel parcel) {
+            return new CarrierIdentifier(parcel);
+        }
+
+            @Override
+        public CarrierIdentifier[] newArray(int i) {
+            return new CarrierIdentifier[i];
+        }
+    };
+
+    private String mMcc;
+    private String mMnc;
+    private String mSpn;
+    private String mImsi;
+    private String mGid1;
+    private String mGid2;
+
+    public CarrierIdentifier(String mcc, String mnc, String spn, String imsi, String gid1,
+            String gid2) {
+        mMcc = mcc;
+        mMnc = mnc;
+        mSpn = spn;
+        mImsi = imsi;
+        mGid1 = gid1;
+        mGid2 = gid2;
+    }
+
+    /** @hide */
+    public CarrierIdentifier(Parcel parcel) {
+        readFromParcel(parcel);
+    }
+
+    /** Get the mobile country code. */
+    public String getMcc() {
+        return mMcc;
+    }
+
+    /** Get the mobile network code. */
+    public String getMnc() {
+        return mMnc;
+    }
+
+    /** Get the service provider name. */
+    public String getSpn() {
+        return mSpn;
+    }
+
+    /** Get the international mobile subscriber identity. */
+    public String getImsi() {
+        return mImsi;
+    }
+
+    /** Get the group identifier level 1. */
+    public String getGid1() {
+        return mGid1;
+    }
+
+    /** Get the group identifier level 2. */
+    public String getGid2() {
+        return mGid2;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mMcc);
+        out.writeString(mMnc);
+        out.writeString(mSpn);
+        out.writeString(mImsi);
+        out.writeString(mGid1);
+        out.writeString(mGid2);
+    }
+
+    /** @hide */
+    public void readFromParcel(Parcel in) {
+        mMcc = in.readString();
+        mMnc = in.readString();
+        mSpn = in.readString();
+        mImsi = in.readString();
+        mGid1 = in.readString();
+        mGid2 = in.readString();
+    }
+}
diff --git a/core/java/android/service/carrier/ICarrierConfigService.aidl b/core/java/android/service/carrier/ICarrierConfigService.aidl
new file mode 100644
index 0000000..d8390b6
--- /dev/null
+++ b/core/java/android/service/carrier/ICarrierConfigService.aidl
@@ -0,0 +1,32 @@
+/**
+ * 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.service.carrier;
+
+import android.os.Bundle;
+import android.service.carrier.CarrierIdentifier;
+
+/**
+ * Service used to get carrier config from carrier apps.
+ *
+ * @see android.service.carrier.CarrierConfigService
+ * @hide
+ */
+interface ICarrierConfigService {
+
+    /** @see android.service.carrier.CarrierConfigService#onLoadConfig */
+    Bundle getCarrierConfig(in CarrierIdentifier id);
+}
\ No newline at end of file
diff --git a/core/java/android/service/gatekeeper/IGateKeeperService.aidl b/core/java/android/service/gatekeeper/IGateKeeperService.aidl
index 2f3e296..9edd04d 100644
--- a/core/java/android/service/gatekeeper/IGateKeeperService.aidl
+++ b/core/java/android/service/gatekeeper/IGateKeeperService.aidl
@@ -53,13 +53,20 @@
      * Verifies an enrolled handle against a provided, plaintext blob.
      * @param uid The Android user ID associated to this enrollment
      * @param challenge a challenge to authenticate agaisnt the device credential. If successful
-     *                  authentication occurs, this value will be written to the returned 
+     *                  authentication occurs, this value will be written to the returned
      *                  authentication attestation.
      * @param enrolledPasswordHandle The handle against which the provided password will be
      *                               verified.
      * @param The plaintext blob to verify against enrolledPassword.
      * @return an opaque attestation of authentication on success, or null.
      */
-    byte[] verifyChallenge(int uid, long challenge, in byte[] enrolledPasswordHandle, 
+    byte[] verifyChallenge(int uid, long challenge, in byte[] enrolledPasswordHandle,
             in byte[] providedPassword);
+
+    /**
+     * Retrieves the secure identifier for the user with the provided Android ID,
+     * or 0 if none is found.
+     * @param uid the Android user id
+     */
+    long getSecureUserId(int uid);
 }
diff --git a/core/java/android/text/TextDirectionHeuristics.java b/core/java/android/text/TextDirectionHeuristics.java
index 866137c..354c15f 100644
--- a/core/java/android/text/TextDirectionHeuristics.java
+++ b/core/java/android/text/TextDirectionHeuristics.java
@@ -81,29 +81,47 @@
     private static final int STATE_FALSE = 1;
     private static final int STATE_UNKNOWN = 2;
 
-    private static int isRtlText(int directionality) {
-        switch (directionality) {
+    /* Returns STATE_TRUE for strong RTL characters, STATE_FALSE for strong LTR characters, and
+     * STATE_UNKNOWN for everything else.
+     */
+    private static int isRtlCodePoint(int codePoint) {
+        switch (Character.getDirectionality(codePoint)) {
             case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
                 return STATE_FALSE;
             case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
             case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
                 return STATE_TRUE;
-            default:
-                return STATE_UNKNOWN;
-        }
-    }
+            case Character.DIRECTIONALITY_UNDEFINED:
+                // Unassigned characters still have bidi direction, defined at:
+                // http://www.unicode.org/Public/UCD/latest/ucd/extracted/DerivedBidiClass.txt
 
-    private static int isRtlTextOrFormat(int directionality) {
-        switch (directionality) {
-            case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
-            case Character.DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING:
-            case Character.DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE:
-                return STATE_FALSE;
-            case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
-            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
-            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING:
-            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE:
-                return STATE_TRUE;
+                if ((0x0590 <= codePoint && codePoint <= 0x08FF) ||
+                        (0xFB1D <= codePoint && codePoint <= 0xFDCF) ||
+                        (0xFDF0 <= codePoint && codePoint <= 0xFDFF) ||
+                        (0xFE70 <= codePoint && codePoint <= 0xFEFF) ||
+                        (0x10800 <= codePoint && codePoint <= 0x10FFF) ||
+                        (0x1E800 <= codePoint && codePoint <= 0x1EFFF)) {
+                    // Unassigned RTL character
+                    return STATE_TRUE;
+                } else if (
+                        // Potentially-unassigned Default_Ignorable. Ranges are from unassigned
+                        // characters that have Unicode property Other_Default_Ignorable_Code_Point
+                        // plus some enlargening to cover bidi isolates and simplify checks.
+                        (0x2065 <= codePoint && codePoint <= 0x2069) ||
+                        (0xFFF0 <= codePoint && codePoint <= 0xFFF8) ||
+                        (0xE0000 <= codePoint && codePoint <= 0xE0FFF) ||
+                        // Non-character
+                        (0xFDD0 <= codePoint && codePoint <= 0xFDEF) ||
+                        ((codePoint & 0xFFFE) == 0xFFFE) ||
+                        // Currency symbol
+                        (0x20A0 <= codePoint && codePoint <= 0x20CF) ||
+                        // Unpaired surrogate
+                        (0xD800 <= codePoint && codePoint <= 0xDFFF)) {
+                    return STATE_UNKNOWN;
+                } else {
+                    // Unassigned LTR character
+                    return STATE_FALSE;
+                }
             default:
                 return STATE_UNKNOWN;
         }
@@ -181,14 +199,26 @@
 
     /**
      * Algorithm that uses the first strong directional character to determine the paragraph
-     * direction. This is the standard Unicode Bidirectional algorithm.
+     * direction. This is the standard Unicode Bidirectional Algorithm (steps P2 and P3), with the
+     * exception that if no strong character is found, UNKNOWN is returned.
      */
     private static class FirstStrong implements TextDirectionAlgorithm {
         @Override
         public int checkRtl(CharSequence cs, int start, int count) {
             int result = STATE_UNKNOWN;
-            for (int i = start, e = start + count; i < e && result == STATE_UNKNOWN; ++i) {
-                result = isRtlTextOrFormat(Character.getDirectionality(cs.charAt(i)));
+            int openIsolateCount = 0;
+            for (int cp, i = start, end = start + count;
+                    i < end && result == STATE_UNKNOWN;
+                    i += Character.charCount(cp)) {
+                cp = Character.codePointAt(cs, i);
+                if (0x2066 <= cp && cp <= 0x2068) { // Opening isolates
+                    openIsolateCount += 1;
+                } else if (cp == 0x2069) { // POP DIRECTIONAL ISOLATE (PDI)
+                    if (openIsolateCount > 0) openIsolateCount -= 1;
+                } else if (openIsolateCount == 0) {
+                    // Only consider the characters outside isolate pairs
+                    result = isRtlCodePoint(cp);
+                }
             }
             return result;
         }
@@ -200,9 +230,10 @@
     }
 
     /**
-     * Algorithm that uses the presence of any strong directional non-format
-     * character (e.g. excludes LRE, LRO, RLE, RLO) to determine the
-     * direction of text.
+     * Algorithm that uses the presence of any strong directional character of the type indicated
+     * in the constructor parameter to determine the direction of text.
+     *
+     * Characters inside isolate pairs are skipped.
      */
     private static class AnyStrong implements TextDirectionAlgorithm {
         private final boolean mLookForRtl;
@@ -210,22 +241,31 @@
         @Override
         public int checkRtl(CharSequence cs, int start, int count) {
             boolean haveUnlookedFor = false;
-            for (int i = start, e = start + count; i < e; ++i) {
-                switch (isRtlText(Character.getDirectionality(cs.charAt(i)))) {
-                    case STATE_TRUE:
-                        if (mLookForRtl) {
-                            return STATE_TRUE;
-                        }
-                        haveUnlookedFor = true;
-                        break;
-                    case STATE_FALSE:
-                        if (!mLookForRtl) {
-                            return STATE_FALSE;
-                        }
-                        haveUnlookedFor = true;
-                        break;
-                    default:
-                        break;
+            int openIsolateCount = 0;
+            for (int cp, i = start, end = start + count; i < end; i += Character.charCount(cp)) {
+                cp = Character.codePointAt(cs, i);
+                if (0x2066 <= cp && cp <= 0x2068) { // Opening isolates
+                    openIsolateCount += 1;
+                } else if (cp == 0x2069) { // POP DIRECTIONAL ISOLATE (PDI)
+                    if (openIsolateCount > 0) openIsolateCount -= 1;
+                } else if (openIsolateCount == 0) {
+                    // Only consider the characters outside isolate pairs
+                    switch (isRtlCodePoint(cp)) {
+                        case STATE_TRUE:
+                            if (mLookForRtl) {
+                                return STATE_TRUE;
+                            }
+                            haveUnlookedFor = true;
+                            break;
+                        case STATE_FALSE:
+                            if (!mLookForRtl) {
+                                return STATE_FALSE;
+                            }
+                            haveUnlookedFor = true;
+                            break;
+                        default:
+                            break;
+                    }
                 }
             }
             if (haveUnlookedFor) {
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java
index 07c1ec3..fe7571f 100644
--- a/core/java/android/text/method/BaseKeyListener.java
+++ b/core/java/android/text/method/BaseKeyListener.java
@@ -97,7 +97,7 @@
         // Delete a character.
         final int start = Selection.getSelectionEnd(content);
         final int end;
-        if (isForwardDelete || event.isShiftPressed() || isShiftActive) {
+        if (isForwardDelete) {
             end = TextUtils.getOffsetAfter(content, start);
         } else {
             end = TextUtils.getOffsetBefore(content, start);
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 71863b7..71e2251 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -170,6 +170,15 @@
     public static final int FLAG_PRESENTATION = 1 << 3;
 
     /**
+     * Display flag: Indicates that the contents of the display should not be scaled
+     * to fit the physical screen dimensions.  Used for development only to emulate
+     * devices with smaller physicals screens while preserving density.
+     *
+     * @hide
+     */
+    public static final int FLAG_SCALING_DISABLED = 1 << 30;
+
+    /**
      * Display type: Unknown display type.
      * @hide
      */
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index ecf45b4..243961c 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -538,6 +538,9 @@
         if ((flags & Display.FLAG_PRESENTATION) != 0) {
             result.append(", FLAG_PRESENTATION");
         }
+        if ((flags & Display.FLAG_SCALING_DISABLED) != 0) {
+            result.append(", FLAG_SCALING_DISABLED");
+        }
         return result.toString();
     }
 }
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index 2351548..b8544c6 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -149,12 +149,30 @@
     }
 
     /**
+     * The listener that is used to notify when a stylus button press occurs.
+     */
+    public interface OnStylusButtonPressListener {
+        /**
+         * Notified when a stylus button press occurs. This is when the stylus
+         * is touching the screen and the {@value MotionEvent#BUTTON_SECONDARY}
+         * is pressed.
+         *
+         * @param e The motion event that occurred during the stylus button
+         *            press.
+         * @return true if the event is consumed, else false
+         */
+        boolean onStylusButtonPress(MotionEvent e);
+    }
+
+    /**
      * A convenience class to extend when you only want to listen for a subset
      * of all the gestures. This implements all methods in the
-     * {@link OnGestureListener} and {@link OnDoubleTapListener} but does
-     * nothing and return {@code false} for all applicable methods.
+     * {@link OnGestureListener}, {@link OnDoubleTapListener}, and {@link OnStylusButtonPressListener}
+     * but does nothing and return {@code false} for all applicable methods.
      */
-    public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener {
+    public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener,
+            OnStylusButtonPressListener {
+
         public boolean onSingleTapUp(MotionEvent e) {
             return false;
         }
@@ -190,6 +208,10 @@
         public boolean onSingleTapConfirmed(MotionEvent e) {
             return false;
         }
+
+        public boolean onStylusButtonPress(MotionEvent e) {
+            return false;
+        }
     }
 
     private int mTouchSlopSquare;
@@ -211,10 +233,12 @@
     private final Handler mHandler;
     private final OnGestureListener mListener;
     private OnDoubleTapListener mDoubleTapListener;
+    private OnStylusButtonPressListener mStylusButtonListener;
 
     private boolean mStillDown;
     private boolean mDeferConfirmSingleTap;
     private boolean mInLongPress;
+    private boolean mInStylusButtonPress;
     private boolean mAlwaysInTapRegion;
     private boolean mAlwaysInBiggerTapRegion;
 
@@ -358,6 +382,9 @@
         if (listener instanceof OnDoubleTapListener) {
             setOnDoubleTapListener((OnDoubleTapListener) listener);
         }
+        if (listener instanceof OnStylusButtonPressListener) {
+            setOnStylusButtonPressListener((OnStylusButtonPressListener) listener);
+        }
         init(context);
     }
     
@@ -420,6 +447,19 @@
     }
 
     /**
+     * Sets the listener which will be called for stylus button related
+     * gestures.
+     *
+     * @param onStylusButtonPressListener the listener invoked for all the
+     *            callbacks, or null to stop listening for stylus button
+     *            gestures.
+     */
+    public void setOnStylusButtonPressListener(
+            OnStylusButtonPressListener onStylusButtonPressListener) {
+        mStylusButtonListener = onStylusButtonPressListener;
+    }
+
+    /**
      * Set whether longpress is enabled, if this is enabled when a user
      * presses and holds down you get a longpress event and nothing further.
      * If it's disabled the user can press and hold down and then later
@@ -512,7 +552,18 @@
             break;
 
         case MotionEvent.ACTION_DOWN:
-            if (mDoubleTapListener != null) {
+            if (mStylusButtonListener != null
+                    && ev.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS
+                    && (ev.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) {
+                if (mStylusButtonListener.onStylusButtonPress(ev)) {
+                    mInStylusButtonPress = true;
+                    handled = true;
+                    mHandler.removeMessages(LONG_PRESS);
+                    mHandler.removeMessages(TAP);
+                }
+            }
+
+            if (mDoubleTapListener != null && !mInStylusButtonPress) {
                 boolean hadTapMessage = mHandler.hasMessages(TAP);
                 if (hadTapMessage) mHandler.removeMessages(TAP);
                 if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null) && hadTapMessage &&
@@ -540,8 +591,8 @@
             mStillDown = true;
             mInLongPress = false;
             mDeferConfirmSingleTap = false;
-            
-            if (mIsLongpressEnabled) {
+
+            if (mIsLongpressEnabled && !mInStylusButtonPress) {
                 mHandler.removeMessages(LONG_PRESS);
                 mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime()
                         + TAP_TIMEOUT + LONGPRESS_TIMEOUT);
@@ -551,7 +602,17 @@
             break;
 
         case MotionEvent.ACTION_MOVE:
-            if (mInLongPress) {
+            if (mStylusButtonListener != null && !mInStylusButtonPress && !mInLongPress
+                    && ev.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS
+                    && (ev.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) {
+                if (mStylusButtonListener.onStylusButtonPress(ev)) {
+                    mInStylusButtonPress = true;
+                    handled = true;
+                    mHandler.removeMessages(LONG_PRESS);
+                    mHandler.removeMessages(TAP);
+                }
+            }
+            if (mInLongPress || mInStylusButtonPress) {
                 break;
             }
             final float scrollX = mLastFocusX - focusX;
@@ -591,6 +652,9 @@
             } else if (mInLongPress) {
                 mHandler.removeMessages(TAP);
                 mInLongPress = false;
+            } else if (mInStylusButtonPress) {
+                mHandler.removeMessages(TAP);
+                mInStylusButtonPress = false;
             } else if (mAlwaysInTapRegion) {
                 handled = mListener.onSingleTapUp(ev);
                 if (mDeferConfirmSingleTap && mDoubleTapListener != null) {
@@ -649,9 +713,8 @@
         mAlwaysInTapRegion = false;
         mAlwaysInBiggerTapRegion = false;
         mDeferConfirmSingleTap = false;
-        if (mInLongPress) {
-            mInLongPress = false;
-        }
+        mInLongPress = false;
+        mInStylusButtonPress = false;
     }
 
     private void cancelTaps() {
@@ -662,9 +725,8 @@
         mAlwaysInTapRegion = false;
         mAlwaysInBiggerTapRegion = false;
         mDeferConfirmSingleTap = false;
-        if (mInLongPress) {
-            mInLongPress = false;
-        }
+        mInLongPress = false;
+        mInStylusButtonPress = false;
     }
 
     private boolean isConsideredDoubleTap(MotionEvent firstDown, MotionEvent firstUp,
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index d6625c8..5994d4f 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -70,6 +70,7 @@
     int getBaseDisplayDensity(int displayId);
     void setForcedDisplayDensity(int displayId, int density);
     void clearForcedDisplayDensity(int displayId);
+    void setForcedDisplayScalingMode(int displayId, int mode); // 0 = auto, 1 = disable
 
     void setOverscan(int displayId, int left, int top, int right, int bottom);
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 25fa349..fa40e5f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -18173,7 +18173,8 @@
             // flag not set, setMeasuredDimension() was not invoked, we raise
             // an exception to warn the developer
             if ((mPrivateFlags & PFLAG_MEASURED_DIMENSION_SET) != PFLAG_MEASURED_DIMENSION_SET) {
-                throw new IllegalStateException("onMeasure() did not set the"
+                throw new IllegalStateException("View with id " + getId() + ": "
+                        + getClass().getName() + "#onMeasure() did not set the"
                         + " measured dimension by calling"
                         + " setMeasuredDimension()");
             }
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 98b895d..10724b0 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -6353,6 +6353,7 @@
     public void onStopNestedScroll(View child) {
         // Stop any recursive nested scrolling.
         stopNestedScroll();
+        mNestedScrollAxes = 0;
     }
 
     /**
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index e7b6238..c9d9a8c 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3116,6 +3116,25 @@
         }
     }
 
+    private boolean performStylusButtonPressAction(MotionEvent ev) {
+        if (ev.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS
+                && ev.isButtonPressed(MotionEvent.BUTTON_SECONDARY)
+                && mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL && mChoiceActionMode == null) {
+            final View child = getChildAt(mMotionPosition - mFirstPosition);
+            if (child != null) {
+                final int longPressPosition = mMotionPosition;
+                final long longPressId = mAdapter.getItemId(mMotionPosition);
+                if (performLongPress(child, longPressPosition, longPressId)) {
+                    mTouchMode = TOUCH_MODE_REST;
+                    setPressed(false);
+                    child.setPressed(false);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     boolean performLongPress(final View child,
             final int longPressPosition, final long longPressId) {
         // CHOICE_MODE_MULTIPLE_MODAL takes over long press.
@@ -3757,8 +3776,8 @@
         }
 
         if (mTouchMode == TOUCH_MODE_DOWN && mMotionPosition != INVALID_POSITION
-                && performButtonActionOnTouchDown(ev)) {
-            removeCallbacks(mPendingCheckForTap);
+                && (performButtonActionOnTouchDown(ev) || performStylusButtonPressAction(ev))) {
+                removeCallbacks(mPendingCheckForTap);
         }
     }
 
@@ -3800,6 +3819,11 @@
                     mTouchMode = TOUCH_MODE_DONE_WAITING;
                     updateSelectorState();
                 } else if (motionView != null) {
+                    if (performStylusButtonPressAction(ev)) {
+                        removeCallbacks(mPendingCheckForTap);
+                        removeCallbacks(mPendingCheckForLongPress);
+                    }
+
                     // Still within bounds, update the hotspot.
                     final float[] point = mTmpPoint;
                     point[0] = x;
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index d6f9f78..ff74c60 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -703,9 +703,9 @@
                     // fallthrough
                 case KeyEvent.KEYCODE_DPAD_RIGHT:
                     increment = isLayoutRtl() ? -increment : increment;
-                    int progress = getProgress() + increment;
-                    if (progress > 0 && progress < getMax()) {
-                        setProgress(progress, true);
+
+                    // Let progress bar handle clamping values.
+                    if (setProgress(getProgress() + increment, true)) {
                         onKeyChange();
                         return true;
                     }
@@ -729,10 +729,10 @@
         if (isEnabled()) {
             final int progress = getProgress();
             if (progress > 0) {
-                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+                info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD);
             }
             if (progress < getMax()) {
-                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+                info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD);
             }
         }
     }
@@ -743,29 +743,26 @@
         if (super.performAccessibilityActionInternal(action, arguments)) {
             return true;
         }
+
         if (!isEnabled()) {
             return false;
         }
-        final int progress = getProgress();
-        final int increment = Math.max(1, Math.round((float) getMax() / 5));
-        switch (action) {
-            case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
-                if (progress <= 0) {
-                    return false;
-                }
-                setProgress(progress - increment, true);
+
+        if (action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD
+                || action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) {
+            int increment = Math.max(1, Math.round((float) getMax() / 5));
+            if (action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) {
+                increment = -increment;
+            }
+
+            // Let progress bar handle clamping values.
+            if (setProgress(getProgress() + increment, true)) {
                 onKeyChange();
                 return true;
             }
-            case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
-                if (progress >= getMax()) {
-                    return false;
-                }
-                setProgress(progress + increment, true);
-                onKeyChange();
-                return true;
-            }
+            return false;
         }
+
         return false;
     }
 
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 24e9cbe..b59ae17 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -43,6 +43,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.AttributeSet;
+import android.util.MathUtils;
 import android.util.Pools.SynchronizedPool;
 import android.view.Gravity;
 import android.view.RemotableViewMethod;
@@ -1341,23 +1342,22 @@
     }
 
     @android.view.RemotableViewMethod
-    synchronized void setProgress(int progress, boolean fromUser) {
+    synchronized boolean setProgress(int progress, boolean fromUser) {
         if (mIndeterminate) {
-            return;
+            // Not applicable.
+            return false;
         }
 
-        if (progress < 0) {
-            progress = 0;
+        progress = MathUtils.constrain(progress, 0, mMax);
+
+        if (progress == mProgress) {
+            // No change from current.
+            return false;
         }
 
-        if (progress > mMax) {
-            progress = mMax;
-        }
-
-        if (progress != mProgress) {
-            mProgress = progress;
-            refreshProgress(R.id.progress, mProgress, fromUser);
-        }
+        mProgress = progress;
+        refreshProgress(R.id.progress, mProgress, fromUser);
+        return true;
     }
 
     /**
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 13877fb..ec57eba 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -517,13 +517,6 @@
         android:description="@string/permdesc_accessCoarseLocation"
         android:protectionLevel="dangerous" />
 
-    <!-- Allows an application to create mock location providers for testing. -->
-    <permission android:name="android.permission.ACCESS_MOCK_LOCATION"
-        android:permissionGroup="android.permission-group.LOCATION"
-        android:label="@string/permlab_accessMockLocation"
-        android:description="@string/permdesc_accessMockLocation"
-        android:protectionLevel="dangerous" />
-
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the device telephony                         -->
     <!-- ====================================================================== -->
@@ -734,12 +727,6 @@
     <!-- =============================================================== -->
     <eat-comment />
 
-
-    <!-- =============================================================== -->
-    <!-- Permissions for accessing the user dictionary                   -->
-    <!-- =============================================================== -->
-    <eat-comment />
-
     <!-- Used for permissions that provide access to the user
          calendar to create / view events.-->
     <permission-group android:name="android.permission-group.USER_DICTIONARY"
@@ -848,6 +835,12 @@
         android:protectionLevel="signature|system" />
     <uses-permission android:name="android.permission.LOCATION_HARDWARE"/>
 
+    <!-- Allows an application to create mock location providers for testing. -->
+    <permission android:name="android.permission.ACCESS_MOCK_LOCATION"
+        android:label="@string/permlab_accessMockLocation"
+        android:description="@string/permdesc_accessMockLocation"
+        android:protectionLevel="normal" />
+
     <!-- ======================================= -->
     <!-- Permissions for accessing networks -->
     <!-- ======================================= -->
@@ -2408,6 +2401,15 @@
                 android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
                 android:protectionLevel="signature" />
 
+    <!-- The system process that pulls carrier configuration from carrier apps will
+         have this permission. Carrier apps that provide
+         {@link android.service.carrier.CarrierConfigService} should require this
+         permission for clients binding to their service. -->
+    <permission android:name="android.permission.BIND_CARRIER_CONFIG_SERVICE"
+        android:label="@string/permlab_bindCarrierConfigService"
+        android:description="@string/permdesc_bindCarrierConfigService"
+        android:protectionLevel="signature|system" />
+
     <!-- The system process is explicitly the only one allowed to launch the
          confirmation UI for full backup/restore -->
     <uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
diff --git a/core/res/res/drawable-hdpi/ic_audio_bt_alpha.png b/core/res/res/drawable-hdpi/ic_audio_bt_alpha.png
deleted file mode 100644
index 597c384..0000000
--- a/core/res/res/drawable-hdpi/ic_audio_bt_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_audio_bt_mute_alpha.png b/core/res/res/drawable-hdpi/ic_audio_bt_mute_alpha.png
deleted file mode 100644
index 298db92..0000000
--- a/core/res/res/drawable-hdpi/ic_audio_bt_mute_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_audio_phone_am_alpha.png b/core/res/res/drawable-hdpi/ic_audio_phone_am_alpha.png
deleted file mode 100644
index 8a7d67a..0000000
--- a/core/res/res/drawable-hdpi/ic_audio_phone_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_bt_alpha.png b/core/res/res/drawable-mdpi/ic_audio_bt_alpha.png
deleted file mode 100644
index 282c643..0000000
--- a/core/res/res/drawable-mdpi/ic_audio_bt_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_bt_mute_alpha.png b/core/res/res/drawable-mdpi/ic_audio_bt_mute_alpha.png
deleted file mode 100644
index f734c1c..0000000
--- a/core/res/res/drawable-mdpi/ic_audio_bt_mute_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_phone_am_alpha.png b/core/res/res/drawable-mdpi/ic_audio_phone_am_alpha.png
deleted file mode 100644
index beda721..0000000
--- a/core/res/res/drawable-mdpi/ic_audio_phone_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_audio_bt_alpha.png b/core/res/res/drawable-xhdpi/ic_audio_bt_alpha.png
deleted file mode 100644
index b8aa083..0000000
--- a/core/res/res/drawable-xhdpi/ic_audio_bt_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_audio_bt_mute_alpha.png b/core/res/res/drawable-xhdpi/ic_audio_bt_mute_alpha.png
deleted file mode 100644
index 93a2481..0000000
--- a/core/res/res/drawable-xhdpi/ic_audio_bt_mute_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_audio_phone_am_alpha.png b/core/res/res/drawable-xhdpi/ic_audio_phone_am_alpha.png
deleted file mode 100644
index 2a04619..0000000
--- a/core/res/res/drawable-xhdpi/ic_audio_phone_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_bt_alpha.png b/core/res/res/drawable-xxhdpi/ic_audio_bt_alpha.png
deleted file mode 100755
index 140edac..0000000
--- a/core/res/res/drawable-xxhdpi/ic_audio_bt_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_bt_mute_alpha.png b/core/res/res/drawable-xxhdpi/ic_audio_bt_mute_alpha.png
deleted file mode 100644
index 97829b4..0000000
--- a/core/res/res/drawable-xxhdpi/ic_audio_bt_mute_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_phone_am_alpha.png b/core/res/res/drawable-xxhdpi/ic_audio_phone_am_alpha.png
deleted file mode 100644
index 1fd54a1..0000000
--- a/core/res/res/drawable-xxhdpi/ic_audio_phone_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/btn_colored_material.xml b/core/res/res/drawable/btn_colored_material.xml
new file mode 100644
index 0000000..81cbe39
--- /dev/null
+++ b/core/res/res/drawable/btn_colored_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+       android:insetLeft="@dimen/button_inset_horizontal_material"
+       android:insetTop="@dimen/button_inset_vertical_material"
+       android:insetRight="@dimen/button_inset_horizontal_material"
+       android:insetBottom="@dimen/button_inset_vertical_material">
+    <ripple android:color="?attr/colorControlHighlight">
+        <item>
+            <shape android:shape="rectangle"
+                   android:tint="@color/btn_colored_material">
+                <corners android:radius="@dimen/control_corner_material" />
+                <solid android:color="@color/white" />
+                <padding android:left="@dimen/button_padding_horizontal_material"
+                         android:top="@dimen/button_padding_vertical_material"
+                         android:right="@dimen/button_padding_horizontal_material"
+                         android:bottom="@dimen/button_padding_vertical_material" />
+            </shape>
+        </item>
+    </ripple>
+</inset>
diff --git a/core/res/res/drawable/ic_audio_bt.xml b/core/res/res/drawable/ic_audio_bt.xml
deleted file mode 100644
index 4f5af3d..0000000
--- a/core/res/res/drawable/ic_audio_bt.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_audio_bt_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_audio_bt_mute.xml b/core/res/res/drawable/ic_audio_bt_mute.xml
deleted file mode 100644
index d2004c0..0000000
--- a/core/res/res/drawable/ic_audio_bt_mute.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_audio_bt_mute_alpha"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_audio_phone.xml b/core/res/res/drawable/ic_audio_phone.xml
deleted file mode 100644
index 1bab863..0000000
--- a/core/res/res/drawable/ic_audio_phone.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright 2013, 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.
- */
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_audio_phone_am_alpha"
-    android:autoMirrored="true"
-    android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 0ac366d..12d7e60 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -501,9 +501,16 @@
     <attr name="excludeFromRecents" format="boolean" />
 
     <!-- Specify that an Activity should be shown over the lock screen and,
-         in a multiuser environment, across all users' windows -->
+         in a multiuser environment, across all users' windows.
+         @deprecated use {@link android.R.attr#showForAllUsers} instead. -->
     <attr name="showOnLockScreen" format="boolean" />
 
+    <!-- Specify that an Activity should be shown even if the current/foreground user
+         is different from the user of the Activity. This will also force the
+         <code>android.view.LayoutParams.FLAG_SHOW_WHEN_LOCKED</code> flag
+         to be set for all windows of this activity -->
+    <attr name="showForAllUsers" format="boolean" />
+
     <!-- Specify the authorities under which this content provider can be
          found.  Multiple authorities may be supplied by separating them
          with a semicolon.  Authority names should use a Java-style naming
@@ -1761,6 +1768,7 @@
         <attr name="alwaysRetainTaskState" />
         <attr name="stateNotNeeded" />
         <attr name="excludeFromRecents" />
+        <!-- @deprecated use {@link android.R.attr#showForAllUsers} instead. -->
         <attr name="showOnLockScreen" />
         <!-- Specify whether the activity is enabled or not (that is, can be instantiated by the system).
              It can also be specified for an application as a whole, in which case a value of "false"
@@ -1789,6 +1797,7 @@
         <attr name="resumeWhilePausing" />
         <attr name="resizeableActivity" />
         <attr name="lockTaskMode" />
+        <attr name="showForAllUsers" />
     </declare-styleable>
 
     <!-- The <code>activity-alias</code> tag declares a new
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 8336058..07f8c60 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -423,6 +423,9 @@
          point on the move. A value of 0 means no periodic scans will be used in the framework. -->
     <integer translatable="false" name="config_wifi_framework_scan_interval">300000</integer>
 
+    <!-- Integer indicating disconnect mode scan interval in milliseconds -->
+    <integer translatable="false" name="config_wifi_disconnected_scan_interval">15000</integer>
+
     <!-- Integer indicating associated partial scan interval in milliseconds -->
     <integer translatable="false" name="config_wifi_framework_associated_scan_interval">20000</integer>
 
@@ -472,6 +475,9 @@
     <!-- Wifi driver supports batched scan -->
     <bool translatable="false" name="config_wifi_batched_scan_supported">false</bool>
 
+    <!-- Wifi HAL supported PNO -->
+    <bool translatable="false" name="config_wifi_hal_pno_enable">false</bool>
+
     <!-- Idle Receive current for wifi radio. 0 by default-->
     <integer translatable="false" name="config_wifi_idle_receive_cur_ma">1</integer>
 
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 282c80b..208afb7d 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2641,6 +2641,7 @@
   <public type="style" name="Theme.Material.DayNight.Panel" />
   <public type="style" name="Theme.Material.Light.LightStatusBar" />
   <public type="style" name="ThemeOverlay.Material.Dialog" />
+  <public type="style" name="TextAppearance.Material.Widget.Button.Inverse" />
 
   <public type="id" name="pasteAsPlainText" />
   <public type="id" name="undo" />
@@ -2668,4 +2669,6 @@
 
   <public type="attr" name="leftIndents" />
   <public type="attr" name="rightIndents" />
+
+  <public type="attr" name="showForAllUsers" />
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 3d1fd7c..59366cc 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1323,6 +1323,108 @@
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_use_sip">Allows the app to make and receive SIP calls.</string>
 
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_register_sim_subscription">register new telecom SIM connections</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_register_sim_subscription">Allows the app to register new telecom SIM connections.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_register_call_provider">register new telecom connections</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_register_call_provider">Allows the app to register new telecom connections.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_connection_manager">manage telecom connections</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_connection_manager">Allows the app to manage telecom connections.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_bind_incall_service">interact with in-call screen</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bind_incall_service">Allows the app to control when and how the user sees the in-call screen.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_bind_connection_service">interact with telephony services</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bind_connection_service">Allows the app to interact with telephony services to make/receive calls.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_control_incall_experience">provide an in-call user experience</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_control_incall_experience">Allows the app to provide an in-call user experience.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_readNetworkUsageHistory">read historical network usage</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_readNetworkUsageHistory">Allows the app to read historical network usage for specific networks and apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_manageNetworkPolicy">manage network policy</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_manageNetworkPolicy">Allows the app to manage network policies and define app-specific rules.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_modifyNetworkAccounting">modify network usage accounting</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_modifyNetworkAccounting">Allows the app to modify how network usage is accounted against apps. Not for use by normal apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_accessNotifications">access notifications</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_accessNotifications">Allows the app to retrieve, examine, and clear notifications, including those posted by other apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_bindNotificationListenerService">bind to a notification listener service</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bindNotificationListenerService">Allows the holder to bind to the top-level interface of a notification listener service. Should never be needed for normal apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_bindConditionProviderService">bind to a condition provider service</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bindConditionProviderService">Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_bindDreamService">bind to a dream service</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bindDreamService">Allows the holder to bind to the top-level interface of a dream service. Should never be needed for normal apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_invokeCarrierSetup">invoke the carrier-provided configuration app</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_invokeCarrierSetup">Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_accessNetworkConditions">listen for observations on network conditions</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_accessNetworkConditions">Allows an application to listen for observations on network conditions. Should never be needed for normal apps.</string>
+
+    <string name="permlab_setInputCalibration">change input device calibration</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_setInputCalibration">Allows the app to modify the calibration parameters of the touch screen. Should never be needed for normal apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_accessDrmCertificates">access DRM certificates</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_accessDrmCertificates">Allows an application to provision and use DRM certficates. Should never be needed for normal apps.</string>
+
+    <string name="permlab_handoverStatus">Receive Android Beam transfer status</string>
+    <string name="permdesc_handoverStatus">Allows this application to receive information about current Android Beam transfers</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_removeDrmCertificates">remove DRM certificates</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_removeDrmCertificates">Allows an application to remove DRM certficates. Should never be needed for normal apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_bindCarrierMessagingService">bind to a carrier messaging service</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bindCarrierMessagingService">Allows the holder to bind to the top-level interface of a carrier messaging service. Should never be needed for normal apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_bindCarrierConfigService">bind to a carrier config service</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bindCarrierConfigService">Allows the holder to bind to a carrier config service. Should never be needed for normal apps.</string>
+
     <!-- Policy administration -->
 
     <!-- Title of policy access to limiting the user's password choices -->
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 88cac72..b874f63 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -289,6 +289,10 @@
     <style name="TextAppearance.Material.Widget"/>
     <style name="TextAppearance.Material.Widget.Button" parent="TextAppearance.Material.Button" />
 
+    <style name="TextAppearance.Material.Widget.Button.Inverse">
+        <item name="textColor">?attr/textColorPrimaryInverse</item>
+    </style>
+
     <style name="TextAppearance.Material.Widget.EditText">
         <item name="textColor">?attr/textColorPrimaryInverse</item>
         <item name="textColorHint">?attr/textColorHintInverse</item>
@@ -461,7 +465,8 @@
 
     <!-- Colored bordered ink button -->
     <style name="Widget.Material.Button.Colored">
-        <item name="backgroundTint">@color/btn_colored_material</item>
+        <item name="background">@drawable/btn_colored_material</item>
+        <item name="textAppearance">@style/TextAppearance.Material.Widget.Button.Inverse</item>
     </style>
 
     <!-- Small bordered ink button -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ac8216e..180b415 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -378,7 +378,9 @@
   <java-symbol type="integer" name="config_shortPressOnSleepBehavior" />
   <java-symbol type="integer" name="config_wifi_framework_scan_interval" />
   <java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
+  <java-symbol type="integer" name="config_wifi_disconnected_scan_interval" />
   <java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" />
+  <java-symbol type="bool" name="config_wifi_hal_pno_enable" />
   <java-symbol type="integer" name="db_connection_pool_size" />
   <java-symbol type="integer" name="db_journal_size_limit" />
   <java-symbol type="integer" name="db_wal_autocheckpoint" />
@@ -1163,13 +1165,10 @@
   <java-symbol type="drawable" name="expander_open_holo_dark" />
   <java-symbol type="drawable" name="ic_audio_alarm" />
   <java-symbol type="drawable" name="ic_audio_alarm_mute" />
-  <java-symbol type="drawable" name="ic_audio_bt" />
-  <java-symbol type="drawable" name="ic_audio_bt_mute" />
   <java-symbol type="drawable" name="ic_audio_media" />
   <java-symbol type="drawable" name="ic_audio_media_mute" />
   <java-symbol type="drawable" name="ic_audio_notification" />
   <java-symbol type="drawable" name="ic_audio_notification_mute" />
-  <java-symbol type="drawable" name="ic_audio_phone" />
   <java-symbol type="drawable" name="ic_audio_ring_notif" />
   <java-symbol type="drawable" name="ic_audio_ring_notif_mute" />
   <java-symbol type="drawable" name="ic_audio_ring_notif_vibrate" />
diff --git a/docs/html/guide/topics/manifest/application-element.jd b/docs/html/guide/topics/manifest/application-element.jd
index b5af9c3..d6ad656 100644
--- a/docs/html/guide/topics/manifest/application-element.jd
+++ b/docs/html/guide/topics/manifest/application-element.jd
@@ -32,6 +32,7 @@
              android:<a href="#testOnly">testOnly</a>=["true" | "false"]
              android:<a href="#theme">theme</a>="<i>resource or theme</i>"
              android:<a href="#uioptions">uiOptions</a>=["none" | "splitActionBarWhenNarrow"]
+             android:<a href="#usesCleartextTraffic">usesCleartextTraffic</a>=["true" | "false"]
              android:<a href="#vmSafeMode">vmSafeMode</a>=["true" | "false"] &gt;
     . . .
 &lt;/application&gt;</pre></dd>
@@ -446,6 +447,32 @@
   <p>This attribute was added in API level 14.</p>
 </dd>
 
+<dt><a name="usesCleartextTraffic"></a>{@code android:usesCleartextTraffic}</dt>
+<dd>Indicates whether the app intends to use cleartext network traffic, such as cleartext HTTP.
+The default value is {@code "true"}.
+
+<p>When the attribute is set to {@code "false"}, platform components (for example, HTTP and FTP
+stacks, {@link android.webkit.WebView}, {@link android.app.DownloadManager},
+{@link android.media.MediaPlayer}) will refuse the app's requests to use cleartext traffic.
+Third-party libraries are strongly encouraged to honor this setting as well. The key reason for
+avoiding cleartext traffic is the lack of confidentiality, authenticity, and protections against
+tampering: a network attacker can eavesdrop on transmitted data and also modify it without being
+detected.
+
+<p>This flag is honored on a best effort basis because it's impossible to prevent all cleartext
+traffic from Android applications given the level of access provided to them. For example, there's
+no expectation that the {@link java.net.Socket} API will honor this flag because it cannot
+determine whether its traffic is in cleartext. However, most network traffic from applications is
+handled by higher-level network stacks/components which can honor this flag by either reading it
+from {@link android.content.pm.ApplicationInfo#flags ApplicationInfo.flags} or
+{@link android.security.NetworkSecurityPolicy#isCleartextTrafficPermitted() NetworkSecurityPolicy.isCleartextTrafficPermitted()}.
+
+<p>During app development, StrictMode can be used to identify any cleartext traffic from the app: see
+{@link android.os.StrictMode.VmPolicy.Builder#detectCleartextNetwork() StrictMode.VmPolicy.Builder.detectCleartextNetwork()}.
+
+<p>This attribute was added in API level 23.</p>
+</dd>
+
 <dt><a name="vmSafeMode"></a>{@code android:vmSafeMode}</dt>
 <dd>Indicates whether the app would like the virtual machine (VM) to operate
 in safe mode. The default value is {@code "false"}.
diff --git a/docs/html/tools/help/hprof-conv.jd b/docs/html/tools/help/hprof-conv.jd
index f96def2..982f337 100644
--- a/docs/html/tools/help/hprof-conv.jd
+++ b/docs/html/tools/help/hprof-conv.jd
@@ -8,9 +8,13 @@
 generated by the Android SDK tools to a standard format so you
 can view the file in a profiling tool of your choice. </p>
 
-<pre> hprof-conv &lt;infile&gt; &lt;outfile&gt;</pre>
+<pre> hprof-conv [-z] &lt;infile&gt; &lt;outfile&gt;</pre>
 
 <p>
 You can use "-" for <code>&lt;infile&gt;</code> or <code>&lt;outfile&gt;</code>
 to specify stdin or stdout.
 </p>
+
+<p>
+You can use "-z" to filter out zygote allocations shared by all applications.
+</p>
diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/AndroidKeyStore.java
index 1c068be..c259c25 100644
--- a/keystore/java/android/security/AndroidKeyStore.java
+++ b/keystore/java/android/security/AndroidKeyStore.java
@@ -535,6 +535,12 @@
             args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
                     KeyStoreKeyProperties.UserAuthenticator.allToKeymaster(
                             params.getUserAuthenticators()));
+            long secureUserId = GateKeeper.getSecureUserId();
+            if (secureUserId == 0) {
+                throw new IllegalStateException("Secure lock screen must be enabled"
+                        + " to import keys requiring user authentication");
+            }
+            args.addLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, secureUserId);
         }
         if (params.isInvalidatedOnNewFingerprintEnrolled()) {
             // TODO: Add the invalidate on fingerprint enrolled constraint once Keymaster supports
diff --git a/keystore/java/android/security/GateKeeper.java b/keystore/java/android/security/GateKeeper.java
new file mode 100644
index 0000000..c9f06e9
--- /dev/null
+++ b/keystore/java/android/security/GateKeeper.java
@@ -0,0 +1,30 @@
+package android.security;
+
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.service.gatekeeper.IGateKeeperService;
+
+/**
+ * Convenience class for accessing the gatekeeper service.
+ *
+ * @hide
+ */
+public abstract class GateKeeper {
+
+    private GateKeeper() {}
+
+    public static IGateKeeperService getService() {
+        return IGateKeeperService.Stub.asInterface(
+                ServiceManager.getService("android.service.gatekeeper.IGateKeeperService"));
+    }
+
+    public static long getSecureUserId() throws IllegalStateException {
+        try {
+            return GateKeeper.getService().getSecureUserId(UserHandle.myUserId());
+        } catch (RemoteException e) {
+            throw new IllegalStateException(
+                    "Failed to obtain secure user ID from gatekeeper", e);
+        }
+    }
+}
diff --git a/keystore/java/android/security/KeyStoreCipherSpi.java b/keystore/java/android/security/KeyStoreCipherSpi.java
index 7bc6378..37e00b2 100644
--- a/keystore/java/android/security/KeyStoreCipherSpi.java
+++ b/keystore/java/android/security/KeyStoreCipherSpi.java
@@ -547,18 +547,12 @@
             if (mIvRequired) {
                 // IV is needed
                 if ((mIv == null) && (mEncrypting)) {
-                    // TODO: Switch to keymaster-generated IV code below once keymaster supports
-                    // that.
-                    // IV is needed but was not provided by the caller -- generate an IV.
-                    mIv = new byte[mBlockSizeBytes];
-                    SecureRandom rng = (mRng != null) ? mRng : new SecureRandom();
-                    rng.nextBytes(mIv);
-//                    // IV was not provided by the caller and thus will be generated by keymaster.
-//                    // Mix in some additional entropy from the provided SecureRandom.
-//                    if (mRng != null) {
-//                        mAdditionalEntropyForBegin = new byte[mBlockSizeBytes];
-//                        mRng.nextBytes(mAdditionalEntropyForBegin);
-//                    }
+                    // IV was not provided by the caller and thus will be generated by keymaster.
+                    // Mix in some additional entropy from the provided SecureRandom.
+                    if (mRng != null) {
+                        mAdditionalEntropyForBegin = new byte[mBlockSizeBytes];
+                        mRng.nextBytes(mAdditionalEntropyForBegin);
+                    }
                 }
             }
         }
diff --git a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
index 72c485a..d1abe12 100644
--- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
@@ -167,6 +167,12 @@
             args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
                     KeyStoreKeyProperties.UserAuthenticator.allToKeymaster(
                             spec.getUserAuthenticators()));
+            long secureUserId = GateKeeper.getSecureUserId();
+            if (secureUserId == 0) {
+                throw new IllegalStateException("Secure lock screen must be enabled"
+                        + " to generate keys requiring user authentication");
+            }
+            args.addLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, secureUserId);
         }
         if (spec.isInvalidatedOnNewFingerprintEnrolled()) {
             // TODO: Add the invalidate on fingerprint enrolled constraint once Keymaster supports
diff --git a/keystore/java/android/security/KeyStoreKeyProperties.java b/keystore/java/android/security/KeyStoreKeyProperties.java
index b1f330f..206103f 100644
--- a/keystore/java/android/security/KeyStoreKeyProperties.java
+++ b/keystore/java/android/security/KeyStoreKeyProperties.java
@@ -217,7 +217,7 @@
     }
 
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({Origin.GENERATED, Origin.IMPORTED})
+    @IntDef({Origin.GENERATED, Origin.IMPORTED, Origin.UNKNOWN})
     public @interface OriginEnum {}
 
     /**
@@ -233,14 +233,22 @@
         public static final int IMPORTED = 1 << 1;
 
         /**
+         * Origin of the key is unknown. This can occur only for keys backed by an old TEE
+         * implementation which does not record origin information.
+         */
+        public static final int UNKNOWN = 1 << 2;
+
+        /**
          * @hide
          */
         public static @OriginEnum int fromKeymaster(int origin) {
             switch (origin) {
-                case KeymasterDefs.KM_ORIGIN_HARDWARE:
+                case KeymasterDefs.KM_ORIGIN_GENERATED:
                     return GENERATED;
                 case KeymasterDefs.KM_ORIGIN_IMPORTED:
                     return IMPORTED;
+                case KeymasterDefs.KM_ORIGIN_UNKNOWN:
+                    return UNKNOWN;
                 default:
                     throw new IllegalArgumentException("Unknown origin: " + origin);
             }
diff --git a/media/java/android/media/DataSource.java b/media/java/android/media/DataSource.java
deleted file mode 100644
index 347bd5f..0000000
--- a/media/java/android/media/DataSource.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media;
-
-import java.io.Closeable;
-
-/**
- * An abstraction for a media data source, e.g. a file or an http stream
- * {@hide}
- */
-public interface DataSource extends Closeable {
-    /**
-     * Reads data from the data source at the requested position
-     *
-     * @param offset where in the source to read
-     * @param buffer the buffer to read the data into
-     * @param size how many bytes to read
-     * @return the number of bytes read, or -1 if there was an error
-     */
-    public int readAt(long offset, byte[] buffer, int size);
-
-    /**
-     * Gets the size of the data source.
-     *
-     * @return size of data source, or -1 if the length is unknown
-     */
-    public long getSize();
-}
diff --git a/media/java/android/media/MediaDataSource.java b/media/java/android/media/MediaDataSource.java
new file mode 100644
index 0000000..246c0ef
--- /dev/null
+++ b/media/java/android/media/MediaDataSource.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.media;
+
+import java.io.Closeable;
+
+/**
+ * For supplying media data to the framework. Implement this if your app has
+ * special requirements for the way media data is obtained.
+ *
+ * <p class="note">Methods of this interface may be called on multiple different
+ * threads. There will be a thread synchronization point between each call to ensure that
+ * modifications to the state of your MediaDataSource are visible to future calls. This means
+ * you don't need to do your own synchronization unless you're modifying the
+ * MediaDataSource from another thread while it's being used by the framework.</p>
+ */
+public interface MediaDataSource extends Closeable {
+    /**
+     * Called to request data from the given position.
+     *
+     * Implementations should should write up to {@code size} bytes into
+     * {@code buffer}, and return the number of bytes written.
+     *
+     * Return {@code 0} to indicate that {@code position} is at, or beyond, the
+     * end of the source.
+     *
+     * Return {@code -1} to indicate that a fatal error occurred. The failed
+     * read will not be retried, so transient errors should be handled
+     * internally.
+     *
+     * Throwing an exception from this method will have the same effect as
+     * returning {@code -1}.
+     *
+     * @param position the position in the data source to read from.
+     * @param buffer the buffer to read the data into.
+     * @param size the number of bytes to read.
+     * @return the number of bytes read, or -1 if there was an error.
+     */
+    public int readAt(long position, byte[] buffer, int size);
+
+    /**
+     * Called to get the size of the data source.
+     *
+     * @return the size of data source in bytes, or -1 if the size is unknown.
+     */
+    public long getSize();
+}
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index b23b540..b4acbc0 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -66,10 +66,11 @@
     }
 
     /**
-     * Sets the DataSource object to be used as the data source for this extractor
-     * {@hide}
+     * Sets the data source (MediaDataSource) to use.
+     *
+     * @param dataSource the MediaDataSource for the media you want to extract from
      */
-    public native final void setDataSource(DataSource source) throws IOException;
+    public native final void setDataSource(MediaDataSource dataSource) throws IllegalArgumentException, IOException;
 
     /**
      * Sets the data source as a content Uri.
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index 9aa8003..a3ff080 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -203,7 +203,20 @@
     }
 
     /**
-     * Call this method after setDataSource(). This method retrieves the 
+     * Sets the data source (MediaDataSource) to use.
+     *
+     * @param dataSource the MediaDataSource for the media you want to play
+     */
+    public void setDataSource(MediaDataSource dataSource)
+            throws IllegalArgumentException {
+        _setDataSource(dataSource);
+    }
+
+    private native void _setDataSource(MediaDataSource dataSource)
+          throws IllegalArgumentException;
+
+    /**
+     * Call this method after setDataSource(). This method retrieves the
      * meta data value associated with the keyCode.
      * 
      * The keyCode currently supported is listed below as METADATA_XXX
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 83954ae..cb80bc4 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -181,7 +181,8 @@
  *         {@link #setDataSource(FileDescriptor)}, or
  *         {@link #setDataSource(String)}, or
  *         {@link #setDataSource(Context, Uri)}, or
- *         {@link #setDataSource(FileDescriptor, long, long)} transfers a
+ *         {@link #setDataSource(FileDescriptor, long, long)}, or
+ *         {@link #setDataSource(MediaDataSource)} transfers a
  *         MediaPlayer object in the <em>Idle</em> state to the
  *         <em>Initialized</em> state.
  *         <ul>
@@ -1127,6 +1128,20 @@
             throws IOException, IllegalArgumentException, IllegalStateException;
 
     /**
+     * Sets the data source (MediaDataSource) to use.
+     *
+     * @param dataSource the MediaDataSource for the media you want to play
+     * @throws IllegalStateException if it is called in an invalid state
+     */
+    public void setDataSource(MediaDataSource dataSource)
+            throws IllegalArgumentException, IllegalStateException {
+        _setDataSource(dataSource);
+    }
+
+    private native void _setDataSource(MediaDataSource dataSource)
+          throws IllegalArgumentException, IllegalStateException;
+
+    /**
      * Prepares the player for playback, synchronously.
      *
      * After setting the datasource and the display surface, you need to either
diff --git a/media/java/android/media/MediaSync.java b/media/java/android/media/MediaSync.java
index 7350bd4..9446c0c 100644
--- a/media/java/android/media/MediaSync.java
+++ b/media/java/android/media/MediaSync.java
@@ -43,9 +43,9 @@
  * // MediaCodec videoDecoder = ...;
  * videoDecoder.configure(format, inputSurface, ...);
  * ...
- * sync.configureAudioTrack(audioTrack, nativeSampleRateInHz);
+ * sync.configureAudioTrack(audioTrack);
  * sync.setCallback(new MediaSync.Callback() {
- *     \@Override
+ *     {@literal @Override}
  *     public void onReturnAudioBuffer(MediaSync sync, ByteBuffer audioBuffer, int bufferIndex) {
  *         ...
  *     }
@@ -151,8 +151,6 @@
     private Handler mCallbackHandler = null;
     private MediaSync.Callback mCallback = null;
 
-    private int mNativeSampleRateInHz = 0;
-
     private Thread mAudioThread = null;
     // Created on mAudioThread when mAudioThread is started. When used on user thread, they should
     // be guarded by checking mAudioThread.
@@ -247,20 +245,17 @@
      * Configures the audio track for MediaSync.
      *
      * @param audioTrack Specify an AudioTrack through which to render the audio data.
-     * @throws IllegalArgumentException if the audioTrack has been released, or is invalid,
-     *     or nativeSampleRateInHz is invalid.
+     * @throws IllegalArgumentException if the audioTrack has been released, or is invalid.
      * @throws IllegalStateException if not in the Initialized state, or another audio track
      *     has already been configured.
      */
-    public void configureAudioTrack(AudioTrack audioTrack, int nativeSampleRateInHz) {
-        if (audioTrack != null && nativeSampleRateInHz <= 0) {
-            final String msg = "Native sample rate " + nativeSampleRateInHz + " is invalid";
-            throw new IllegalArgumentException(msg);
-        }
+    public void configureAudioTrack(AudioTrack audioTrack) {
+        // AudioTrack has sanity check for configured sample rate.
+        int nativeSampleRateInHz = (audioTrack == null ? 0 : audioTrack.getSampleRate());
+
         native_configureAudioTrack(audioTrack, nativeSampleRateInHz);
         mAudioTrack = audioTrack;
-        mNativeSampleRateInHz = nativeSampleRateInHz;
-        if (mAudioThread == null) {
+        if (audioTrack != null && mAudioThread == null) {
             createAudioThread();
         }
     }
@@ -349,8 +344,9 @@
 
         int status = AudioTrack.SUCCESS;
         if (mAudioTrack != null) {
-            int playbackSampleRate = (int)(rate * mNativeSampleRateInHz + 0.5);
-            rate = playbackSampleRate / (float)mNativeSampleRateInHz;
+            int nativeSampleRateInHz = mAudioTrack.getSampleRate();
+            int playbackSampleRate = (int)(rate * nativeSampleRateInHz + 0.5);
+            rate = playbackSampleRate / (float)nativeSampleRateInHz;
 
             try {
                 if (rate == 0.0) {
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 66d055a..c8464c7 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -7,6 +7,7 @@
     android_media_MediaCrypto.cpp \
     android_media_MediaCodec.cpp \
     android_media_MediaCodecList.cpp \
+    android_media_MediaDataSource.cpp \
     android_media_MediaDrm.cpp \
     android_media_MediaExtractor.cpp \
     android_media_MediaHTTPConnection.cpp \
diff --git a/media/jni/android_media_MediaDataSource.cpp b/media/jni/android_media_MediaDataSource.cpp
new file mode 100644
index 0000000..1e6d2af
--- /dev/null
+++ b/media/jni/android_media_MediaDataSource.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "JMediaDataSource-JNI"
+#include <utils/Log.h>
+
+#include "android_media_MediaDataSource.h"
+
+#include "android_runtime/AndroidRuntime.h"
+#include "android_runtime/Log.h"
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include <binder/MemoryDealer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+namespace android {
+
+JMediaDataSource::JMediaDataSource(JNIEnv* env, jobject source)
+    : mJavaObjStatus(OK), mSizeIsCached(false), mCachedSize(0), mMemory(NULL) {
+    mMediaDataSourceObj = env->NewGlobalRef(source);
+    CHECK(mMediaDataSourceObj != NULL);
+
+    ScopedLocalRef<jclass> mediaDataSourceClass(env, env->GetObjectClass(mMediaDataSourceObj));
+    CHECK(mediaDataSourceClass.get() != NULL);
+
+    mReadMethod = env->GetMethodID(mediaDataSourceClass.get(), "readAt", "(J[BI)I");
+    CHECK(mReadMethod != NULL);
+    mGetSizeMethod = env->GetMethodID(mediaDataSourceClass.get(), "getSize", "()J");
+    CHECK(mGetSizeMethod != NULL);
+    mCloseMethod = env->GetMethodID(mediaDataSourceClass.get(), "close", "()V");
+    CHECK(mCloseMethod != NULL);
+
+    ScopedLocalRef<jbyteArray> tmp(env, env->NewByteArray(kBufferSize));
+    mByteArrayObj = (jbyteArray)env->NewGlobalRef(tmp.get());
+    CHECK(mByteArrayObj != NULL);
+
+    sp<MemoryDealer> memoryDealer = new MemoryDealer(kBufferSize, "JMediaDataSource");
+    mMemory = memoryDealer->allocate(kBufferSize);
+    if (mMemory == NULL) {
+        ALOGE("Failed to allocate memory!");
+    }
+}
+
+JMediaDataSource::~JMediaDataSource() {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    env->DeleteGlobalRef(mMediaDataSourceObj);
+    env->DeleteGlobalRef(mByteArrayObj);
+}
+
+sp<IMemory> JMediaDataSource::getIMemory() {
+    Mutex::Autolock lock(mLock);
+    return mMemory;
+}
+
+ssize_t JMediaDataSource::readAt(off64_t offset, size_t size) {
+    Mutex::Autolock lock(mLock);
+
+    if (mJavaObjStatus != OK || mMemory == NULL) {
+        return -1;
+    }
+    if (size > kBufferSize) {
+        size = kBufferSize;
+    }
+
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    jint numread = env->CallIntMethod(mMediaDataSourceObj, mReadMethod,
+                                      (jlong)offset, mByteArrayObj, (jint)size);
+    if (env->ExceptionCheck()) {
+        ALOGW("An exception occurred in readAt()");
+        LOGW_EX(env);
+        env->ExceptionClear();
+        mJavaObjStatus = UNKNOWN_ERROR;
+        return -1;
+    }
+    if (numread < 0) {
+        ALOGW("An error occurred in readAt()");
+        mJavaObjStatus = UNKNOWN_ERROR;
+        return -1;
+    }
+    if ((size_t)numread > size) {
+        ALOGE("readAt read too many bytes.");
+        mJavaObjStatus = UNKNOWN_ERROR;
+        return -1;
+    }
+
+    ALOGV("readAt %lld / %zu => %d.", (long long)offset, size, numread);
+    env->GetByteArrayRegion(mByteArrayObj, 0, numread, (jbyte*)mMemory->pointer());
+    return numread;
+}
+
+status_t JMediaDataSource::getSize(off64_t* size) {
+    Mutex::Autolock lock(mLock);
+
+    if (mJavaObjStatus != OK) {
+        return UNKNOWN_ERROR;
+    }
+    if (mSizeIsCached) {
+        return mCachedSize;
+    }
+
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    *size = env->CallLongMethod(mMediaDataSourceObj, mGetSizeMethod);
+    if (env->ExceptionCheck()) {
+        ALOGW("An exception occurred in getSize()");
+        LOGW_EX(env);
+        env->ExceptionClear();
+        // After returning an error, size shouldn't be used by callers.
+        *size = UNKNOWN_ERROR;
+        mJavaObjStatus = UNKNOWN_ERROR;
+        return UNKNOWN_ERROR;
+    }
+
+    // The minimum size should be -1, which indicates unknown size.
+    if (*size < 0) {
+        *size = -1;
+    }
+
+    mCachedSize = *size;
+    mSizeIsCached = true;
+    return OK;
+}
+
+void JMediaDataSource::close() {
+    Mutex::Autolock lock(mLock);
+
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    env->CallVoidMethod(mMediaDataSourceObj, mCloseMethod);
+    // The closed state is effectively the same as an error state.
+    mJavaObjStatus = UNKNOWN_ERROR;
+}
+
+}  // namespace android
diff --git a/media/jni/android_media_MediaDataSource.h b/media/jni/android_media_MediaDataSource.h
new file mode 100644
index 0000000..2bc237e
--- /dev/null
+++ b/media/jni/android_media_MediaDataSource.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef _ANDROID_MEDIA_MEDIADATASOURCE_H_
+#define _ANDROID_MEDIA_MEDIADATASOURCE_H_
+
+#include "jni.h"
+
+#include <media/IDataSource.h>
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/Errors.h>
+#include <utils/Mutex.h>
+
+namespace android {
+
+// The native counterpart to a Java android.media.MediaDataSource. It inherits from
+// IDataSource so that it can be accessed remotely.
+//
+// If the java DataSource returns an error or throws an exception it
+// will be considered to be in a broken state, and the only further call this
+// will make is to close().
+class JMediaDataSource : public BnDataSource {
+public:
+    enum {
+        kBufferSize = 64 * 1024,
+    };
+
+    JMediaDataSource(JNIEnv *env, jobject source);
+    virtual ~JMediaDataSource();
+
+    virtual sp<IMemory> getIMemory();
+    virtual ssize_t readAt(off64_t offset, size_t size);
+    virtual status_t getSize(off64_t* size);
+    virtual void close();
+
+private:
+    // Protect all member variables with mLock because this object will be
+    // accessed on different binder worker threads.
+    Mutex mLock;
+
+    // The status of the java DataSource. Set to OK unless an error occurred or
+    // close() was called.
+    status_t mJavaObjStatus;
+    // Only call the java getSize() once so the app can't change the size on us.
+    bool mSizeIsCached;
+    off64_t mCachedSize;
+    sp<IMemory> mMemory;
+
+    jobject mMediaDataSourceObj;
+    jmethodID mReadMethod;
+    jmethodID mGetSizeMethod;
+    jmethodID mCloseMethod;
+    jbyteArray mByteArrayObj;
+
+    DISALLOW_EVIL_CONSTRUCTORS(JMediaDataSource);
+};
+
+}  // namespace android
+
+#endif  // _ANDROID_MEDIA_MEDIADATASOURCE_H_
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index c0795b6..b6b7a80 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -25,6 +25,7 @@
 #include "android_runtime/Log.h"
 #include "jni.h"
 #include "JNIHelp.h"
+#include "android_media_MediaDataSource.h"
 
 #include <media/IMediaHTTPService.h>
 #include <media/hardware/CryptoAPI.h>
@@ -50,74 +51,6 @@
 
 static fields_t gFields;
 
-class JavaDataSourceBridge : public DataSource {
-    jmethodID mReadMethod;
-    jmethodID mGetSizeMethod;
-    jmethodID mCloseMethod;
-    jobject   mDataSource;
- public:
-    JavaDataSourceBridge(JNIEnv *env, jobject source) {
-        mDataSource = env->NewGlobalRef(source);
-
-        jclass datasourceclass = env->GetObjectClass(mDataSource);
-        CHECK(datasourceclass != NULL);
-
-        mReadMethod = env->GetMethodID(datasourceclass, "readAt", "(J[BI)I");
-        CHECK(mReadMethod != NULL);
-
-        mGetSizeMethod = env->GetMethodID(datasourceclass, "getSize", "()J");
-        CHECK(mGetSizeMethod != NULL);
-
-        mCloseMethod = env->GetMethodID(datasourceclass, "close", "()V");
-        CHECK(mCloseMethod != NULL);
-    }
-
-    ~JavaDataSourceBridge() {
-        JNIEnv *env = AndroidRuntime::getJNIEnv();
-        env->CallVoidMethod(mDataSource, mCloseMethod);
-        env->DeleteGlobalRef(mDataSource);
-    }
-
-    virtual status_t initCheck() const {
-        return OK;
-    }
-
-    virtual ssize_t readAt(off64_t offset, void* buffer, size_t size) {
-        JNIEnv *env = AndroidRuntime::getJNIEnv();
-
-        // XXX could optimize this by reusing the same array
-        jbyteArray byteArrayObj = env->NewByteArray(size);
-        env->DeleteLocalRef(env->GetObjectClass(mDataSource));
-        env->DeleteLocalRef(env->GetObjectClass(byteArrayObj));
-        ssize_t numread = env->CallIntMethod(mDataSource, mReadMethod, offset, byteArrayObj, (jint)size);
-        env->GetByteArrayRegion(byteArrayObj, 0, size, (jbyte*) buffer);
-        env->DeleteLocalRef(byteArrayObj);
-        if (env->ExceptionCheck()) {
-            ALOGW("Exception occurred while reading %zu at %lld", size, (long long)offset);
-            LOGW_EX(env);
-            env->ExceptionClear();
-            return -1;
-        }
-        return numread;
-    }
-
-    virtual status_t getSize(off64_t *size) {
-        JNIEnv *env = AndroidRuntime::getJNIEnv();
-
-        CHECK(size != NULL);
-
-        int64_t len = env->CallLongMethod(mDataSource, mGetSizeMethod);
-        if (len < 0) {
-            *size = ERROR_UNSUPPORTED;
-        } else {
-            *size = len;
-        }
-        return OK;
-    }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
 JMediaExtractor::JMediaExtractor(JNIEnv *env, jobject thiz)
     : mClass(NULL),
       mObject(NULL) {
@@ -777,7 +710,8 @@
         return;
     }
 
-    sp<JavaDataSourceBridge> bridge = new JavaDataSourceBridge(env, callbackObj);
+    sp<DataSource> bridge =
+        DataSource::CreateFromIDataSource(new JMediaDataSource(env, callbackObj));
     status_t err = extractor->setDataSource(bridge);
 
     if (err != OK) {
@@ -881,7 +815,7 @@
     { "setDataSource", "(Ljava/io/FileDescriptor;JJ)V",
       (void *)android_media_MediaExtractor_setDataSourceFd },
 
-    { "setDataSource", "(Landroid/media/DataSource;)V",
+    { "setDataSource", "(Landroid/media/MediaDataSource;)V",
       (void *)android_media_MediaExtractor_setDataSourceCallback },
 
     { "getCachedDuration", "()J",
diff --git a/media/jni/android_media_MediaHTTPConnection.cpp b/media/jni/android_media_MediaHTTPConnection.cpp
index 7226ef5..393003d 100644
--- a/media/jni/android_media_MediaHTTPConnection.cpp
+++ b/media/jni/android_media_MediaHTTPConnection.cpp
@@ -134,7 +134,6 @@
 static jint android_media_MediaHTTPConnection_native_readAt(
         JNIEnv *env, jobject thiz, jlong offset, jint size) {
     sp<JMediaHTTPConnection> conn = getObject(env, thiz);
-
     if (size > JMediaHTTPConnection::kBufferSize) {
         size = JMediaHTTPConnection::kBufferSize;
     }
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index c6fa379..59fb6d6 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -30,6 +30,7 @@
 #include "jni.h"
 #include "JNIHelp.h"
 #include "android_runtime/AndroidRuntime.h"
+#include "android_media_MediaDataSource.h"
 #include "android_media_Utils.h"
 #include "android_util_Binder.h"
 
@@ -171,6 +172,23 @@
     process_media_retriever_call(env, retriever->setDataSource(fd, offset, length), "java/lang/RuntimeException", "setDataSource failed");
 }
 
+static void android_media_MediaMetadataRetriever_setDataSourceCallback(JNIEnv *env, jobject thiz, jobject dataSource)
+{
+    ALOGV("setDataSourceCallback");
+    MediaMetadataRetriever* retriever = getRetriever(env, thiz);
+    if (retriever == 0) {
+        jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
+        return;
+    }
+    if (dataSource == NULL) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+        return;
+    }
+
+    sp<IDataSource> callbackDataSource = new JMediaDataSource(env, dataSource);
+    process_media_retriever_call(env, retriever->setDataSource(callbackDataSource), "java/lang/RuntimeException", "setDataSourceCallback failed");
+}
+
 template<typename T>
 static void rotate0(T* dst, const T* src, size_t width, size_t height)
 {
@@ -457,6 +475,7 @@
         },
 
         {"setDataSource",   "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaMetadataRetriever_setDataSourceFD},
+        {"_setDataSource",   "(Landroid/media/MediaDataSource;)V", (void *)android_media_MediaMetadataRetriever_setDataSourceCallback},
         {"_getFrameAtTime", "(JI)Landroid/graphics/Bitmap;", (void *)android_media_MediaMetadataRetriever_getFrameAtTime},
         {"extractMetadata", "(I)Ljava/lang/String;", (void *)android_media_MediaMetadataRetriever_extractMetadata},
         {"getEmbeddedPicture", "(I)[B", (void *)android_media_MediaMetadataRetriever_getEmbeddedPicture},
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 3e41716..c247220 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -36,6 +36,7 @@
 #include "utils/Errors.h"  // for status_t
 #include "utils/KeyedVector.h"
 #include "utils/String8.h"
+#include "android_media_MediaDataSource.h"
 #include "android_media_Utils.h"
 
 #include "android_os_Parcel.h"
@@ -251,6 +252,23 @@
     process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." );
 }
 
+static void
+android_media_MediaPlayer_setDataSourceCallback(JNIEnv *env, jobject thiz, jobject dataSource)
+{
+    sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
+    if (mp == NULL ) {
+        jniThrowException(env, "java/lang/IllegalStateException", NULL);
+        return;
+    }
+
+    if (dataSource == NULL) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+        return;
+    }
+    sp<IDataSource> callbackDataSource = new JMediaDataSource(env, dataSource);
+    process_media_player_call(env, thiz, mp->setDataSource(callbackDataSource), "java/lang/RuntimeException", "setDataSourceCallback failed." );
+}
+
 static sp<IGraphicBufferProducer>
 getVideoSurfaceTexture(JNIEnv* env, jobject thiz) {
     IGraphicBufferProducer * const p = (IGraphicBufferProducer*)env->GetLongField(thiz, fields.surface_texture);
@@ -871,7 +889,8 @@
         (void *)android_media_MediaPlayer_setDataSourceAndHeaders
     },
 
-    {"_setDataSource",       "(Ljava/io/FileDescriptor;JJ)V",    (void *)android_media_MediaPlayer_setDataSourceFD},
+    {"_setDataSource",      "(Ljava/io/FileDescriptor;JJ)V",    (void *)android_media_MediaPlayer_setDataSourceFD},
+    {"_setDataSource",      "(Landroid/media/MediaDataSource;)V",(void *)android_media_MediaPlayer_setDataSourceCallback },
     {"_setVideoSurface",    "(Landroid/view/Surface;)V",        (void *)android_media_MediaPlayer_setVideoSurface},
     {"_prepare",            "()V",                              (void *)android_media_MediaPlayer_prepare},
     {"prepareAsync",        "()V",                              (void *)android_media_MediaPlayer_prepareAsync},
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CopyService.java b/packages/DocumentsUI/src/com/android/documentsui/CopyService.java
index d2ef3d7..a9f03b6 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CopyService.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CopyService.java
@@ -191,7 +191,8 @@
         cancelIntent.putExtra(EXTRA_CANCEL, mJobId);
         mProgressBuilder.addAction(R.drawable.ic_cab_cancel,
                 getString(android.R.string.cancel), PendingIntent.getService(this, 0,
-                        cancelIntent, PendingIntent.FLAG_ONE_SHOT));
+                        cancelIntent,
+                        PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT));
 
         // Send an initial progress notification.
         mProgressBuilder.setProgress(0, 0, true); // Indeterminate progress while setting up.
diff --git a/packages/SystemUI/res/drawable/ic_audio_alarm.xml b/packages/SystemUI/res/drawable/ic_audio_alarm.xml
deleted file mode 100644
index 91010a3..0000000
--- a/packages/SystemUI/res/drawable/ic_audio_alarm.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="28.0dp"
-        android:height="28.0dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:fillColor="#ffffffff"
-        android:pathData="M44.0,11.44l-9.19,-7.71 -2.57,3.06 9.19,7.71 2.57,-3.06zm-28.24,-4.66l-2.57,-3.06 -9.19,7.71 2.57,3.06 9.19,-7.71zm9.24,9.22l-3.0,0.0l0.0,12.0l9.49,5.71 1.51,-2.47 -8.0,-4.74l0.0,-10.5zm-1.01,-8.0c-9.95,0.0 -17.99,8.06 -17.99,18.0s8.04,18.0 17.99,18.0 18.01,-8.06 18.01,-18.0 -8.06,-18.0 -18.01,-18.0zm0.01,32.0c-7.73,0.0 -14.0,-6.27 -14.0,-14.0s6.27,-14.0 14.0,-14.0 14.0,6.27 14.0,14.0 -6.26,14.0 -14.0,14.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_audio_alarm_mute.xml b/packages/SystemUI/res/drawable/ic_audio_alarm_mute.xml
deleted file mode 100644
index dd124d7..0000000
--- a/packages/SystemUI/res/drawable/ic_audio_alarm_mute.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="28.0dp"
-        android:height="28.0dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:fillColor="#ffffffff"
-        android:pathData="M24.0,12.0c7.73,0.0 14.0,6.27 14.0,14.0 0.0,1.69 -0.31,3.3 -0.86,4.8l3.04,3.04c1.16,-2.37 1.82,-5.03 1.82,-7.84 0.0,-9.94 -8.06,-18.0 -18.01,-18.0 -2.81,0.0 -5.46,0.66 -7.84,1.81l3.05,3.05c1.5,-0.55 3.11,-0.86 4.8,-0.86zm20.0,-0.56l-9.19,-7.71 -2.57,3.06 9.19,7.71 2.57,-3.06zm-38.16,-6.85l-2.55,2.54 2.66,2.66 -2.22,1.86 2.84,2.84 2.22,-1.86 1.6,1.6c-2.73,3.16 -4.39,7.27 -4.39,11.77 0.0,9.94 8.04,18.0 17.99,18.0 4.51,0.0 8.62,-1.67 11.77,-4.4l4.4,4.4 2.54,-2.55 -34.91,-34.91 -1.95,-1.95zm27.1,32.19c-2.43,2.01 -5.54,3.22 -8.94,3.22 -7.73,0.0 -14.0,-6.27 -14.0,-14.0 0.0,-3.4 1.21,-6.51 3.22,-8.94l19.72,19.72zm-16.91,-30.23l-2.84,-2.84 -1.7,1.43 2.84,2.84 1.7,-1.43z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_audio_bt.xml b/packages/SystemUI/res/drawable/ic_audio_bt.xml
deleted file mode 100644
index c0da519..0000000
--- a/packages/SystemUI/res/drawable/ic_audio_bt.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="28dp"
-        android:height="28dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_audio_bt_mute.xml b/packages/SystemUI/res/drawable/ic_audio_bt_mute.xml
deleted file mode 100644
index 718eee5..0000000
--- a/packages/SystemUI/res/drawable/ic_audio_bt_mute.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="28dp"
-        android:height="28dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M26.0,11.8l3.8,3.8l-3.2,3.2l2.8,2.8l6.0,-6.0L24.0,4.2l-2.0,0.0l0.0,10.1l4.0,4.0L26.0,11.8zM10.8,8.2L8.0,11.0l13.2,13.2L10.0,35.3l2.8,2.8L22.0,29.0l0.0,15.2l2.0,0.0l8.6,-8.6l4.6,4.6l2.8,-2.8L10.8,8.2zM26.0,36.5L26.0,29.0l3.8,3.8L26.0,36.5z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_audio_remote.xml b/packages/SystemUI/res/drawable/ic_audio_remote.xml
deleted file mode 100644
index 762878b..0000000
--- a/packages/SystemUI/res/drawable/ic_audio_remote.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="28dp"
-        android:height="28dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM38.0,14.0L10.0,14.0l0.0,3.3c7.9,2.6 14.2,8.8 16.7,16.7L38.0,34.0L38.0,14.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0zM42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_audio_vol.xml b/packages/SystemUI/res/drawable/ic_audio_vol.xml
deleted file mode 100644
index 587ea89..0000000
--- a/packages/SystemUI/res/drawable/ic_audio_vol.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="28.0dp"
-        android:height="28.0dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:fillColor="#ffffffff"
-        android:pathData="M6.0,18.0l0.0,12.0l8.0,0.0l10.0,10.0L24.0,8.0L14.0,18.0L6.0,18.0zm27.0,6.0c0.0,-3.53 -2.04,-6.58 -5.0,-8.05l0.0,16.11c2.96,-1.48 5.0,-4.53 5.0,-8.06zM28.0,6.46l0.0,4.13c5.78,1.72 10.0,7.07 10.0,13.41s-4.22,11.69 -10.0,13.41l0.0,4.13c8.01,-1.82 14.0,-8.97 14.0,-17.54S36.01,8.28 28.0,6.46z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_audio_vol_mute.xml b/packages/SystemUI/res/drawable/ic_audio_vol_mute.xml
deleted file mode 100644
index 8a7c7ec..0000000
--- a/packages/SystemUI/res/drawable/ic_audio_vol_mute.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="28.0dp"
-        android:height="28.0dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:fillColor="#ffffffff"
-        android:pathData="M33.0,24.0c0.0,-3.53 -2.04,-6.58 -5.0,-8.05l0.0,4.42l4.91,4.91c0.06,-0.42 0.09,-0.85 0.09,-1.28zm5.0,0.0c0.0,1.88 -0.41,3.65 -1.08,5.28l3.03,3.03C41.25,29.82 42.0,27.0 42.0,24.0c0.0,-8.56 -5.99,-15.72 -14.0,-17.54l0.0,4.13c5.78,1.72 10.0,7.07 10.0,13.41zM8.55,6.0L6.0,8.55 15.45,18.0L6.0,18.0l0.0,12.0l8.0,0.0l10.0,10.0L24.0,26.55l8.51,8.51c-1.34,1.03 -2.85,1.86 -4.51,2.36l0.0,4.13c2.75,-0.63 5.26,-1.89 7.37,-3.62L39.45,42.0 42.0,39.45l-18.0,-18.0L8.55,6.0zM24.0,8.0l-4.18,4.18L24.0,16.36L24.0,8.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_ringer_audible.xml b/packages/SystemUI/res/drawable/ic_ringer_audible.xml
deleted file mode 100644
index fd50617..0000000
--- a/packages/SystemUI/res/drawable/ic_ringer_audible.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="28dp"
-        android:height="28dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,16.0l0.0,-5.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0L18.0,16.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_ringer_mute.xml b/packages/SystemUI/res/drawable/ic_ringer_mute.xml
deleted file mode 100644
index b29a139..0000000
--- a/packages/SystemUI/res/drawable/ic_ringer_mute.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="28dp"
-        android:height="28dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M23.000000,44.000000c2.200000,0.000000 4.000000,-1.800000 4.000000,-4.000000l-8.000000,0.000000C19.000000,42.200001 20.799999,44.000000 23.000000,44.000000zM36.000000,21.000000c0.000000,-6.100000 -4.300000,-11.300000 -10.000000,-12.600000L26.000000,7.000000c0.000000,-1.700000 -1.300000,-3.000000 -3.000000,-3.000000c-1.700000,0.000000 -3.000000,1.300000 -3.000000,3.000000l0.000000,1.400000c-1.000000,0.200000 -2.000000,0.600000 -2.900000,1.100000L36.000000,28.400000L36.000000,21.000000zM35.500000,38.000000l4.000000,4.000000l2.500000,-2.500000L8.500000,6.000000L6.000000,8.500000l5.800000,5.800000C10.700000,16.299999 10.000000,18.600000 10.000000,21.000000l0.000000,11.000000l-4.000000,4.000000l0.000000,2.000000L35.500000,38.000000z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_ringer_vibrate.xml
deleted file mode 100644
index 4bff96d..0000000
--- a/packages/SystemUI/res/drawable/ic_ringer_vibrate.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="28dp"
-        android:height="28dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M0.0,15.0l2.0,0.0L2.0,9.0L0.0,9.0L0.0,15.0zM3.0,17.0l2.0,0.0L5.0,7.0L3.0,7.0L3.0,17.0zM22.0,9.0l0.0,6.0l2.0,0.0L24.0,9.0L22.0,9.0zM19.0,17.0l2.0,0.0L21.0,7.0l-2.0,0.0L19.0,17.0zM16.5,3.0l-9.0,0.0C6.7,3.0 6.0,3.7 6.0,4.5l0.0,15.0C6.0,20.3 6.7,21.0 7.5,21.0l9.0,0.0c0.8,0.0 1.5,-0.7 1.5,-1.5l0.0,-15.0C18.0,3.7 17.3,3.0 16.5,3.0zM16.0,19.0L8.0,19.0L8.0,5.0l8.0,0.0L16.0,19.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/layout/volume_panel.xml b/packages/SystemUI/res/layout/volume_panel.xml
deleted file mode 100644
index 4d8aaa7..0000000
--- a/packages/SystemUI/res/layout/volume_panel.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2007 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.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/visible_panel"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical" >
-
-    <FrameLayout
-        android:id="@+id/slider_panel"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:background="@color/system_secondary_color"
-        android:paddingTop="8dp"
-        android:paddingLeft="8dp"
-        android:paddingRight="8dp"
-        android:clipChildren="false" />
-
-     <include
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        layout="@layout/zen_mode_panel" />
-
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_panel_dialog.xml b/packages/SystemUI/res/layout/volume_panel_dialog.xml
deleted file mode 100644
index 700102f..0000000
--- a/packages/SystemUI/res/layout/volume_panel_dialog.xml
+++ /dev/null
@@ -1,27 +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.
--->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_marginBottom="@dimen/volume_panel_z"
-    android:layout_marginLeft="@dimen/notification_side_padding"
-    android:layout_marginRight="@dimen/notification_side_padding"
-    android:background="@drawable/qs_background_primary"
-    android:translationZ="@dimen/volume_panel_z" >
-
-    <include layout="@layout/volume_panel" />
-
-</FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_panel_item.xml b/packages/SystemUI/res/layout/volume_panel_item.xml
deleted file mode 100644
index dad68c3..0000000
--- a/packages/SystemUI/res/layout/volume_panel_item.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2011 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:clipChildren="false"
-    android:gravity="start|center_vertical"
-    android:orientation="horizontal" >
-
-    <ImageView
-        android:id="@+id/stream_icon"
-        android:layout_width="48dp"
-        android:layout_height="48dp"
-        android:scaleType="center"
-        android:background="@drawable/btn_borderless_rect"
-        android:contentDescription="@null" />
-
-    <FrameLayout
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_weight="1" >
-
-        <TextView
-            android:id="@+id/suppressor"
-            android:visibility="gone"
-            android:textAppearance="@style/TextAppearance.QS.VolumeSuppressor"
-            android:paddingStart="8dp"
-            android:paddingEnd="8dp"
-            android:singleLine="true"
-            android:ellipsize="end"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
-
-        <SeekBar
-            android:id="@+id/seekbar"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:paddingBottom="0dp"
-            android:paddingEnd="16dp"
-            android:paddingStart="8dp"
-            android:paddingTop="0dp" />
-
-    </FrameLayout>
-
-    <View
-        android:id="@+id/divider"
-        android:layout_width="1dp"
-        android:layout_height="32dp"
-        android:layout_marginLeft="8dp"
-        android:layout_marginRight="8dp"
-        android:background="@color/volume_panel_divider" />
-
-    <ImageView
-        android:id="@+id/secondary_icon"
-        android:layout_width="48dp"
-        android:layout_height="48dp"
-        android:scaleType="center"
-        android:background="@drawable/btn_borderless_rect"
-        android:contentDescription="@null" />
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index d829f0e..b676bce 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -126,7 +126,7 @@
             android:lineSpacingMultiplier="1.20029"
             android:layout_toStartOf="@id/zen_introduction_confirm"
             android:text="@string/zen_priority_introduction"
-            android:textAppearance="@style/TextAppearance.QS.VolumeSuppressor" />
+            android:textAppearance="@style/TextAppearance.QS.Introduction" />
 
         <TextView
             android:id="@+id/zen_introduction_customize"
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 88d1769..1f1455a 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -129,7 +129,6 @@
 
     <color name="segmented_button_selected">#FFFFFFFF</color>
     <color name="segmented_button_unselected">#B3B0BEC5</color><!-- 70% blue grey 200 -->
-    <color name="volume_panel_divider">#1FFFFFFF</color><!-- 12% white -->
 
     <color name="dark_mode_icon_color_single_tone">#99000000</color>
     <color name="dark_mode_icon_color_dual_tone_background">#3d000000</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 88bf58a..2e44547 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -276,9 +276,6 @@
     <!-- Doze: alpha to apply to small icons when dozing -->
     <integer name="doze_small_icon_alpha">222</integer><!-- 87% of 0xff -->
 
-    <!-- Volume: time to delay dismissing the volume panel after a click is performed -->
-    <integer name="volume_panel_dismiss_delay">200</integer>
-
     <!-- Hotspot tile: number of days to show after feature is used. -->
     <integer name="days_to_show_hotspot_tile">30</integer>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 9e084a0..7e50454 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -344,15 +344,6 @@
     <!-- The chevron padding to the circle when hinting -->
     <dimen name="hint_chevron_circle_padding">16dp</dimen>
 
-    <!-- Volume panel dialog y offset -->
-    <dimen name="volume_panel_top">0dp</dimen>
-
-    <!-- Volume panel dialog width -->
-    <dimen name="volume_panel_width">344dp</dimen>
-
-    <!-- Volume panel z depth -->
-    <dimen name="volume_panel_z">3dp</dimen>
-
     <!-- Distance between notifications and header when they are considered to be colliding. -->
     <dimen name="header_notifications_collide_distance">48dp</dimen>
 
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 87f9ca2..ef2e6f3 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -138,9 +138,8 @@
         <item name="android:textColor">@color/system_accent_color</item>
     </style>
 
-    <style name="TextAppearance.QS.VolumeSuppressor">
+    <style name="TextAppearance.QS.Introduction">
         <item name="android:textSize">14sp</item>
-        <item name="android:textColor">@color/qs_tile_text</item>
     </style>
 
     <style name="TextAppearance.QS.DetailButton">
@@ -228,12 +227,6 @@
         <item name="android:gravity">center</item>
     </style>
 
-    <!-- Window animations used for volume panel. -->
-    <style name="VolumePanelAnimation">
-        <item name="android:windowEnterAnimation">@*android:anim/popup_enter_material</item>
-        <item name="android:windowExitAnimation">@*android:anim/popup_exit_material</item>
-    </style>
-
     <style name="TextAppearance.Material.Notification.Parenthetical"
            parent="@*android:style/TextAppearance.Material.Notification">
         <item name="android:textStyle">italic</item>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 33a07d9..cb8217e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -62,7 +62,7 @@
     private boolean mShowingPublic;
     private boolean mSensitive;
     private boolean mShowingPublicInitialized;
-    private boolean mShowingPublicForIntrinsicHeight;
+    private boolean mHideSensitiveForIntrinsicHeight;
 
     /**
      * Is this notification expanded by the system. The expansion state can be overridden by the
@@ -570,13 +570,15 @@
         }
         boolean inExpansionState = isExpanded();
         int maxContentHeight;
-        if (mIsHeadsUp) {
+        if (mSensitive && mHideSensitiveForIntrinsicHeight) {
+            return mRowMinHeight;
+        } else if (mIsHeadsUp) {
             if (inExpansionState) {
                 maxContentHeight = Math.max(mMaxExpandHeight, mHeadsUpHeight);
             } else {
                 maxContentHeight = Math.max(mRowMinHeight, mHeadsUpHeight);
             }
-        } else if ((!inExpansionState && !mChildrenExpanded) || mShowingPublicForIntrinsicHeight) {
+        } else if ((!inExpansionState && !mChildrenExpanded)) {
             maxContentHeight = mRowMinHeight;
         } else if (mChildrenExpanded) {
             maxContentHeight = mChildrenContainer.getIntrinsicHeight();
@@ -661,7 +663,7 @@
     }
 
     public void setHideSensitiveForIntrinsicHeight(boolean hideSensitive) {
-        mShowingPublicForIntrinsicHeight = mSensitive && hideSensitive;
+        mHideSensitiveForIntrinsicHeight = hideSensitive;
     }
 
     public void setHideSensitive(boolean hideSensitive, boolean animated, long delay,
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 61e679a..a5dad92 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1116,11 +1116,12 @@
         if (shadeEntry == null) {
             return;
         }
-        if (mUseHeadsUp && shouldInterrupt(notification)) {
+        boolean isHeadsUped = mUseHeadsUp && shouldInterrupt(notification);
+        if (isHeadsUped) {
             mHeadsUpManager.showNotification(shadeEntry);
         }
 
-        if (notification.getNotification().fullScreenIntent != null) {
+        if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
             // Stop screensaver if the notification has a full-screen intent.
             // (like an incoming phone call)
             awakenDreams();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 920a0a1..dccf2e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -464,15 +464,21 @@
 
         public void updateEntry() {
             long currentTime = mClock.currentTimeMillis();
-            postTime = Math.max(postTime, currentTime);
-            long finishTime = postTime + mHeadsUpNotificationDecay;
-            long removeDelay = Math.max(finishTime - currentTime, mMinimumDisplayTime);
             earliestRemovaltime = currentTime + mMinimumDisplayTime;
+            postTime = Math.max(postTime, currentTime);
             removeAutoCancelCallbacks();
-            mHandler.postDelayed(mRemoveHeadsUpRunnable, removeDelay);
+            if (canEntryDecay()) {
+                long finishTime = postTime + mHeadsUpNotificationDecay;
+                long removeDelay = Math.max(finishTime - currentTime, mMinimumDisplayTime);
+                mHandler.postDelayed(mRemoveHeadsUpRunnable, removeDelay);
+            }
             updateSortOrder(HeadsUpEntry.this);
         }
 
+        private boolean canEntryDecay() {
+            return entry.notification.getNotification().fullScreenIntent == null;
+        }
+
         @Override
         public int compareTo(HeadsUpEntry o) {
             return postTime < o.postTime ? 1
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index f247488..88fc602 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -220,7 +220,6 @@
     private PhoneStatusBar mPhoneStatusBar;
     private int[] mTempInt2 = new int[2];
     private boolean mGenerateChildOrderChangedEvent;
-    private boolean mRemoveAnimationEnabled;
     private HashSet<Runnable> mAnimationFinishedRunnables = new HashSet<>();
     private HashSet<Pair<ExpandableNotificationRow, Boolean>> mHeadsUpChangeAnimations
             = new HashSet<>();
@@ -1630,16 +1629,11 @@
         ((ExpandableView) child).setOnHeightChangedListener(null);
         mCurrentStackScrollState.removeViewStateForView(child);
         updateScrollStateForRemovedChild(child);
-        if (mRemoveAnimationEnabled) {
-            boolean animationGenerated = generateRemoveAnimation(child);
-            if (animationGenerated && !mSwipedOutViews.contains(child)) {
-                // Add this view to an overlay in order to ensure that it will still be temporary
-                // drawn when removed
-                getOverlay().add(child);
-            }
-        } else {
-            // TODO: handle this more cleanly when HEADS-up and the shade are merged
-            requestAnimateEverything();
+        boolean animationGenerated = generateRemoveAnimation(child);
+        if (animationGenerated && !mSwipedOutViews.contains(child)) {
+            // Add this view to an overlay in order to ensure that it will still be temporary
+            // drawn when removed
+            getOverlay().add(child);
         }
         updateAnimationState(false, child);
 
@@ -2631,10 +2625,6 @@
         return touchY > mIntrinsicPadding;
     }
 
-    public void setRemoveAnimationEnabled(boolean enabled) {
-        mRemoveAnimationEnabled = enabled;
-    }
-
     private void updateExpandButtons() {
         for (int i = 0; i < getChildCount(); i++) {
             View child = getChildAt(i);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
deleted file mode 100644
index 45cb4a1..0000000
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ /dev/null
@@ -1,1538 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.volume;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnDismissListener;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.ServiceInfo;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.ColorDrawable;
-import android.media.AudioAttributes;
-import android.media.AudioManager;
-import android.media.AudioSystem;
-import android.media.RingtoneManager;
-import android.media.ToneGenerator;
-import android.media.VolumeProvider;
-import android.media.session.MediaController;
-import android.media.session.MediaController.PlaybackInfo;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Debug;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Vibrator;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.WindowManager.LayoutParams;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.widget.ImageView;
-import android.widget.SeekBar;
-import android.widget.SeekBar.OnSeekBarChangeListener;
-import android.widget.TextView;
-
-import com.android.internal.R;
-import com.android.systemui.DemoMode;
-import com.android.systemui.statusbar.policy.ZenModeController;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Handles the user interface for the volume keys.
- *
- * @hide
- */
-public class VolumePanel extends Handler implements DemoMode {
-    private static final String TAG = "VolumePanel";
-    private static boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
-
-    private static final int PLAY_SOUND_DELAY = AudioSystem.PLAY_SOUND_DELAY;
-
-    /**
-     * The delay before vibrating. This small period exists so if the user is
-     * moving to silent mode, it will not emit a short vibrate (it normally
-     * would since vibrate is between normal mode and silent mode using hardware
-     * keys).
-     */
-    public static final int VIBRATE_DELAY = 300;
-
-    private static final int VIBRATE_DURATION = 300;
-    private static final int BEEP_DURATION = 150;
-    private static final int MAX_VOLUME = 100;
-    private static final int FREE_DELAY = 10000;
-    private static final int TIMEOUT_DELAY = 3000;
-    private static final int TIMEOUT_DELAY_SHORT = 1500;
-    private static final int TIMEOUT_DELAY_COLLAPSED = 4500;
-    private static final int TIMEOUT_DELAY_SAFETY_WARNING = 5000;
-    private static final int TIMEOUT_DELAY_EXPANDED = 10000;
-
-    private static final int MSG_VOLUME_CHANGED = 0;
-    private static final int MSG_FREE_RESOURCES = 1;
-    private static final int MSG_PLAY_SOUND = 2;
-    private static final int MSG_STOP_SOUNDS = 3;
-    private static final int MSG_VIBRATE = 4;
-    private static final int MSG_TIMEOUT = 5;
-    private static final int MSG_RINGER_MODE_CHANGED = 6;
-    private static final int MSG_MUTE_CHANGED = 7;
-    private static final int MSG_REMOTE_VOLUME_CHANGED = 8;
-    private static final int MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN = 9;
-    private static final int MSG_SLIDER_VISIBILITY_CHANGED = 10;
-    private static final int MSG_DISPLAY_SAFE_VOLUME_WARNING = 11;
-    private static final int MSG_LAYOUT_DIRECTION = 12;
-    private static final int MSG_ZEN_MODE_AVAILABLE_CHANGED = 13;
-    private static final int MSG_USER_ACTIVITY = 14;
-    private static final int MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED = 15;
-    private static final int MSG_INTERNAL_RINGER_MODE_CHANGED = 16;
-
-    // Pseudo stream type for remote volume
-    private static final int STREAM_REMOTE_MUSIC = -200;
-
-    private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
-            .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
-            .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
-            .build();
-
-    private static final int IC_AUDIO_VOL = com.android.systemui.R.drawable.ic_audio_vol;
-    private static final int IC_AUDIO_VOL_MUTE = com.android.systemui.R.drawable.ic_audio_vol_mute;
-    private static final int IC_AUDIO_BT = com.android.systemui.R.drawable.ic_audio_bt;
-    private static final int IC_AUDIO_BT_MUTE = com.android.systemui.R.drawable.ic_audio_bt_mute;
-
-    private final String mTag;
-    protected final Context mContext;
-    private final AudioManager mAudioManager;
-    private final ZenModeController mZenController;
-    private boolean mRingIsSilent;
-    private boolean mVoiceCapable;
-    private boolean mZenModeAvailable;
-    private boolean mZenPanelExpanded;
-    private int mTimeoutDelay = TIMEOUT_DELAY;
-    private float mDisabledAlpha;
-    private int mLastRingerMode = AudioManager.RINGER_MODE_NORMAL;
-    private int mLastRingerProgress = 0;
-    private int mDemoIcon;
-
-    /** Volume panel content view */
-    private final View mView;
-    /** Dialog hosting the panel */
-    private final Dialog mDialog;
-
-    /** The visible portion of the volume overlay */
-    private final ViewGroup mPanel;
-    /** Contains the slider and its touchable icons */
-    private final ViewGroup mSliderPanel;
-    /** The zen mode configuration panel view */
-    private ZenModePanel mZenPanel;
-    /** The component currently suppressing notification stream effects */
-    private ComponentName mNotificationEffectsSuppressor;
-
-    private Callback mCallback;
-
-    /** Currently active stream that shows up at the top of the list of sliders */
-    private int mActiveStreamType = -1;
-    /** All the slider controls mapped by stream type */
-    private SparseArray<StreamControl> mStreamControls;
-    private final AccessibilityManager mAccessibilityManager;
-    private final SecondaryIconTransition mSecondaryIconTransition;
-    private final IconPulser mIconPulser;
-
-    private enum StreamResources {
-        BluetoothSCOStream(AudioManager.STREAM_BLUETOOTH_SCO,
-                R.string.volume_icon_description_bluetooth,
-                IC_AUDIO_BT,
-                IC_AUDIO_BT_MUTE,
-                false),
-        RingerStream(AudioManager.STREAM_RING,
-                R.string.volume_icon_description_ringer,
-                com.android.systemui.R.drawable.ic_ringer_audible,
-                com.android.systemui.R.drawable.ic_ringer_mute,
-                false),
-        VoiceStream(AudioManager.STREAM_VOICE_CALL,
-                R.string.volume_icon_description_incall,
-                com.android.systemui.R.drawable.ic_audio_phone,
-                com.android.systemui.R.drawable.ic_audio_phone,
-                false),
-        AlarmStream(AudioManager.STREAM_ALARM,
-                R.string.volume_alarm,
-                com.android.systemui.R.drawable.ic_audio_alarm,
-                com.android.systemui.R.drawable.ic_audio_alarm_mute,
-                false),
-        MediaStream(AudioManager.STREAM_MUSIC,
-                R.string.volume_icon_description_media,
-                IC_AUDIO_VOL,
-                IC_AUDIO_VOL_MUTE,
-                true),
-        NotificationStream(AudioManager.STREAM_NOTIFICATION,
-                R.string.volume_icon_description_notification,
-                com.android.systemui.R.drawable.ic_ringer_audible,
-                com.android.systemui.R.drawable.ic_ringer_mute,
-                true),
-        RemoteStream(STREAM_REMOTE_MUSIC,
-                R.string.volume_icon_description_media, //FIXME should have its own description
-                com.android.systemui.R.drawable.ic_audio_remote,
-                com.android.systemui.R.drawable.ic_audio_remote,
-                false);// will be dynamically updated
-
-        int streamType;
-        int descRes;
-        int iconRes;
-        int iconMuteRes;
-        // RING, VOICE_CALL & BLUETOOTH_SCO are hidden unless explicitly requested
-        boolean show;
-
-        StreamResources(int streamType, int descRes, int iconRes, int iconMuteRes, boolean show) {
-            this.streamType = streamType;
-            this.descRes = descRes;
-            this.iconRes = iconRes;
-            this.iconMuteRes = iconMuteRes;
-            this.show = show;
-        }
-    }
-
-    // List of stream types and their order
-    private static final StreamResources[] STREAMS = {
-        StreamResources.BluetoothSCOStream,
-        StreamResources.RingerStream,
-        StreamResources.VoiceStream,
-        StreamResources.MediaStream,
-        StreamResources.NotificationStream,
-        StreamResources.AlarmStream,
-        StreamResources.RemoteStream
-    };
-
-    /** Object that contains data for each slider */
-    private class StreamControl {
-        int streamType;
-        MediaController controller;
-        ViewGroup group;
-        ImageView icon;
-        SeekBar seekbarView;
-        TextView suppressorView;
-        View divider;
-        ImageView secondaryIcon;
-        int iconRes;
-        int iconMuteRes;
-        int iconSuppressedRes;
-        int minVolume;
-    }
-
-    // Synchronize when accessing this
-    private ToneGenerator mToneGenerators[];
-    private Vibrator mVibrator;
-    private boolean mHasVibrator;
-
-    private static AlertDialog sSafetyWarning;
-    private static Object sSafetyWarningLock = new Object();
-
-    protected LayoutParams getDialogLayoutParams(Window window, Resources res) {
-        final LayoutParams lp = window.getAttributes();
-        lp.token = null;
-        lp.y = res.getDimensionPixelOffset(com.android.systemui.R.dimen.volume_panel_top);
-        lp.type = LayoutParams.TYPE_STATUS_BAR_PANEL;
-        lp.format = PixelFormat.TRANSLUCENT;
-        lp.windowAnimations = com.android.systemui.R.style.VolumePanelAnimation;
-        lp.setTitle(TAG);
-        return lp;
-    }
-
-    public VolumePanel(Context context, ZenModeController zenController) {
-        mTag = String.format("%s.%08x", TAG, hashCode());
-        mContext = context;
-        mZenController = zenController;
-        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-        mAccessibilityManager = (AccessibilityManager) context.getSystemService(
-                Context.ACCESSIBILITY_SERVICE);
-        mSecondaryIconTransition = new SecondaryIconTransition();
-        mIconPulser = new IconPulser(context);
-
-        if (LOGD) Log.d(mTag, "new VolumePanel");
-
-        mDisabledAlpha = 0.5f;
-        if (mContext.getTheme() != null) {
-            final TypedArray arr = mContext.getTheme().obtainStyledAttributes(
-                    new int[] { android.R.attr.disabledAlpha });
-            mDisabledAlpha = arr.getFloat(0, mDisabledAlpha);
-            arr.recycle();
-        }
-
-        mDialog = new Dialog(context) {
-            @Override
-            public boolean onTouchEvent(MotionEvent event) {
-                if (isShowing() && event.getAction() == MotionEvent.ACTION_OUTSIDE &&
-                        sSafetyWarning == null) {
-                    forceTimeout(0);
-                    return true;
-                }
-                return false;
-            }
-        };
-
-        final Window window = mDialog.getWindow();
-        window.requestFeature(Window.FEATURE_NO_TITLE);
-        mDialog.setCanceledOnTouchOutside(true);
-        mDialog.setContentView(com.android.systemui.R.layout.volume_panel_dialog);
-        mDialog.setOnDismissListener(new OnDismissListener() {
-            @Override
-            public void onDismiss(DialogInterface dialog) {
-                mActiveStreamType = -1;
-                mAudioManager.forceVolumeControlStream(mActiveStreamType);
-                setZenPanelVisible(false);
-                mDemoIcon = 0;
-                mSecondaryIconTransition.cancel();
-            }
-        });
-
-        mDialog.create();
-
-        final Resources res = context.getResources();
-        window.setAttributes(getDialogLayoutParams(window, res));
-
-        updateWidth();
-
-        window.setBackgroundDrawable(new ColorDrawable(0x00000000));
-        window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
-        window.addFlags(LayoutParams.FLAG_NOT_FOCUSABLE
-                | LayoutParams.FLAG_NOT_TOUCH_MODAL
-                | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
-                | LayoutParams.FLAG_HARDWARE_ACCELERATED);
-        mView = window.findViewById(R.id.content);
-        Interaction.register(mView, new Interaction.Callback() {
-            @Override
-            public void onInteraction() {
-                resetTimeout();
-            }
-        });
-
-        mPanel = (ViewGroup) mView.findViewById(com.android.systemui.R.id.visible_panel);
-        mSliderPanel = (ViewGroup) mView.findViewById(com.android.systemui.R.id.slider_panel);
-        mZenPanel = (ZenModePanel) mView.findViewById(com.android.systemui.R.id.zen_mode_panel);
-        initZenModePanel();
-
-        mToneGenerators = new ToneGenerator[AudioSystem.getNumStreamTypes()];
-        mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
-        mHasVibrator = mVibrator != null && mVibrator.hasVibrator();
-        mVoiceCapable = context.getResources().getBoolean(R.bool.config_voice_capable);
-
-        if (mZenController != null) {
-            mZenModeAvailable = mZenController.isZenAvailable();
-            mNotificationEffectsSuppressor = mZenController.getEffectsSuppressor();
-            mZenController.addCallback(mZenCallback);
-        }
-
-        registerReceiver();
-    }
-
-    public void onConfigurationChanged(Configuration newConfig) {
-        updateWidth();
-        if (mZenPanel != null) {
-            mZenPanel.updateLocale();
-        }
-    }
-
-    private void updateWidth() {
-        final Resources res = mContext.getResources();
-        final LayoutParams lp = mDialog.getWindow().getAttributes();
-        lp.width = res.getDimensionPixelSize(com.android.systemui.R.dimen.notification_panel_width);
-        lp.gravity =
-                res.getInteger(com.android.systemui.R.integer.notification_panel_layout_gravity);
-        mDialog.getWindow().setAttributes(lp);
-    }
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("VolumePanel state:");
-        pw.print("  mTag="); pw.println(mTag);
-        pw.print("  mRingIsSilent="); pw.println(mRingIsSilent);
-        pw.print("  mVoiceCapable="); pw.println(mVoiceCapable);
-        pw.print("  mHasVibrator="); pw.println(mHasVibrator);
-        pw.print("  mZenModeAvailable="); pw.println(mZenModeAvailable);
-        pw.print("  mZenPanelExpanded="); pw.println(mZenPanelExpanded);
-        pw.print("  mNotificationEffectsSuppressor="); pw.println(mNotificationEffectsSuppressor);
-        pw.print("  mTimeoutDelay="); pw.println(mTimeoutDelay);
-        pw.print("  mDisabledAlpha="); pw.println(mDisabledAlpha);
-        pw.print("  mLastRingerMode="); pw.println(mLastRingerMode);
-        pw.print("  mLastRingerProgress="); pw.println(mLastRingerProgress);
-        pw.print("  isShowing()="); pw.println(isShowing());
-        pw.print("  mCallback="); pw.println(mCallback);
-        pw.print("  sConfirmSafeVolumeDialog=");
-        pw.println(sSafetyWarning != null ? "<not null>" : null);
-        pw.print("  mActiveStreamType="); pw.println(mActiveStreamType);
-        pw.print("  mStreamControls=");
-        if (mStreamControls == null) {
-            pw.println("null");
-        } else {
-            final int N = mStreamControls.size();
-            pw.print("<size "); pw.print(N); pw.println('>');
-            for (int i = 0; i < N; i++) {
-                final StreamControl sc = mStreamControls.valueAt(i);
-                pw.print("    stream "); pw.print(sc.streamType); pw.print(":");
-                if (sc.seekbarView != null) {
-                    pw.print(" progress="); pw.print(sc.seekbarView.getProgress());
-                    pw.print(" of "); pw.print(sc.seekbarView.getMax());
-                    if (!sc.seekbarView.isEnabled()) pw.print(" (disabled)");
-                }
-                if (sc.icon != null && sc.icon.isClickable()) pw.print(" (clickable)");
-                pw.println();
-            }
-        }
-        if (mZenPanel != null) {
-            mZenPanel.dump(fd, pw, args);
-        }
-    }
-
-    private void initZenModePanel() {
-        mZenPanel.init(mZenController);
-        mZenPanel.setCallback(new ZenModePanel.Callback() {
-            @Override
-            public void onMoreSettings() {
-                if (mCallback != null) {
-                    mCallback.onZenSettings();
-                }
-            }
-
-            @Override
-            public void onPrioritySettings() {
-                if (mCallback != null) {
-                    mCallback.onZenPrioritySettings();
-                }
-            }
-
-            @Override
-            public void onInteraction() {
-                resetTimeout();
-            }
-
-            @Override
-            public void onExpanded(boolean expanded) {
-                if (mZenPanelExpanded == expanded) return;
-                mZenPanelExpanded = expanded;
-                updateTimeoutDelay();
-                resetTimeout();
-            }
-        });
-    }
-
-    private void setLayoutDirection(int layoutDirection) {
-        mPanel.setLayoutDirection(layoutDirection);
-        updateStates();
-    }
-
-    private void registerReceiver() {
-        final IntentFilter filter = new IntentFilter();
-        filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
-        filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
-        filter.addAction(Intent.ACTION_SCREEN_OFF);
-        mContext.registerReceiver(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                final String action = intent.getAction();
-
-                if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
-                    removeMessages(MSG_RINGER_MODE_CHANGED);
-                    sendEmptyMessage(MSG_RINGER_MODE_CHANGED);
-                }
-
-                if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
-                    removeMessages(MSG_INTERNAL_RINGER_MODE_CHANGED);
-                    sendEmptyMessage(MSG_INTERNAL_RINGER_MODE_CHANGED);
-                }
-
-                if (Intent.ACTION_SCREEN_OFF.equals(action)) {
-                    postDismiss(0);
-                }
-            }
-        }, filter);
-    }
-
-    private boolean isMuted(int streamType) {
-        if (streamType == STREAM_REMOTE_MUSIC) {
-            // TODO do we need to support a distinct mute property for remote?
-            return false;
-        } else {
-            return mAudioManager.isStreamMute(streamType);
-        }
-    }
-
-    private int getStreamMinVolume(int streamType) {
-        if (streamType == STREAM_REMOTE_MUSIC) {
-            return 0;
-        } else {
-            return mAudioManager.getStreamMinVolume(streamType);
-        }
-    }
-
-    private int getStreamMaxVolume(int streamType) {
-        if (streamType == STREAM_REMOTE_MUSIC) {
-            if (mStreamControls != null) {
-                StreamControl sc = mStreamControls.get(streamType);
-                if (sc != null && sc.controller != null) {
-                    PlaybackInfo ai = sc.controller.getPlaybackInfo();
-                    return ai.getMaxVolume();
-                }
-            }
-            return -1;
-        } else {
-            return mAudioManager.getStreamMaxVolume(streamType);
-        }
-    }
-
-    private int getStreamVolume(int streamType) {
-        if (streamType == STREAM_REMOTE_MUSIC) {
-            if (mStreamControls != null) {
-                StreamControl sc = mStreamControls.get(streamType);
-                if (sc != null && sc.controller != null) {
-                    PlaybackInfo ai = sc.controller.getPlaybackInfo();
-                    return ai.getCurrentVolume();
-                }
-            }
-            return -1;
-        } else {
-            return mAudioManager.getLastAudibleStreamVolume(streamType);
-        }
-    }
-
-    private void setStreamVolume(StreamControl sc, int index, int flags) {
-        if (sc.streamType == STREAM_REMOTE_MUSIC) {
-            if (sc.controller != null) {
-                sc.controller.setVolumeTo(index, flags);
-            } else {
-                Log.w(mTag, "Adjusting remote volume without a controller!");
-            }
-        } else if (getStreamVolume(sc.streamType) != index) {
-            mAudioManager.setStreamVolume(sc.streamType, index, flags);
-        }
-    }
-
-    private void createSliders() {
-        final Resources res = mContext.getResources();
-        final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
-                Context.LAYOUT_INFLATER_SERVICE);
-
-        mStreamControls = new SparseArray<StreamControl>(STREAMS.length);
-
-        final StreamResources notificationStream = StreamResources.NotificationStream;
-        for (int i = 0; i < STREAMS.length; i++) {
-            StreamResources streamRes = STREAMS[i];
-
-            final int streamType = streamRes.streamType;
-            final boolean isNotification = isNotificationOrRing(streamType);
-
-            final StreamControl sc = new StreamControl();
-            sc.streamType = streamType;
-            sc.group = (ViewGroup) inflater.inflate(
-                    com.android.systemui.R.layout.volume_panel_item, null);
-            sc.group.setTag(sc);
-            sc.icon = (ImageView) sc.group.findViewById(com.android.systemui.R.id.stream_icon);
-            sc.icon.setTag(sc);
-            sc.icon.setContentDescription(res.getString(streamRes.descRes));
-            sc.iconRes = streamRes.iconRes;
-            sc.iconMuteRes = streamRes.iconMuteRes;
-            sc.icon.setImageResource(sc.iconRes);
-            sc.icon.setClickable(isNotification && mHasVibrator);
-            if (isNotification) {
-                if (mHasVibrator) {
-                    sc.icon.setSoundEffectsEnabled(false);
-                    sc.iconMuteRes = com.android.systemui.R.drawable.ic_ringer_vibrate;
-                    sc.icon.setOnClickListener(new OnClickListener() {
-                        @Override
-                        public void onClick(View v) {
-                            resetTimeout();
-                            toggleRinger(sc);
-                        }
-                    });
-                }
-                sc.iconSuppressedRes = com.android.systemui.R.drawable.ic_ringer_mute;
-            }
-            sc.seekbarView = (SeekBar) sc.group.findViewById(com.android.systemui.R.id.seekbar);
-            sc.suppressorView =
-                    (TextView) sc.group.findViewById(com.android.systemui.R.id.suppressor);
-            sc.suppressorView.setVisibility(View.GONE);
-            final boolean showSecondary = !isNotification && notificationStream.show;
-            sc.divider = sc.group.findViewById(com.android.systemui.R.id.divider);
-            sc.secondaryIcon = (ImageView) sc.group
-                    .findViewById(com.android.systemui.R.id.secondary_icon);
-            sc.secondaryIcon.setImageResource(com.android.systemui.R.drawable.ic_ringer_audible);
-            sc.secondaryIcon.setContentDescription(res.getString(notificationStream.descRes));
-            sc.secondaryIcon.setClickable(showSecondary);
-            sc.divider.setVisibility(showSecondary ? View.VISIBLE : View.GONE);
-            sc.secondaryIcon.setVisibility(showSecondary ? View.VISIBLE : View.GONE);
-            if (showSecondary) {
-                sc.secondaryIcon.setOnClickListener(new OnClickListener() {
-                    @Override
-                    public void onClick(View v) {
-                        mSecondaryIconTransition.start(sc);
-                    }
-                });
-            }
-            sc.minVolume = getStreamMinVolume(streamType);
-            sc.seekbarView.setMax(getStreamMaxVolume(streamType) - sc.minVolume);
-            sc.seekbarView.setOnSeekBarChangeListener(mSeekListener);
-            sc.seekbarView.setTag(sc);
-            mStreamControls.put(streamType, sc);
-        }
-    }
-
-    private void toggleRinger(StreamControl sc) {
-        if (!mHasVibrator) return;
-        if (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_NORMAL) {
-            mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_VIBRATE);
-            postVolumeChanged(sc.streamType, AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE);
-        } else {
-            mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL);
-            postVolumeChanged(sc.streamType, AudioManager.FLAG_PLAY_SOUND);
-        }
-    }
-
-    private void reorderSliders(int activeStreamType) {
-        mSliderPanel.removeAllViews();
-
-        final StreamControl active = mStreamControls.get(activeStreamType);
-        if (active == null) {
-            Log.e(TAG, "Missing stream type! - " + activeStreamType);
-            mActiveStreamType = -1;
-        } else {
-            mSliderPanel.addView(active.group);
-            mActiveStreamType = activeStreamType;
-            active.group.setVisibility(View.VISIBLE);
-            updateSlider(active, true /*forceReloadIcon*/);
-            updateTimeoutDelay();
-            updateZenPanelVisible();
-        }
-    }
-
-    private void updateSliderProgress(StreamControl sc, int progress) {
-        final boolean isRinger = isNotificationOrRing(sc.streamType);
-        if (isRinger && mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
-            progress = mLastRingerProgress;
-        }
-        if (progress < 0) {
-            progress = getStreamVolume(sc.streamType);
-        }
-        sc.seekbarView.setProgress(progress - sc.minVolume);
-        if (isRinger) {
-            mLastRingerProgress = progress;
-        }
-    }
-
-    private void updateSliderIcon(StreamControl sc, boolean muted) {
-        ComponentName suppressor = null;
-        if (isNotificationOrRing(sc.streamType)) {
-            suppressor = mNotificationEffectsSuppressor;
-            int ringerMode = mAudioManager.getRingerModeInternal();
-            if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
-                ringerMode = mLastRingerMode;
-            } else {
-                mLastRingerMode = ringerMode;
-            }
-            if (mHasVibrator) {
-                muted = ringerMode == AudioManager.RINGER_MODE_VIBRATE;
-            } else {
-                muted = false;
-            }
-        }
-        sc.icon.setImageResource(mDemoIcon != 0 ? mDemoIcon
-                : suppressor != null ? sc.iconSuppressedRes
-                : muted ? sc.iconMuteRes
-                : sc.iconRes);
-    }
-
-    private void updateSliderSuppressor(StreamControl sc) {
-        final ComponentName suppressor = isNotificationOrRing(sc.streamType)
-                ? mNotificationEffectsSuppressor : null;
-        if (suppressor == null) {
-            sc.seekbarView.setVisibility(View.VISIBLE);
-            sc.suppressorView.setVisibility(View.GONE);
-        } else {
-            sc.seekbarView.setVisibility(View.GONE);
-            sc.suppressorView.setVisibility(View.VISIBLE);
-            sc.suppressorView.setText(mContext.getString(R.string.muted_by,
-                    getSuppressorCaption(suppressor)));
-        }
-    }
-
-    private String getSuppressorCaption(ComponentName suppressor) {
-        final PackageManager pm = mContext.getPackageManager();
-        try {
-            final ServiceInfo info = pm.getServiceInfo(suppressor, 0);
-            if (info != null) {
-                final CharSequence seq = info.loadLabel(pm);
-                if (seq != null) {
-                    final String str = seq.toString().trim();
-                    if (str.length() > 0) {
-                        return str;
-                    }
-                }
-            }
-        } catch (Throwable e) {
-            Log.w(TAG, "Error loading suppressor caption", e);
-        }
-        return suppressor.getPackageName();
-    }
-
-    /** Update the mute and progress state of a slider */
-    private void updateSlider(StreamControl sc, boolean forceReloadIcon) {
-        updateSliderProgress(sc, -1);
-        final boolean muted = isMuted(sc.streamType);
-        if (forceReloadIcon) {
-            sc.icon.setImageDrawable(null);
-        }
-        updateSliderIcon(sc, muted);
-        updateSliderEnabled(sc, muted, false);
-        updateSliderSuppressor(sc);
-    }
-
-    private void updateSliderEnabled(final StreamControl sc, boolean muted, boolean fixedVolume) {
-        final boolean wasEnabled = sc.seekbarView.isEnabled();
-        final boolean isRinger = isNotificationOrRing(sc.streamType);
-        if (sc.streamType == STREAM_REMOTE_MUSIC) {
-            // never disable touch interactions for remote playback, the muting is not tied to
-            // the state of the phone.
-            sc.seekbarView.setEnabled(!fixedVolume);
-        } else if (isRinger && mNotificationEffectsSuppressor != null) {
-            sc.icon.setEnabled(true);
-            sc.icon.setAlpha(1f);
-            sc.icon.setClickable(false);
-        } else if (isRinger
-                && mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
-            sc.seekbarView.setEnabled(false);
-            sc.icon.setEnabled(false);
-            sc.icon.setAlpha(mDisabledAlpha);
-            sc.icon.setClickable(false);
-        } else if (fixedVolume ||
-                (sc.streamType != mAudioManager.getUiSoundsStreamType() && !isRinger && muted) ||
-                (sSafetyWarning != null)) {
-            sc.seekbarView.setEnabled(false);
-        } else {
-            sc.seekbarView.setEnabled(true);
-            sc.icon.setEnabled(true);
-            sc.icon.setAlpha(1f);
-        }
-        // show the silent hint when the disabled slider is touched in silent mode
-        if (isRinger && wasEnabled != sc.seekbarView.isEnabled()) {
-            if (sc.seekbarView.isEnabled()) {
-                sc.group.setOnTouchListener(null);
-                sc.icon.setClickable(mHasVibrator);
-            } else {
-                final View.OnTouchListener showHintOnTouch = new View.OnTouchListener() {
-                    @Override
-                    public boolean onTouch(View v, MotionEvent event) {
-                        resetTimeout();
-                        showSilentHint();
-                        return false;
-                    }
-                };
-                sc.group.setOnTouchListener(showHintOnTouch);
-            }
-        }
-    }
-
-    private void showSilentHint() {
-        if (mZenPanel != null) {
-            mZenPanel.showSilentHint();
-        }
-    }
-
-    private void showVibrateHint() {
-        final StreamControl active = mStreamControls.get(mActiveStreamType);
-        if (active != null) {
-            mIconPulser.start(active.icon);
-            if (!hasMessages(MSG_VIBRATE)) {
-                sendEmptyMessageDelayed(MSG_VIBRATE, VIBRATE_DELAY);
-            }
-        }
-    }
-
-    private static boolean isNotificationOrRing(int streamType) {
-        return streamType == AudioManager.STREAM_RING
-                || streamType == AudioManager.STREAM_NOTIFICATION;
-    }
-
-    public void setCallback(Callback callback) {
-        mCallback = callback;
-    }
-
-    private void updateTimeoutDelay() {
-        mTimeoutDelay = mDemoIcon != 0 ? TIMEOUT_DELAY_EXPANDED
-                : sSafetyWarning != null ? TIMEOUT_DELAY_SAFETY_WARNING
-                : mActiveStreamType == AudioManager.STREAM_MUSIC ? TIMEOUT_DELAY_SHORT
-                : mZenPanelExpanded ? TIMEOUT_DELAY_EXPANDED
-                : isZenPanelVisible() ? TIMEOUT_DELAY_COLLAPSED
-                : TIMEOUT_DELAY;
-    }
-
-    private boolean isZenPanelVisible() {
-        return mZenPanel != null && mZenPanel.getVisibility() == View.VISIBLE;
-    }
-
-    private void setZenPanelVisible(boolean visible) {
-        if (LOGD) Log.d(mTag, "setZenPanelVisible " + visible + " mZenPanel=" + mZenPanel);
-        final boolean changing = visible != isZenPanelVisible();
-        if (visible) {
-            mZenPanel.setHidden(false);
-            resetTimeout();
-        } else {
-            mZenPanel.setHidden(true);
-        }
-        if (changing) {
-            updateTimeoutDelay();
-            resetTimeout();
-        }
-    }
-
-    private void updateStates() {
-        final int count = mSliderPanel.getChildCount();
-        for (int i = 0; i < count; i++) {
-            StreamControl sc = (StreamControl) mSliderPanel.getChildAt(i).getTag();
-            updateSlider(sc, true /*forceReloadIcon*/);
-        }
-    }
-
-    private void updateActiveSlider() {
-        final StreamControl active = mStreamControls.get(mActiveStreamType);
-        if (active != null) {
-            updateSlider(active, false /*forceReloadIcon*/);
-        }
-    }
-
-    private void updateZenPanelVisible() {
-        setZenPanelVisible(mZenModeAvailable && isNotificationOrRing(mActiveStreamType));
-    }
-
-    public void postVolumeChanged(int streamType, int flags) {
-        if (hasMessages(MSG_VOLUME_CHANGED)) return;
-        synchronized (this) {
-            if (mStreamControls == null) {
-                createSliders();
-            }
-        }
-        removeMessages(MSG_FREE_RESOURCES);
-        obtainMessage(MSG_VOLUME_CHANGED, streamType, flags).sendToTarget();
-    }
-
-    public void postRemoteVolumeChanged(MediaController controller, int flags) {
-        if (hasMessages(MSG_REMOTE_VOLUME_CHANGED)) return;
-        synchronized (this) {
-            if (mStreamControls == null) {
-                createSliders();
-            }
-        }
-        removeMessages(MSG_FREE_RESOURCES);
-        obtainMessage(MSG_REMOTE_VOLUME_CHANGED, flags, 0, controller).sendToTarget();
-    }
-
-    public void postRemoteSliderVisibility(boolean visible) {
-        obtainMessage(MSG_SLIDER_VISIBILITY_CHANGED,
-                STREAM_REMOTE_MUSIC, visible ? 1 : 0).sendToTarget();
-    }
-
-    /**
-     * Called by AudioService when it has received new remote playback information that
-     * would affect the VolumePanel display (mainly volumes). The difference with
-     * {@link #postRemoteVolumeChanged(int, int)} is that the handling of the posted message
-     * (MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN) will only update the volume slider if it is being
-     * displayed.
-     * This special code path is due to the fact that remote volume updates arrive to AudioService
-     * asynchronously. So after AudioService has sent the volume update (which should be treated
-     * as a request to update the volume), the application will likely set a new volume. If the UI
-     * is still up, we need to refresh the display to show this new value.
-     */
-    public void postHasNewRemotePlaybackInfo() {
-        if (hasMessages(MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN)) return;
-        // don't create or prevent resources to be freed, if they disappear, this update came too
-        //   late and shouldn't warrant the panel to be displayed longer
-        obtainMessage(MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN).sendToTarget();
-    }
-
-    public void postMuteChanged(int streamType, int flags) {
-        if (hasMessages(MSG_VOLUME_CHANGED)) return;
-        synchronized (this) {
-            if (mStreamControls == null) {
-                createSliders();
-            }
-        }
-        removeMessages(MSG_FREE_RESOURCES);
-        obtainMessage(MSG_MUTE_CHANGED, streamType, flags).sendToTarget();
-    }
-
-    public void postDisplaySafeVolumeWarning(int flags) {
-        if (hasMessages(MSG_DISPLAY_SAFE_VOLUME_WARNING)) return;
-        obtainMessage(MSG_DISPLAY_SAFE_VOLUME_WARNING, flags, 0).sendToTarget();
-    }
-
-    public void postDismiss(long delay) {
-        forceTimeout(delay);
-    }
-
-    public void postLayoutDirection(int layoutDirection) {
-        removeMessages(MSG_LAYOUT_DIRECTION);
-        obtainMessage(MSG_LAYOUT_DIRECTION, layoutDirection, 0).sendToTarget();
-    }
-
-    private static String flagsToString(int flags) {
-        return flags == 0 ? "0" : (flags + "=" + AudioManager.flagsToString(flags));
-    }
-
-    private static String streamToString(int stream) {
-        return AudioSystem.streamToString(stream);
-    }
-
-    /**
-     * Override this if you have other work to do when the volume changes (for
-     * example, vibrating, playing a sound, etc.). Make sure to call through to
-     * the superclass implementation.
-     */
-    protected void onVolumeChanged(int streamType, int flags) {
-
-        if (LOGD) Log.d(mTag, "onVolumeChanged(streamType: " + streamToString(streamType)
-                + ", flags: " + flagsToString(flags) + ")");
-
-        if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
-            synchronized (this) {
-                if (mActiveStreamType != streamType) {
-                    reorderSliders(streamType);
-                }
-                onShowVolumeChanged(streamType, flags, null);
-            }
-        }
-
-        if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && ! mRingIsSilent) {
-            removeMessages(MSG_PLAY_SOUND);
-            sendMessageDelayed(obtainMessage(MSG_PLAY_SOUND, streamType, flags), PLAY_SOUND_DELAY);
-        }
-
-        if ((flags & AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE) != 0) {
-            removeMessages(MSG_PLAY_SOUND);
-            removeMessages(MSG_VIBRATE);
-            onStopSounds();
-        }
-
-        removeMessages(MSG_FREE_RESOURCES);
-        sendMessageDelayed(obtainMessage(MSG_FREE_RESOURCES), FREE_DELAY);
-        resetTimeout();
-    }
-
-    protected void onMuteChanged(int streamType, int flags) {
-
-        if (LOGD) Log.d(mTag, "onMuteChanged(streamType: " + streamToString(streamType)
-                + ", flags: " + flagsToString(flags) + ")");
-
-        StreamControl sc = mStreamControls.get(streamType);
-        if (sc != null) {
-            updateSliderIcon(sc, isMuted(sc.streamType));
-        }
-
-        onVolumeChanged(streamType, flags);
-    }
-
-    protected void onShowVolumeChanged(int streamType, int flags, MediaController controller) {
-        int index = getStreamVolume(streamType);
-
-        mRingIsSilent = false;
-
-        if (LOGD) {
-            Log.d(mTag, "onShowVolumeChanged(streamType: " + streamToString(streamType)
-                    + ", flags: " + flagsToString(flags) + "), index: " + index);
-        }
-
-        // get max volume for progress bar
-
-        int max = getStreamMaxVolume(streamType) - getStreamMinVolume(streamType);
-        StreamControl sc = mStreamControls.get(streamType);
-
-        switch (streamType) {
-
-            case AudioManager.STREAM_RING: {
-                Uri ringuri = RingtoneManager.getActualDefaultRingtoneUri(
-                        mContext, RingtoneManager.TYPE_RINGTONE);
-                if (ringuri == null) {
-                    mRingIsSilent = true;
-                }
-                break;
-            }
-
-            case AudioManager.STREAM_MUSIC: {
-                // Special case for when Bluetooth is active for music
-                if ((mAudioManager.getDevicesForStream(AudioManager.STREAM_MUSIC) &
-                        (AudioManager.DEVICE_OUT_BLUETOOTH_A2DP |
-                        AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
-                        AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) != 0) {
-                    setMusicIcon(IC_AUDIO_BT, IC_AUDIO_BT_MUTE);
-                } else {
-                    setMusicIcon(IC_AUDIO_VOL, IC_AUDIO_VOL_MUTE);
-                }
-                break;
-            }
-
-            case AudioManager.STREAM_ALARM: {
-                break;
-            }
-
-            case AudioManager.STREAM_NOTIFICATION: {
-                Uri ringuri = RingtoneManager.getActualDefaultRingtoneUri(
-                        mContext, RingtoneManager.TYPE_NOTIFICATION);
-                if (ringuri == null) {
-                    mRingIsSilent = true;
-                }
-                break;
-            }
-
-            case STREAM_REMOTE_MUSIC: {
-                if (controller == null && sc != null) {
-                    // If we weren't passed one try using the last one set.
-                    controller = sc.controller;
-                }
-                if (controller == null) {
-                    // We still don't have one, ignore the command.
-                    Log.w(mTag, "sent remote volume change without a controller!");
-                } else {
-                    PlaybackInfo vi = controller.getPlaybackInfo();
-                    index = vi.getCurrentVolume();
-                    max = vi.getMaxVolume();
-                    if ((vi.getVolumeControl() & VolumeProvider.VOLUME_CONTROL_FIXED) != 0) {
-                        // if the remote volume is fixed add the flag for the UI
-                        flags |= AudioManager.FLAG_FIXED_VOLUME;
-                    }
-                }
-                if (LOGD) { Log.d(mTag, "showing remote volume "+index+" over "+ max); }
-                break;
-            }
-        }
-
-        if (sc != null) {
-            if (streamType == STREAM_REMOTE_MUSIC && controller != sc.controller) {
-                if (sc.controller != null) {
-                    sc.controller.unregisterCallback(mMediaControllerCb);
-                }
-                sc.controller = controller;
-                if (controller != null) {
-                    sc.controller.registerCallback(mMediaControllerCb);
-                }
-            }
-            if (sc.seekbarView.getMax() != max) {
-                sc.seekbarView.setMax(max);
-            }
-            updateSliderProgress(sc, index);
-            final boolean muted = isMuted(streamType);
-            updateSliderEnabled(sc, muted, (flags & AudioManager.FLAG_FIXED_VOLUME) != 0);
-            if (isNotificationOrRing(streamType)) {
-                // check for secondary-icon transition completion
-                if (mSecondaryIconTransition.isRunning()) {
-                    mSecondaryIconTransition.cancel();  // safe to reset
-                    sc.seekbarView.setAlpha(0); sc.seekbarView.animate().alpha(1);
-                    mZenPanel.setAlpha(0); mZenPanel.animate().alpha(1);
-                }
-                updateSliderIcon(sc, muted);
-            }
-        }
-
-        if (!isShowing()) {
-            int stream = (streamType == STREAM_REMOTE_MUSIC) ? -1 : streamType;
-            // when the stream is for remote playback, use -1 to reset the stream type evaluation
-            mAudioManager.forceVolumeControlStream(stream);
-            mDialog.show();
-            if (mCallback != null) {
-                mCallback.onVisible(true);
-            }
-            announceDialogShown();
-        }
-
-        // Do a little vibrate if applicable (only when going into vibrate mode)
-        if ((streamType != STREAM_REMOTE_MUSIC) &&
-                ((flags & AudioManager.FLAG_VIBRATE) != 0) &&
-                isNotificationOrRing(streamType) &&
-                mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE) {
-            sendMessageDelayed(obtainMessage(MSG_VIBRATE), VIBRATE_DELAY);
-        }
-
-        // Pulse the zen icon if an adjustment was suppressed due to silent mode.
-        if ((flags & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {
-            showSilentHint();
-        }
-
-        // Pulse the slider icon & vibrate if an adjustment down was suppressed due to vibrate mode.
-        if ((flags & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) {
-            showVibrateHint();
-        }
-    }
-
-    private void announceDialogShown() {
-        mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
-    }
-
-    private boolean isShowing() {
-        return mDialog.isShowing();
-    }
-
-    protected void onPlaySound(int streamType, int flags) {
-
-        if (hasMessages(MSG_STOP_SOUNDS)) {
-            removeMessages(MSG_STOP_SOUNDS);
-            // Force stop right now
-            onStopSounds();
-        }
-
-        synchronized (this) {
-            ToneGenerator toneGen = getOrCreateToneGenerator(streamType);
-            if (toneGen != null) {
-                toneGen.startTone(ToneGenerator.TONE_PROP_BEEP);
-                sendMessageDelayed(obtainMessage(MSG_STOP_SOUNDS), BEEP_DURATION);
-            }
-        }
-    }
-
-    protected void onStopSounds() {
-
-        synchronized (this) {
-            int numStreamTypes = AudioSystem.getNumStreamTypes();
-            for (int i = numStreamTypes - 1; i >= 0; i--) {
-                ToneGenerator toneGen = mToneGenerators[i];
-                if (toneGen != null) {
-                    toneGen.stopTone();
-                }
-            }
-        }
-    }
-
-    protected void onVibrate() {
-
-        // Make sure we ended up in vibrate ringer mode
-        if (mAudioManager.getRingerModeInternal() != AudioManager.RINGER_MODE_VIBRATE) {
-            return;
-        }
-        if (mVibrator != null) {
-            mVibrator.vibrate(VIBRATE_DURATION, VIBRATION_ATTRIBUTES);
-        }
-    }
-
-    protected void onRemoteVolumeChanged(MediaController controller, int flags) {
-        if (LOGD) Log.d(mTag, "onRemoteVolumeChanged(controller:" + controller + ", flags: "
-                + flagsToString(flags) + ")");
-
-        if (((flags & AudioManager.FLAG_SHOW_UI) != 0) || isShowing()) {
-            synchronized (this) {
-                if (mActiveStreamType != STREAM_REMOTE_MUSIC) {
-                    reorderSliders(STREAM_REMOTE_MUSIC);
-                }
-                onShowVolumeChanged(STREAM_REMOTE_MUSIC, flags, controller);
-            }
-        } else {
-            if (LOGD) Log.d(mTag, "not calling onShowVolumeChanged(), no FLAG_SHOW_UI or no UI");
-        }
-
-        removeMessages(MSG_FREE_RESOURCES);
-        sendMessageDelayed(obtainMessage(MSG_FREE_RESOURCES), FREE_DELAY);
-        resetTimeout();
-    }
-
-    protected void onRemoteVolumeUpdateIfShown() {
-        if (LOGD) Log.d(mTag, "onRemoteVolumeUpdateIfShown()");
-        if (isShowing()
-                && (mActiveStreamType == STREAM_REMOTE_MUSIC)
-                && (mStreamControls != null)) {
-            onShowVolumeChanged(STREAM_REMOTE_MUSIC, 0, null);
-        }
-    }
-
-    /**
-     * Clear the current remote stream controller.
-     */
-    private void clearRemoteStreamController() {
-        if (mStreamControls != null) {
-            StreamControl sc = mStreamControls.get(STREAM_REMOTE_MUSIC);
-            if (sc != null) {
-                if (sc.controller != null) {
-                    sc.controller.unregisterCallback(mMediaControllerCb);
-                    sc.controller = null;
-                }
-            }
-        }
-    }
-
-    /**
-     * Handler for MSG_SLIDER_VISIBILITY_CHANGED Hide or show a slider
-     *
-     * @param streamType can be a valid stream type value, or
-     *            VolumePanel.STREAM_MASTER, or VolumePanel.STREAM_REMOTE_MUSIC
-     * @param visible
-     */
-    synchronized protected void onSliderVisibilityChanged(int streamType, int visible) {
-        if (LOGD) Log.d(mTag, "onSliderVisibilityChanged(stream="+streamType+", visi="+visible+")");
-        boolean isVisible = (visible == 1);
-        for (int i = STREAMS.length - 1 ; i >= 0 ; i--) {
-            StreamResources streamRes = STREAMS[i];
-            if (streamRes.streamType == streamType) {
-                streamRes.show = isVisible;
-                if (!isVisible && (mActiveStreamType == streamType)) {
-                    mActiveStreamType = -1;
-                }
-                break;
-            }
-        }
-    }
-
-    protected void onDisplaySafeVolumeWarning(int flags) {
-        if ((flags & (AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_SHOW_UI_WARNINGS)) != 0
-                || isShowing()) {
-            synchronized (sSafetyWarningLock) {
-                if (sSafetyWarning != null) {
-                    return;
-                }
-                sSafetyWarning = new SafetyWarningDialog(mContext, mAudioManager) {
-                    @Override
-                    protected void cleanUp() {
-                        synchronized (sSafetyWarningLock) {
-                            sSafetyWarning = null;
-                        }
-                        forceTimeout(0);
-                        updateStates();
-                    }
-                };
-                sSafetyWarning.show();
-            }
-            updateStates();
-        }
-        if (mAccessibilityManager.isTouchExplorationEnabled()) {
-            removeMessages(MSG_TIMEOUT);
-        } else {
-            updateTimeoutDelay();
-            resetTimeout();
-        }
-    }
-
-    /**
-     * Lock on this VolumePanel instance as long as you use the returned ToneGenerator.
-     */
-    private ToneGenerator getOrCreateToneGenerator(int streamType) {
-        synchronized (this) {
-            if (mToneGenerators[streamType] == null) {
-                try {
-                    mToneGenerators[streamType] = new ToneGenerator(streamType, MAX_VOLUME);
-                } catch (RuntimeException e) {
-                    if (LOGD) {
-                        Log.d(mTag, "ToneGenerator constructor failed with "
-                                + "RuntimeException: " + e);
-                    }
-                }
-            }
-            return mToneGenerators[streamType];
-        }
-    }
-
-
-    /**
-     * Switch between icons because Bluetooth music is same as music volume, but with
-     * different icons.
-     */
-    private void setMusicIcon(int resId, int resMuteId) {
-        StreamControl sc = mStreamControls.get(AudioManager.STREAM_MUSIC);
-        if (sc != null) {
-            sc.iconRes = resId;
-            sc.iconMuteRes = resMuteId;
-            updateSliderIcon(sc, isMuted(sc.streamType));
-        }
-    }
-
-    protected void onFreeResources() {
-        synchronized (this) {
-            for (int i = mToneGenerators.length - 1; i >= 0; i--) {
-                if (mToneGenerators[i] != null) {
-                    mToneGenerators[i].release();
-                }
-                mToneGenerators[i] = null;
-            }
-        }
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        switch (msg.what) {
-
-            case MSG_VOLUME_CHANGED: {
-                onVolumeChanged(msg.arg1, msg.arg2);
-                break;
-            }
-
-            case MSG_MUTE_CHANGED: {
-                onMuteChanged(msg.arg1, msg.arg2);
-                break;
-            }
-
-            case MSG_FREE_RESOURCES: {
-                onFreeResources();
-                break;
-            }
-
-            case MSG_STOP_SOUNDS: {
-                onStopSounds();
-                break;
-            }
-
-            case MSG_PLAY_SOUND: {
-                onPlaySound(msg.arg1, msg.arg2);
-                break;
-            }
-
-            case MSG_VIBRATE: {
-                onVibrate();
-                break;
-            }
-
-            case MSG_TIMEOUT: {
-                if (isShowing()) {
-                    mDialog.dismiss();
-                    clearRemoteStreamController();
-                    mActiveStreamType = -1;
-                    if (mCallback != null) {
-                        mCallback.onVisible(false);
-                    }
-                }
-                synchronized (sSafetyWarningLock) {
-                    if (sSafetyWarning != null) {
-                        if (LOGD) Log.d(mTag, "SafetyWarning timeout");
-                        sSafetyWarning.dismiss();
-                    }
-                }
-                break;
-            }
-
-            case MSG_RINGER_MODE_CHANGED:
-            case MSG_INTERNAL_RINGER_MODE_CHANGED:
-            case MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED: {
-                if (isShowing()) {
-                    updateActiveSlider();
-                }
-                break;
-            }
-
-            case MSG_REMOTE_VOLUME_CHANGED: {
-                onRemoteVolumeChanged((MediaController) msg.obj, msg.arg1);
-                break;
-            }
-
-            case MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN:
-                onRemoteVolumeUpdateIfShown();
-                break;
-
-            case MSG_SLIDER_VISIBILITY_CHANGED:
-                onSliderVisibilityChanged(msg.arg1, msg.arg2);
-                break;
-
-            case MSG_DISPLAY_SAFE_VOLUME_WARNING:
-                onDisplaySafeVolumeWarning(msg.arg1);
-                break;
-
-            case MSG_LAYOUT_DIRECTION:
-                setLayoutDirection(msg.arg1);
-                break;
-
-            case MSG_ZEN_MODE_AVAILABLE_CHANGED:
-                mZenModeAvailable = msg.arg1 != 0;
-                updateZenPanelVisible();
-                break;
-
-            case MSG_USER_ACTIVITY:
-                if (mCallback != null) {
-                    mCallback.onInteraction();
-                }
-                break;
-        }
-    }
-
-    private void resetTimeout() {
-        final boolean touchExploration = mAccessibilityManager.isTouchExplorationEnabled();
-        if (LOGD) Log.d(mTag, "resetTimeout at " + System.currentTimeMillis()
-                + " delay=" + mTimeoutDelay + " touchExploration=" + touchExploration);
-        if (sSafetyWarning == null || !touchExploration) {
-            removeMessages(MSG_TIMEOUT);
-            sendEmptyMessageDelayed(MSG_TIMEOUT, mTimeoutDelay);
-            removeMessages(MSG_USER_ACTIVITY);
-            sendEmptyMessage(MSG_USER_ACTIVITY);
-        }
-    }
-
-    private void forceTimeout(long delay) {
-        if (LOGD) Log.d(mTag, "forceTimeout delay=" + delay + " callers=" + Debug.getCallers(3));
-        removeMessages(MSG_TIMEOUT);
-        sendEmptyMessageDelayed(MSG_TIMEOUT, delay);
-    }
-
-    public ZenModeController getZenController() {
-        return mZenController;
-    }
-
-    @Override
-    public void dispatchDemoCommand(String command, Bundle args) {
-        if (!COMMAND_VOLUME.equals(command)) return;
-        String icon = args.getString("icon");
-        final String iconMute = args.getString("iconmute");
-        final boolean mute = iconMute != null;
-        icon = mute ? iconMute : icon;
-        icon = icon.endsWith("Stream") ? icon : (icon + "Stream");
-        final StreamResources sr = StreamResources.valueOf(icon);
-        mDemoIcon = mute ? sr.iconMuteRes : sr.iconRes;
-        final int forcedStreamType = StreamResources.MediaStream.streamType;
-        mAudioManager.forceVolumeControlStream(forcedStreamType);
-        mAudioManager.adjustStreamVolume(forcedStreamType, AudioManager.ADJUST_SAME,
-                AudioManager.FLAG_SHOW_UI);
-    }
-
-    private final OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
-        @Override
-        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-            final Object tag = seekBar.getTag();
-            if (fromUser && tag instanceof StreamControl) {
-                StreamControl sc = (StreamControl) tag;
-                setStreamVolume(sc, progress + sc.minVolume,
-                        AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE);
-            }
-            resetTimeout();
-        }
-
-        @Override
-        public void onStartTrackingTouch(SeekBar seekBar) {
-        }
-
-        @Override
-        public void onStopTrackingTouch(SeekBar seekBar) {
-        }
-    };
-
-    private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() {
-        @Override
-        public void onZenAvailableChanged(boolean available) {
-            obtainMessage(MSG_ZEN_MODE_AVAILABLE_CHANGED, available ? 1 : 0, 0).sendToTarget();
-        }
-
-        @Override
-        public void onEffectsSupressorChanged() {
-            mNotificationEffectsSuppressor = mZenController.getEffectsSuppressor();
-            sendEmptyMessage(MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED);
-        }
-    };
-
-    private final MediaController.Callback mMediaControllerCb = new MediaController.Callback() {
-        public void onAudioInfoChanged(PlaybackInfo info) {
-            onRemoteVolumeUpdateIfShown();
-        }
-    };
-
-    private final class SecondaryIconTransition extends AnimatorListenerAdapter
-            implements Runnable {
-        private static final int ANIMATION_TIME = 400;
-        private static final int WAIT_FOR_SWITCH_TIME = 1000;
-
-        private final int mAnimationTime = (int)(ANIMATION_TIME * ValueAnimator.getDurationScale());
-        private final int mFadeOutTime = mAnimationTime / 2;
-        private final int mDelayTime = mAnimationTime / 3;
-
-        private final Interpolator mIconInterpolator =
-                AnimationUtils.loadInterpolator(mContext, android.R.interpolator.fast_out_slow_in);
-
-        private StreamControl mTarget;
-
-        public void start(StreamControl sc) {
-            if (sc == null) throw new IllegalArgumentException();
-            if (LOGD) Log.d(mTag, "Secondary icon animation start");
-            if (mTarget != null) {
-                cancel();
-            }
-            mTarget = sc;
-            mTimeoutDelay = mAnimationTime + WAIT_FOR_SWITCH_TIME;
-            resetTimeout();
-            mTarget.secondaryIcon.setClickable(false);
-            final int N = mTarget.group.getChildCount();
-            for (int i = 0; i < N; i++) {
-                final View child = mTarget.group.getChildAt(i);
-                if (child != mTarget.secondaryIcon) {
-                    child.animate().alpha(0).setDuration(mFadeOutTime).start();
-                }
-            }
-            mTarget.secondaryIcon.animate()
-                    .translationXBy(mTarget.icon.getX() - mTarget.secondaryIcon.getX())
-                    .setInterpolator(mIconInterpolator)
-                    .setStartDelay(mDelayTime)
-                    .setDuration(mAnimationTime - mDelayTime)
-                    .setListener(this)
-                    .start();
-        }
-
-        public boolean isRunning() {
-            return mTarget != null;
-        }
-
-        public void cancel() {
-            if (mTarget == null) return;
-            mTarget.secondaryIcon.setClickable(true);
-            final int N = mTarget.group.getChildCount();
-            for (int i = 0; i < N; i++) {
-                final View child = mTarget.group.getChildAt(i);
-                if (child != mTarget.secondaryIcon) {
-                    child.animate().cancel();
-                    child.setAlpha(1);
-                }
-            }
-            mTarget.secondaryIcon.animate().cancel();
-            mTarget.secondaryIcon.setTranslationX(0);
-            mTarget = null;
-        }
-
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            if (mTarget == null) return;
-            AsyncTask.execute(this);
-        }
-
-        @Override
-        public void run() {
-            if (mTarget == null) return;
-            if (LOGD) Log.d(mTag, "Secondary icon animation complete, show notification slider");
-            mAudioManager.forceVolumeControlStream(StreamResources.NotificationStream.streamType);
-            mAudioManager.adjustStreamVolume(StreamResources.NotificationStream.streamType,
-                    AudioManager.ADJUST_SAME, AudioManager.FLAG_SHOW_UI);
-        }
-    }
-
-    public interface Callback {
-        void onZenSettings();
-        void onZenPrioritySettings();
-        void onInteraction();
-        void onVisible(boolean visible);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelComponent.java
deleted file mode 100644
index b072cab..0000000
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelComponent.java
+++ /dev/null
@@ -1,202 +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 com.android.systemui.volume;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.media.AudioManager;
-import android.media.IRemoteVolumeController;
-import android.media.IVolumeController;
-import android.media.VolumePolicy;
-import android.media.session.ISessionController;
-import android.media.session.MediaController;
-import android.media.session.MediaSessionManager;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.RemoteException;
-
-import com.android.systemui.R;
-import com.android.systemui.SystemUI;
-import com.android.systemui.keyguard.KeyguardViewMediator;
-import com.android.systemui.qs.tiles.DndTile;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
-import com.android.systemui.statusbar.policy.ZenModeController;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Implementation of VolumeComponent backed by the old volume panel.
- */
-public class VolumePanelComponent implements VolumeComponent {
-
-    private final SystemUI mSysui;
-    private final Context mContext;
-    private final Handler mHandler;
-    private final VolumeController mVolumeController;
-    private final RemoteVolumeController mRemoteVolumeController;
-    private final AudioManager mAudioManager;
-    private final MediaSessionManager mMediaSessionManager;
-
-    private VolumePanel mPanel;
-    private int mDismissDelay;
-
-    public VolumePanelComponent(SystemUI sysui, Context context, Handler handler,
-            ZenModeController controller) {
-        mSysui = sysui;
-        mContext = context;
-        mHandler = handler;
-        mAudioManager = context.getSystemService(AudioManager.class);
-        mMediaSessionManager = context.getSystemService(MediaSessionManager.class);
-        mVolumeController = new VolumeController();
-        mRemoteVolumeController = new RemoteVolumeController();
-        mDismissDelay = mContext.getResources().getInteger(R.integer.volume_panel_dismiss_delay);
-        mPanel = new VolumePanel(mContext, controller);
-        mPanel.setCallback(new VolumePanel.Callback() {
-            @Override
-            public void onZenSettings() {
-                mHandler.removeCallbacks(mStartZenSettings);
-                mHandler.post(mStartZenSettings);
-            }
-
-            @Override
-            public void onZenPrioritySettings() {
-                mHandler.removeCallbacks(mStartZenPrioritySettings);
-                mHandler.post(mStartZenPrioritySettings);
-            }
-
-            @Override
-            public void onInteraction() {
-                final KeyguardViewMediator kvm = mSysui.getComponent(KeyguardViewMediator.class);
-                if (kvm != null) {
-                    kvm.userActivity();
-                }
-            }
-
-            @Override
-            public void onVisible(boolean visible) {
-                if (mAudioManager != null && mVolumeController != null) {
-                    mAudioManager.notifyVolumeControllerVisible(mVolumeController, visible);
-                }
-            }
-        });
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (mPanel != null) {
-            mPanel.dump(fd, pw, args);
-        }
-    }
-
-    public void register() {
-        mAudioManager.setVolumeController(mVolumeController);
-        mAudioManager.setVolumePolicy(VolumePolicy.DEFAULT);
-        mMediaSessionManager.setRemoteVolumeController(mRemoteVolumeController);
-        DndTile.setVisible(mContext, false);
-    }
-
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        if (mPanel != null) {
-            mPanel.onConfigurationChanged(newConfig);
-        }
-    }
-
-    @Override
-    public ZenModeController getZenController() {
-        return mPanel.getZenController();
-    }
-
-    @Override
-    public void dispatchDemoCommand(String command, Bundle args) {
-        mPanel.dispatchDemoCommand(command, args);
-    }
-
-    @Override
-    public void dismissNow() {
-        mPanel.postDismiss(0);
-    }
-
-    private void startSettings(Intent intent) {
-        mSysui.getComponent(PhoneStatusBar.class).startActivityDismissingKeyguard(intent,
-                true /* onlyProvisioned */, true /* dismissShade */);
-        mPanel.postDismiss(mDismissDelay);
-    }
-
-    private final Runnable mStartZenSettings = new Runnable() {
-        @Override
-        public void run() {
-            startSettings(ZenModePanel.ZEN_SETTINGS);
-        }
-    };
-
-    private final Runnable mStartZenPrioritySettings = new Runnable() {
-        @Override
-        public void run() {
-            startSettings(ZenModePanel.ZEN_PRIORITY_SETTINGS);
-        }
-    };
-
-    private final class RemoteVolumeController extends IRemoteVolumeController.Stub {
-        @Override
-        public void remoteVolumeChanged(ISessionController binder, int flags)
-                throws RemoteException {
-            MediaController controller = new MediaController(mContext, binder);
-            mPanel.postRemoteVolumeChanged(controller, flags);
-        }
-
-        @Override
-        public void updateRemoteController(ISessionController session) throws RemoteException {
-            mPanel.postRemoteSliderVisibility(session != null);
-            // TODO stash default session in case the slider can be opened other
-            // than by remoteVolumeChanged.
-        }
-    }
-
-    /** For now, simply host an unmodified base volume panel in this process. */
-    private final class VolumeController extends IVolumeController.Stub {
-
-        @Override
-        public void displaySafeVolumeWarning(int flags) throws RemoteException {
-            mPanel.postDisplaySafeVolumeWarning(flags);
-        }
-
-        @Override
-        public void volumeChanged(int streamType, int flags)
-                throws RemoteException {
-            mPanel.postVolumeChanged(streamType, flags);
-        }
-
-        @Override
-        public void masterMuteChanged(int flags) throws RemoteException {
-            // no-op
-        }
-
-        @Override
-        public void setLayoutDirection(int layoutDirection)
-                throws RemoteException {
-            mPanel.postLayoutDirection(layoutDirection);
-        }
-
-        @Override
-        public void dismiss() throws RemoteException {
-            dismissNow();
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index e979786..5f04aaf 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -31,7 +31,6 @@
 import android.media.AudioManager;
 import android.media.session.MediaSessionManager;
 import android.os.Handler;
-import android.os.SystemProperties;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
@@ -52,8 +51,6 @@
     private static final String TAG = "VolumeUI";
     private static boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
 
-    private static final boolean USE_OLD_VOLUME = SystemProperties.getBoolean("volume.old", false);
-
     private final Handler mHandler = new Handler();
     private final Receiver mReceiver = new Receiver();
     private final RestorationNotification mRestorationNotification = new RestorationNotification();
@@ -64,8 +61,7 @@
     private MediaSessionManager mMediaSessionManager;
     private ServiceMonitor mVolumeControllerService;
 
-    private VolumePanelComponent mOldVolume;
-    private VolumeDialogComponent mNewVolume;
+    private VolumeDialogComponent mVolumeComponent;
 
     @Override
     public void start() {
@@ -77,8 +73,7 @@
         mMediaSessionManager = (MediaSessionManager) mContext
                 .getSystemService(Context.MEDIA_SESSION_SERVICE);
         final ZenModeController zenController = new ZenModeControllerImpl(mContext, mHandler);
-        mOldVolume = new VolumePanelComponent(this, mContext, mHandler, zenController);
-        mNewVolume = new VolumeDialogComponent(this, mContext, null, zenController);
+        mVolumeComponent = new VolumeDialogComponent(this, mContext, null, zenController);
         putComponent(VolumeComponent.class, getVolumeComponent());
         mReceiver.start();
         mVolumeControllerService = new ServiceMonitor(TAG, LOGD,
@@ -88,7 +83,7 @@
     }
 
     private VolumeComponent getVolumeComponent() {
-        return USE_OLD_VOLUME ? mOldVolume : mNewVolume;
+        return mVolumeComponent;
     }
 
     @Override
@@ -235,7 +230,7 @@
                     .putExtra(Receiver.EXTRA_COMPONENT, component);
             mNotificationManager.notify(R.id.notification_volumeui,
                     new Notification.Builder(mContext)
-                            .setSmallIcon(R.drawable.ic_ringer_audible)
+                            .setSmallIcon(R.drawable.ic_volume_media)
                             .setWhen(0)
                             .setShowWhen(false)
                             .setOngoing(true)
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
index 16b7033..6cfdfee 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
@@ -24,7 +24,6 @@
  *
  * BLAS
  *
- * @hide
  **/
 public final class ScriptIntrinsicBLAS extends ScriptIntrinsic {
     private Allocation mLUT;
@@ -1492,7 +1491,6 @@
      *
      * 8-bit GEMM-like operation for neural networks
      *
-     * @hide
      **/
     public void BNNM(Allocation A, int a_offset, Allocation B, int b_offset, Allocation C, int c_offset, int c_mult) {
         validateL3(Element.U8(mRS), NO_TRANSPOSE, TRANSPOSE, 0, A, B, C);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f25808b..b658932 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7851,6 +7851,27 @@
         rti.lastActiveTime = tr.lastActiveTime;
         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
+        rti.numActivities = 0;
+
+        ActivityRecord base = null;
+        ActivityRecord top = null;
+        ActivityRecord tmp;
+
+        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
+            tmp = tr.mActivities.get(i);
+            if (tmp.finishing) {
+                continue;
+            }
+            base = tmp;
+            if (top == null || (top.state == ActivityState.INITIALIZING)) {
+                top = base;
+            }
+            rti.numActivities++;
+        }
+
+        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
+        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
+
         return rti;
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 6210d60..5b1543e 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -16,7 +16,7 @@
 
 package com.android.server.am;
 
-import static android.content.pm.ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN;
+import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
 
 import static com.android.server.am.ActivityManagerDebugConfig.*;
 
@@ -375,7 +375,7 @@
     }
 
     boolean okToShowLocked(ActivityRecord r) {
-        return isCurrentProfileLocked(r.userId) || (r.info.flags & FLAG_SHOW_ON_LOCK_SCREEN) != 0;
+        return isCurrentProfileLocked(r.userId) || (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0;
     }
 
     final ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
@@ -624,7 +624,7 @@
 
             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                 ActivityRecord r = activities.get(activityNdx);
-                if (notCurrentUserTask && (r.info.flags & FLAG_SHOW_ON_LOCK_SCREEN) == 0) {
+                if (notCurrentUserTask && (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) == 0) {
                     return null;
                 }
                 if (!r.finishing && r.intent.getComponent().equals(cls) && r.userId == userId) {
@@ -2024,7 +2024,7 @@
         // Now put task at top.
         int taskNdx = mTaskHistory.size();
         final boolean notShownWhenLocked =
-                (newActivity != null && (newActivity.info.flags & FLAG_SHOW_ON_LOCK_SCREEN) == 0)
+                (newActivity != null && (newActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) == 0)
                 || (newActivity == null && task.topRunningActivityLocked(null) == null);
         if (!isCurrentProfileLocked(task.userId) && notShownWhenLocked) {
             // Put non-current user tasks below current user tasks.
@@ -2074,7 +2074,7 @@
                         r.putInHistory();
                         mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
                                 r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
-                                (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
+                                (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0,
                                 r.userId, r.info.configChanges, task.voiceSession != null,
                                 r.mLaunchTaskBehind);
                         if (VALIDATE_TOKENS) {
@@ -2138,7 +2138,7 @@
             }
             mWindowManager.addAppToken(task.mActivities.indexOf(r),
                     r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
-                    (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId,
+                    (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
                     r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
             boolean doShow = true;
             if (newTask) {
@@ -2190,7 +2190,7 @@
             // because there is nothing for it to animate on top of.
             mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
                     r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
-                    (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId,
+                    (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
                     r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
             ActivityOptions.abort(options);
             options = null;
@@ -4061,6 +4061,7 @@
             }
             ActivityRecord r = null;
             ActivityRecord top = null;
+            ActivityRecord tmp;
             int numActivities = 0;
             int numRunning = 0;
             final ArrayList<ActivityRecord> activities = task.mActivities;
@@ -4068,7 +4069,11 @@
                 continue;
             }
             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
-                r = activities.get(activityNdx);
+                tmp = activities.get(activityNdx);
+                if (tmp.finishing) {
+                    continue;
+                }
+                r = tmp;
 
                 // Initialize state for next task if needed.
                 if (top == null || (top.state == ActivityState.INITIALIZING)) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 6908483..58bdc28 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2826,7 +2826,7 @@
             final ActivityRecord r = activities.get(activityNdx);
             mWindowManager.addAppToken(0, r.appToken, task.taskId, stack.mStackId,
                     r.info.screenOrientation, r.fullscreen,
-                    (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
+                    (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0,
                     r.userId, r.info.configChanges, task.voiceSession != null,
                     r.mLaunchTaskBehind);
         }
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index e16be71..ee36972 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -47,6 +47,10 @@
     // within a transaction from performTraversalInTransactionLocked.
     private Surface mCurrentSurface;
 
+    // DEBUG STATE: Last device info which was written to the log, or null if none.
+    // Do not use for any other purpose.
+    DisplayDeviceInfo mDebugLastLoggedDeviceInfo;
+
     public DisplayDevice(DisplayAdapter displayAdapter, IBinder displayToken, String uniqueId) {
         mDisplayAdapter = displayAdapter;
         mDisplayToken = displayToken;
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index d1e73f0..ebf6e4e 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -104,6 +104,16 @@
     public static final int TOUCH_EXTERNAL = 2;
 
     /**
+     * Diff result: The {@link #state} fields differ.
+     */
+    public static final int DIFF_STATE = 1 << 0;
+
+    /**
+     * Diff result: Other fields differ.
+     */
+    public static final int DIFF_OTHER = 1 << 1;
+
+    /**
      * Gets the name of the display device, which may be derived from EDID or
      * other sources. The name may be localized and displayed to the user.
      */
@@ -238,26 +248,39 @@
     }
 
     public boolean equals(DisplayDeviceInfo other) {
-        return other != null
-                && Objects.equal(name, other.name)
-                && Objects.equal(uniqueId, other.uniqueId)
-                && width == other.width
-                && height == other.height
-                && refreshRate == other.refreshRate
-                && Arrays.equals(supportedRefreshRates, other.supportedRefreshRates)
-                && densityDpi == other.densityDpi
-                && xDpi == other.xDpi
-                && yDpi == other.yDpi
-                && appVsyncOffsetNanos == other.appVsyncOffsetNanos
-                && presentationDeadlineNanos == other.presentationDeadlineNanos
-                && flags == other.flags
-                && touch == other.touch
-                && rotation == other.rotation
-                && type == other.type
-                && Objects.equal(address, other.address)
-                && state == other.state
-                && ownerUid == other.ownerUid
-                && Objects.equal(ownerPackageName, other.ownerPackageName);
+        return other != null && diff(other) == 0;
+    }
+
+    /**
+     * Computes the difference between display device infos.
+     * Assumes other is not null.
+     */
+    public int diff(DisplayDeviceInfo other) {
+        int diff = 0;
+        if (state != other.state) {
+            diff |= DIFF_STATE;
+        }
+        if (!Objects.equal(name, other.name)
+                || !Objects.equal(uniqueId, other.uniqueId)
+                || width != other.width
+                || height != other.height
+                || refreshRate != other.refreshRate
+                || !Arrays.equals(supportedRefreshRates, other.supportedRefreshRates)
+                || densityDpi != other.densityDpi
+                || xDpi != other.xDpi
+                || yDpi != other.yDpi
+                || appVsyncOffsetNanos != other.appVsyncOffsetNanos
+                || presentationDeadlineNanos != other.presentationDeadlineNanos
+                || flags != other.flags
+                || touch != other.touch
+                || rotation != other.rotation
+                || type != other.type
+                || !Objects.equal(address, other.address)
+                || ownerUid != other.ownerUid
+                || !Objects.equal(ownerPackageName, other.ownerPackageName)) {
+            diff |= DIFF_OTHER;
+        }
+        return diff;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 9ea0444..1e87433 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -668,13 +668,14 @@
     }
 
     private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
+        DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
         if (mDisplayDevices.contains(device)) {
-            Slog.w(TAG, "Attempted to add already added display device: "
-                    + device.getDisplayDeviceInfoLocked());
+            Slog.w(TAG, "Attempted to add already added display device: " + info);
             return;
         }
 
-        Slog.i(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked());
+        Slog.i(TAG, "Display device added: " + info);
+        device.mDebugLastLoggedDeviceInfo = info;
 
         mDisplayDevices.add(device);
         addLogicalDisplayLocked(device);
@@ -687,13 +688,20 @@
 
     private void handleDisplayDeviceChanged(DisplayDevice device) {
         synchronized (mSyncRoot) {
+            DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
             if (!mDisplayDevices.contains(device)) {
-                Slog.w(TAG, "Attempted to change non-existent display device: "
-                        + device.getDisplayDeviceInfoLocked());
+                Slog.w(TAG, "Attempted to change non-existent display device: " + info);
                 return;
             }
 
-            Slog.i(TAG, "Display device changed: " + device.getDisplayDeviceInfoLocked());
+            int diff = device.mDebugLastLoggedDeviceInfo.diff(info);
+            if (diff == DisplayDeviceInfo.DIFF_STATE) {
+                Slog.i(TAG, "Display device changed state: \"" + info.name
+                        + "\", " + Display.stateToString(info.state));
+            } else if (diff != 0) {
+                Slog.i(TAG, "Display device changed: " + info);
+            }
+            device.mDebugLastLoggedDeviceInfo = info;
 
             device.applyPendingDisplayDeviceInfoChangesLocked();
             if (updateLogicalDisplaysLocked()) {
@@ -708,13 +716,14 @@
         }
     }
     private void handleDisplayDeviceRemovedLocked(DisplayDevice device) {
+        DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
         if (!mDisplayDevices.remove(device)) {
-            Slog.w(TAG, "Attempted to remove non-existent display device: "
-                    + device.getDisplayDeviceInfoLocked());
+            Slog.w(TAG, "Attempted to remove non-existent display device: " + info);
             return;
         }
 
-        Slog.i(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked());
+        Slog.i(TAG, "Display device removed: " + info);
+        device.mDebugLastLoggedDeviceInfo = info;
 
         updateLogicalDisplaysLocked();
         scheduleTraversalLocked(false);
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 3bb7818..65dc72f 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -302,7 +302,10 @@
         // multiplying the fractions by the product of their denominators before
         // comparing them.
         int displayRectWidth, displayRectHeight;
-        if (physWidth * displayInfo.logicalHeight
+        if ((displayInfo.flags & Display.FLAG_SCALING_DISABLED) != 0) {
+            displayRectWidth = displayInfo.logicalWidth;
+            displayRectHeight = displayInfo.logicalHeight;
+        } else if (physWidth * displayInfo.logicalHeight
                 < physHeight * displayInfo.logicalWidth) {
             // Letter box.
             displayRectWidth = physWidth;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 4ac2b48..94f8dee 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -913,6 +913,12 @@
         }
     }
 
+    @ServiceThreadOnly
+    boolean isConnected(int portId) {
+        assertRunOnServiceThread();
+        return mService.isConnected(portId);
+    }
+
     private void notifyArcStatusToAudioService(boolean enabled) {
         // Note that we don't set any name to ARC.
         mService.getAudioManager().setWiredDeviceConnectionState(
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 49a96d8..2cbc1b9 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -780,6 +780,12 @@
         return false;
     }
 
+    @ServiceThreadOnly
+    boolean isConnected(int portId) {
+        assertRunOnServiceThread();
+        return mCecController.isConnected(portId);
+    }
+
     void runOnServiceThread(Runnable runnable) {
         mHandler.post(runnable);
     }
diff --git a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
index a944a27..5f2d651 100644
--- a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
+++ b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
@@ -156,10 +156,13 @@
         int index = -1;
         while ((index = removed.nextSetBit(index + 1)) != -1) {
             if (index == Constants.ADDR_AUDIO_SYSTEM) {
-                ++mAvrStatusCount;
-                Slog.w(TAG, "Ack not returned from AVR. count: " + mAvrStatusCount);
-                if (mAvrStatusCount < AVR_COUNT_MAX) {
-                    continue;
+                HdmiDeviceInfo avr = tv().getAvrDeviceInfo();
+                if (avr != null && tv().isConnected(avr.getPortId())) {
+                    ++mAvrStatusCount;
+                    Slog.w(TAG, "Ack not returned from AVR. count: " + mAvrStatusCount);
+                    if (mAvrStatusCount < AVR_COUNT_MAX) {
+                        continue;
+                    }
                 }
             }
             Slog.v(TAG, "Remove device by hot-plug detection:" + index);
diff --git a/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java b/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java
index d200d35..9b4950b 100644
--- a/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java
+++ b/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java
@@ -54,7 +54,7 @@
     boolean start() {
         // Seq #37.
         if (mEnabled) {
-            // Enable ARC status immediately after sending <Report Arc Initiated>.
+            // Enable ARC status immediately before sending <Report Arc Initiated>.
             // If AVR responds with <Feature Abort>, disable ARC status again.
             // This is different from spec that says that turns ARC status to
             // "Enabled" if <Report ARC Initiated> is acknowledged and no
@@ -80,12 +80,21 @@
         sendCommand(command, new HdmiControlService.SendMessageCallback() {
             @Override
             public void onSendCompleted(int error) {
-                if (error != Constants.SEND_RESULT_SUCCESS) {
-                    // If fails to send <Report ARC Initiated>, disable ARC and
-                    // send <Report ARC Terminated> directly.
-                    setArcStatus(false);
-                    HdmiLogger.debug("Failed to send <Report Arc Initiated>.");
-                    finish();
+                switch (error) {
+                    case Constants.SEND_RESULT_SUCCESS:
+                    case Constants.SEND_RESULT_BUSY:
+                    case Constants.SEND_RESULT_FAILURE:
+                        // The result of the command transmission, unless it is an obvious
+                        // failure indicated by the target device (or lack thereof), should
+                        // not affect the ARC status. Ignores it silently.
+                        break;
+                    case Constants.SEND_RESULT_NAK:
+                        // If <Report ARC Initiated> is negatively ack'ed, disable ARC and
+                        // send <Report ARC Terminated> directly.
+                        setArcStatus(false);
+                        HdmiLogger.debug("Failed to send <Report Arc Initiated>.");
+                        finish();
+                        break;
                 }
             }
         });
diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java
index 23d5c05..98fb11b 100644
--- a/services/core/java/com/android/server/job/controllers/AppIdleController.java
+++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java
@@ -107,7 +107,16 @@
 
     @Override
     public void dumpControllerState(PrintWriter pw) {
-        // TODO:
+        pw.println("AppIdle");
+        pw.println("Plugged In: " + mPluggedIn);
+        synchronized (mTrackedTasks) {
+            for (JobStatus task : mTrackedTasks) {
+                pw.print(task.job.getService().getPackageName());
+                pw.print(":idle=" + !task.appNotIdleConstraintSatisfied.get());
+                pw.print(", ");
+            }
+            pw.println();
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 7c41abbc..a279e0f 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -197,6 +197,8 @@
     private static final int REMOVE_LISTENER = 9;
     private static final int INJECT_NTP_TIME_FINISHED = 10;
     private static final int DOWNLOAD_XTRA_DATA_FINISHED = 11;
+    private static final int SUBSCRIPTION_OR_SIM_CHANGED = 12;
+    private static final int INITIALIZE_HANDLER = 13;
 
     // Request setid
     private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
@@ -338,8 +340,12 @@
     // True if gps should be disabled (used to support battery saver mode in settings).
     private boolean mDisableGps = false;
 
-    // properties loaded from PROPERTIES_FILE
+    /**
+     * Properties loaded from PROPERTIES_FILE.
+     * It must be accessed only inside {@link #mHandler}.
+     */
     private Properties mProperties;
+
     private String mSuplServerHost;
     private int mSuplServerPort = TCP_MIN_PORT;
     private String mC2KServerHost;
@@ -462,7 +468,7 @@
             new OnSubscriptionsChangedListener() {
         @Override
         public void onSubscriptionsChanged() {
-            subscriptionOrSimChanged(mContext);
+            sendMessage(SUBSCRIPTION_OR_SIM_CHANGED, 0, null);
         }
     };
 
@@ -627,53 +633,22 @@
         mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
                 BatteryStats.SERVICE_NAME));
 
-        // Load GPS configuration.
+        // Construct internal handler
+        mHandler = new ProviderHandler(looper);
+
+        // Load GPS configuration and register listeners in the background:
+        // some operations, such as opening files and registering broadcast receivers, can take a
+        // relative long time, so the ctor() is kept to create objects needed by this instance,
+        // while IO initialization and registration is delegated to our internal handler
+        // this approach is just fine because events are posted to our handler anyway
         mProperties = new Properties();
-        reloadGpsProperties(mContext, mProperties);
+        sendMessage(INITIALIZE_HANDLER, 0, null);
 
         // Create a GPS net-initiated handler.
         mNIHandler = new GpsNetInitiatedHandler(context,
                                                 mNetInitiatedListener,
                                                 mSuplEsEnabled);
 
-        // TODO: When this object "finishes" we should unregister by invoking
-        // SubscriptionManager.getInstance(mContext).unregister(mOnSubscriptionsChangedListener);
-        // This is not strictly necessary because it will be unregistered if the
-        // notification fails but it is good form.
-
-        // Register for SubscriptionInfo list changes which is guaranteed
-        // to invoke onSubscriptionsChanged the first time.
-        SubscriptionManager.from(mContext)
-            .addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
-
-        // construct handler, listen for events
-        mHandler = new ProviderHandler(looper);
-        listenForBroadcasts();
-
-        // also listen for PASSIVE_PROVIDER updates
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                LocationManager locManager =
-                        (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
-                final long minTime = 0;
-                final float minDistance = 0;
-                final boolean oneShot = false;
-                LocationRequest request = LocationRequest.createFromDeprecatedProvider(
-                        LocationManager.PASSIVE_PROVIDER,
-                        minTime,
-                        minDistance,
-                        oneShot);
-                // Don't keep track of this request since it's done on behalf of other clients
-                // (which are kept track of separately).
-                request.setHideFromAppOps(true);
-                locManager.requestLocationUpdates(
-                        request,
-                        new NetworkLocationListener(),
-                        mHandler.getLooper());
-            }
-        });
-
         mListenerHelper = new GpsStatusListenerHelper(mHandler) {
             @Override
             protected boolean isAvailableInPlatform() {
@@ -731,33 +706,6 @@
         };
     }
 
-    private void listenForBroadcasts() {
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
-        intentFilter.addDataScheme("sms");
-        intentFilter.addDataAuthority("localhost","7275");
-        mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, mHandler);
-
-        intentFilter = new IntentFilter();
-        intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
-        try {
-            intentFilter.addDataType("application/vnd.omaloc-supl-init");
-        } catch (IntentFilter.MalformedMimeTypeException e) {
-            Log.w(TAG, "Malformed SUPL init mime type");
-        }
-        mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, mHandler);
-
-        intentFilter = new IntentFilter();
-        intentFilter.addAction(ALARM_WAKEUP);
-        intentFilter.addAction(ALARM_TIMEOUT);
-        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE);
-        intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
-        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
-        intentFilter.addAction(Intent.ACTION_SCREEN_ON);
-        intentFilter.addAction(SIM_STATE_CHANGED);
-        mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, mHandler);
-    }
-
     /**
      * Returns the name of this provider.
      */
@@ -2012,13 +1960,85 @@
                 case UPDATE_LOCATION:
                     handleUpdateLocation((Location)msg.obj);
                     break;
+                case SUBSCRIPTION_OR_SIM_CHANGED:
+                    subscriptionOrSimChanged(mContext);
+                    break;
+                case INITIALIZE_HANDLER:
+                    initialize();
+                    break;
             }
             if (msg.arg2 == 1) {
                 // wakelock was taken for this message, release it
                 mWakeLock.release();
             }
         }
-    };
+
+        /**
+         * This method is bound to {@link #GpsLocationProvider(Context, ILocationManager, Looper)}.
+         * It is in charge of loading properties and registering for events that will be posted to
+         * this handler.
+         */
+        private void initialize() {
+            // load default GPS configuration
+            // (this configuration might change in the future based on SIM changes)
+            reloadGpsProperties(mContext, mProperties);
+
+            // TODO: When this object "finishes" we should unregister by invoking
+            // SubscriptionManager.getInstance(mContext).unregister(mOnSubscriptionsChangedListener);
+            // This is not strictly necessary because it will be unregistered if the
+            // notification fails but it is good form.
+
+            // Register for SubscriptionInfo list changes which is guaranteed
+            // to invoke onSubscriptionsChanged the first time.
+            SubscriptionManager.from(mContext)
+                    .addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
+
+            // listen for events
+            IntentFilter intentFilter = new IntentFilter();
+            intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
+            intentFilter.addDataScheme("sms");
+            intentFilter.addDataAuthority("localhost","7275");
+            mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
+
+            intentFilter = new IntentFilter();
+            intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
+            try {
+                intentFilter.addDataType("application/vnd.omaloc-supl-init");
+            } catch (IntentFilter.MalformedMimeTypeException e) {
+                Log.w(TAG, "Malformed SUPL init mime type");
+            }
+            mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
+
+            intentFilter = new IntentFilter();
+            intentFilter.addAction(ALARM_WAKEUP);
+            intentFilter.addAction(ALARM_TIMEOUT);
+            intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE);
+            intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
+            intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
+            intentFilter.addAction(Intent.ACTION_SCREEN_ON);
+            intentFilter.addAction(SIM_STATE_CHANGED);
+            mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
+
+            // listen for PASSIVE_PROVIDER updates
+            LocationManager locManager =
+                    (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
+            long minTime = 0;
+            float minDistance = 0;
+            boolean oneShot = false;
+            LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+                    LocationManager.PASSIVE_PROVIDER,
+                    minTime,
+                    minDistance,
+                    oneShot);
+            // Don't keep track of this request since it's done on behalf of other clients
+            // (which are kept track of separately).
+            request.setHideFromAppOps(true);
+            locManager.requestLocationUpdates(
+                    request,
+                    new NetworkLocationListener(),
+                    getLooper());
+        }
+    }
 
     private final class NetworkLocationListener implements LocationListener {
         @Override
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index a04f6cb..e914cd4 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -56,7 +56,7 @@
     boolean appFullscreen;
     int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
     boolean layoutConfigChanges;
-    boolean showWhenLocked;
+    boolean showForAllUsers;
 
     // The input dispatching timeout for this application token in nanoseconds.
     long inputDispatchingTimeoutNanos;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index f073c23..f914369 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -66,6 +66,7 @@
     int mBaseDisplayWidth = 0;
     int mBaseDisplayHeight = 0;
     int mBaseDisplayDensity = 0;
+    boolean mDisplayScalingDisabled;
     private final DisplayInfo mDisplayInfo = new DisplayInfo();
     private final Display mDisplay;
 
@@ -360,6 +361,9 @@
                 pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
                 pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi");
             }
+            if (mDisplayScalingDisabled) {
+                pw.println(" noscale");
+            }
             pw.print(" cur=");
             pw.print(mDisplayInfo.logicalWidth);
             pw.print("x"); pw.print(mDisplayInfo.logicalHeight);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 34120a0..0c3cf65 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -107,9 +107,9 @@
         }
     }
 
-    boolean showWhenLocked() {
+    boolean showForAllUsers() {
         final int tokensCount = mAppTokens.size();
-        return (tokensCount != 0) && mAppTokens.get(tokensCount - 1).showWhenLocked;
+        return (tokensCount != 0) && mAppTokens.get(tokensCount - 1).showForAllUsers;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index e845f83..7cdf8b2 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -276,27 +276,26 @@
     }
 
     void addTask(Task task, boolean toTop) {
-        addTask(task, toTop, task.showWhenLocked());
+        addTask(task, toTop, task.showForAllUsers());
     }
 
     /**
      * Put a Task in this stack. Used for adding and moving.
      * @param task The task to add.
      * @param toTop Whether to add it to the top or bottom.
-     * @param showWhenLocked Whether to show the task when the device is locked
-     *                       regardless of the current user.
+     * @param showForAllUsers Whether to show the task regardless of the current user.
      */
-    void addTask(Task task, boolean toTop, boolean showWhenLocked) {
+    void addTask(Task task, boolean toTop, boolean showForAllUsers) {
         int stackNdx;
         if (!toTop) {
             stackNdx = 0;
         } else {
             stackNdx = mTasks.size();
-            if (!showWhenLocked && !mService.isCurrentProfileLocked(task.mUserId)) {
+            if (!showForAllUsers && !mService.isCurrentProfileLocked(task.mUserId)) {
                 // Place the task below all current user tasks.
                 while (--stackNdx >= 0) {
                     final Task tmpTask = mTasks.get(stackNdx);
-                    if (!tmpTask.showWhenLocked()
+                    if (!tmpTask.showForAllUsers()
                             || !mService.isCurrentProfileLocked(tmpTask.mUserId)) {
                         break;
                     }
@@ -498,7 +497,7 @@
         int top = mTasks.size();
         for (int taskNdx = 0; taskNdx < top; ++taskNdx) {
             Task task = mTasks.get(taskNdx);
-            if (mService.isCurrentProfileLocked(task.mUserId) || task.showWhenLocked()) {
+            if (mService.isCurrentProfileLocked(task.mUserId) || task.showForAllUsers()) {
                 mTasks.remove(taskNdx);
                 mTasks.add(task);
                 --top;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index e790fb0..964dcc2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3620,13 +3620,13 @@
         EventLog.writeEvent(EventLogTags.WM_TASK_CREATED, taskId, stackId);
         Task task = new Task(taskId, stack, userId, this);
         mTaskIdToTask.put(taskId, task);
-        stack.addTask(task, !atoken.mLaunchTaskBehind /* toTop */, atoken.showWhenLocked);
+        stack.addTask(task, !atoken.mLaunchTaskBehind /* toTop */, atoken.showForAllUsers);
         return task;
     }
 
     @Override
     public void addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
-            int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId,
+            int requestedOrientation, boolean fullscreen, boolean showForAllUsers, int userId,
             int configChanges, boolean voiceInteraction, boolean launchTaskBehind) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "addAppToken()")) {
@@ -3656,7 +3656,7 @@
             atoken = new AppWindowToken(this, token, voiceInteraction);
             atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
             atoken.appFullscreen = fullscreen;
-            atoken.showWhenLocked = showWhenLocked;
+            atoken.showForAllUsers = showForAllUsers;
             atoken.requestedOrientation = requestedOrientation;
             atoken.layoutConfigChanges = (configChanges &
                     (ActivityInfo.CONFIG_SCREEN_SIZE | ActivityInfo.CONFIG_ORIENTATION)) != 0;
@@ -7249,8 +7249,15 @@
             displayInfo.getLogicalMetrics(mRealDisplayMetrics,
                     CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
             displayInfo.getAppMetrics(mDisplayMetrics);
+            if (displayContent.mDisplayScalingDisabled) {
+                displayInfo.flags |= Display.FLAG_SCALING_DISABLED;
+            } else {
+                displayInfo.flags &= ~Display.FLAG_SCALING_DISABLED;
+            }
+
             mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
                     displayContent.getDisplayId(), displayInfo);
+
             displayContent.mBaseDisplayRect.set(0, 0, dw, dh);
         }
         if (false) {
@@ -7547,7 +7554,7 @@
 
         synchronized(mWindowMap) {
             final DisplayContent displayContent = getDefaultDisplayContentLocked();
-            readForcedDisplaySizeAndDensityLocked(displayContent);
+            readForcedDisplayPropertiesLocked(displayContent);
             mDisplayReady = true;
         }
 
@@ -8320,7 +8327,47 @@
         }
     }
 
-    private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) {
+    @Override
+    public void setForcedDisplayScalingMode(int displayId, int mode) {
+        if (mContext.checkCallingOrSelfPermission(
+                android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
+                PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Must hold permission " +
+                    android.Manifest.permission.WRITE_SECURE_SETTINGS);
+        }
+        if (displayId != Display.DEFAULT_DISPLAY) {
+            throw new IllegalArgumentException("Can only set the default display");
+        }
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized(mWindowMap) {
+                final DisplayContent displayContent = getDisplayContentLocked(displayId);
+                if (displayContent != null) {
+                    if (mode < 0 || mode > 1) {
+                        mode = 0;
+                    }
+                    setForcedDisplayScalingModeLocked(displayContent, mode);
+                    Settings.Global.putInt(mContext.getContentResolver(),
+                            Settings.Global.DISPLAY_SCALING_FORCE, mode);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private void setForcedDisplayScalingModeLocked(DisplayContent displayContent,
+            int mode) {
+        Slog.i(TAG, "Using display scaling mode: " + (mode == 0 ? "auto" : "off"));
+
+        synchronized(displayContent.mDisplaySizeLock) {
+            displayContent.mDisplayScalingDisabled = (mode != 0);
+        }
+        reconfigureDisplayLocked(displayContent);
+    }
+
+    private void readForcedDisplayPropertiesLocked(final DisplayContent displayContent) {
+        // Display size.
         String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
                 Settings.Global.DISPLAY_SIZE_FORCED);
         if (sizeStr == null || sizeStr.length() == 0) {
@@ -8345,6 +8392,8 @@
                 }
             }
         }
+
+        // Display density.
         String densityStr = Settings.Global.getString(mContext.getContentResolver(),
                 Settings.Global.DISPLAY_DENSITY_FORCED);
         if (densityStr == null || densityStr.length() == 0) {
@@ -8363,6 +8412,16 @@
             } catch (NumberFormatException ex) {
             }
         }
+
+        // Display scaling mode.
+        int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.DISPLAY_SCALING_FORCE, 0);
+        if (mode != 0) {
+            synchronized(displayContent.mDisplaySizeLock) {
+                Slog.i(TAG, "FORCED DISPLAY SCALING DISABLED");
+                displayContent.mDisplayScalingDisabled = true;
+            }
+        }
     }
 
     // displayContent must not be null
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index db3268d..4f795a6 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -17,6 +17,7 @@
 package com.android.server.wm;
 
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
@@ -478,6 +479,12 @@
         if (mAppToken != null) {
             final DisplayContent appDisplay = getDisplayContent();
             mNotOnAppsDisplay = displayContent != appDisplay;
+
+            if (mAppToken.showForAllUsers) {
+                // Windows for apps that can show for all users should also show when the
+                // device is locked.
+                mAttrs.flags |= FLAG_SHOW_WHEN_LOCKED;
+            }
         }
 
         mWinAnimator = new WindowStateAnimator(this);
@@ -1353,7 +1360,7 @@
             win = win.mAttachedWindow;
         }
         if (win.mAttrs.type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
-                && win.mAppToken != null && win.mAppToken.showWhenLocked) {
+                && win.mAppToken != null && win.mAppToken.showForAllUsers) {
             // Save some cycles by not calling getDisplayInfo unless it is an application
             // window intended for all users.
             final DisplayContent displayContent = win.getDisplayContent();
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 33a7fe1..a46585a 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -16,6 +16,7 @@
 
 package android.telecom;
 
+import android.annotation.SystemApi;
 import android.net.Uri;
 import android.os.Bundle;
 
@@ -233,7 +234,6 @@
         private final int mVideoState;
         private final StatusHints mStatusHints;
         private final Bundle mExtras;
-        private final int mCallSubstate;
 
         /**
          * Whether the supplied capabilities  supports the specified capability.
@@ -430,14 +430,6 @@
             return mExtras;
         }
 
-        /**
-         * @return The substate of the {@code Call}.
-         * @hide
-         */
-        public int getCallSubstate() {
-            return mCallSubstate;
-        }
-
         @Override
         public boolean equals(Object o) {
             if (o instanceof Details) {
@@ -456,8 +448,7 @@
                         Objects.equals(mGatewayInfo, d.mGatewayInfo) &&
                         Objects.equals(mVideoState, d.mVideoState) &&
                         Objects.equals(mStatusHints, d.mStatusHints) &&
-                        Objects.equals(mExtras, d.mExtras) &&
-                        Objects.equals(mCallSubstate, d.mCallSubstate);
+                        Objects.equals(mExtras, d.mExtras);
             }
             return false;
         }
@@ -477,8 +468,7 @@
                     Objects.hashCode(mGatewayInfo) +
                     Objects.hashCode(mVideoState) +
                     Objects.hashCode(mStatusHints) +
-                    Objects.hashCode(mExtras) +
-                    Objects.hashCode(mCallSubstate);
+                    Objects.hashCode(mExtras);
         }
 
         /** {@hide} */
@@ -495,8 +485,7 @@
                 GatewayInfo gatewayInfo,
                 int videoState,
                 StatusHints statusHints,
-                Bundle extras,
-                int callSubstate) {
+                Bundle extras) {
             mHandle = handle;
             mHandlePresentation = handlePresentation;
             mCallerDisplayName = callerDisplayName;
@@ -510,11 +499,10 @@
             mVideoState = videoState;
             mStatusHints = statusHints;
             mExtras = extras;
-            mCallSubstate = callSubstate;
         }
     }
 
-    public static abstract class Listener {
+    public static abstract class Callback {
         /**
          * Invoked when the state of this {@code Call} has changed. See {@link #getState()}.
          *
@@ -598,13 +586,21 @@
         public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {}
     }
 
+    /**
+     * @deprecated Use {@code Call.Callback} instead.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static abstract class Listener extends Callback { }
+
     private final Phone mPhone;
     private final String mTelecomCallId;
     private final InCallAdapter mInCallAdapter;
     private final List<String> mChildrenIds = new ArrayList<>();
     private final List<Call> mChildren = new ArrayList<>();
     private final List<Call> mUnmodifiableChildren = Collections.unmodifiableList(mChildren);
-    private final List<Listener> mListeners = new CopyOnWriteArrayList<>();
+    private final List<Callback> mCallbacks = new CopyOnWriteArrayList<>();
     private final List<Call> mConferenceableCalls = new ArrayList<>();
     private final List<Call> mUnmodifiableConferenceableCalls =
             Collections.unmodifiableList(mConferenceableCalls);
@@ -699,8 +695,8 @@
      * {@code Call} will temporarily pause playing the tones for a pre-defined period of time.
      *
      * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
-     * {@code Call} will pause playing the tones and notify listeners via
-     * {@link Listener#onPostDialWait(Call, String)}. At this point, the in-call app
+     * {@code Call} will pause playing the tones and notify callbacks via
+     * {@link Callback#onPostDialWait(Call, String)}. At this point, the in-call app
      * should display to the user an indication of this state and an affordance to continue
      * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
      * app should invoke the {@link #postDialContinue(boolean)} method.
@@ -841,25 +837,52 @@
     }
 
     /**
+     * Registers a callback to this {@code Call}.
+     *
+     * @param callback A {@code Callback}.
+     */
+    public void registerCallback(Callback callback) {
+        mCallbacks.add(callback);
+    }
+
+    /**
+     * Unregisters a callback from this {@code Call}.
+     *
+     * @param callback A {@code Callback}.
+     */
+    public void unregisterCallback(Callback callback) {
+        if (callback != null) {
+            mCallbacks.remove(callback);
+        }
+    }
+
+    /**
      * Adds a listener to this {@code Call}.
      *
      * @param listener A {@code Listener}.
+     * @deprecated Use {@link #registerCallback} instead.
+     * @hide
      */
+    @Deprecated
+    @SystemApi
     public void addListener(Listener listener) {
-        mListeners.add(listener);
+        registerCallback(listener);
     }
 
     /**
      * Removes a listener from this {@code Call}.
      *
      * @param listener A {@code Listener}.
+     * @deprecated Use {@link #unregisterCallback} instead.
+     * @hide
      */
+    @Deprecated
+    @SystemApi
     public void removeListener(Listener listener) {
-        if (listener != null) {
-            mListeners.remove(listener);
-        }
+        unregisterCallback(listener);
     }
 
+
     /** {@hide} */
     Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter) {
         mPhone = phone;
@@ -889,8 +912,7 @@
                 parcelableCall.getGatewayInfo(),
                 parcelableCall.getVideoState(),
                 parcelableCall.getStatusHints(),
-                parcelableCall.getExtras(),
-                parcelableCall.getCallSubstate());
+                parcelableCall.getExtras());
         boolean detailsChanged = !Objects.equals(mDetails, details);
         if (detailsChanged) {
             mDetails = details;
@@ -991,56 +1013,56 @@
     }
 
     private void fireStateChanged(int newState) {
-        for (Listener listener : mListeners) {
-            listener.onStateChanged(this, newState);
+        for (Callback callback : mCallbacks) {
+            callback.onStateChanged(this, newState);
         }
     }
 
     private void fireParentChanged(Call newParent) {
-        for (Listener listener : mListeners) {
-            listener.onParentChanged(this, newParent);
+        for (Callback callback : mCallbacks) {
+            callback.onParentChanged(this, newParent);
         }
     }
 
     private void fireChildrenChanged(List<Call> children) {
-        for (Listener listener : mListeners) {
-            listener.onChildrenChanged(this, children);
+        for (Callback callback : mCallbacks) {
+            callback.onChildrenChanged(this, children);
         }
     }
 
     private void fireDetailsChanged(Details details) {
-        for (Listener listener : mListeners) {
-            listener.onDetailsChanged(this, details);
+        for (Callback callback : mCallbacks) {
+            callback.onDetailsChanged(this, details);
         }
     }
 
     private void fireCannedTextResponsesLoaded(List<String> cannedTextResponses) {
-        for (Listener listener : mListeners) {
-            listener.onCannedTextResponsesLoaded(this, cannedTextResponses);
+        for (Callback callback : mCallbacks) {
+            callback.onCannedTextResponsesLoaded(this, cannedTextResponses);
         }
     }
 
     private void fireVideoCallChanged(InCallService.VideoCall videoCall) {
-        for (Listener listener : mListeners) {
-            listener.onVideoCallChanged(this, videoCall);
+        for (Callback callback : mCallbacks) {
+            callback.onVideoCallChanged(this, videoCall);
         }
     }
 
     private void firePostDialWait(String remainingPostDialSequence) {
-        for (Listener listener : mListeners) {
-            listener.onPostDialWait(this, remainingPostDialSequence);
+        for (Callback callback : mCallbacks) {
+            callback.onPostDialWait(this, remainingPostDialSequence);
         }
     }
 
     private void fireCallDestroyed() {
-        for (Listener listener : mListeners) {
-            listener.onCallDestroyed(this);
+        for (Callback callback : mCallbacks) {
+            callback.onCallDestroyed(this);
         }
     }
 
     private void fireConferenceableCallsChanged() {
-        for (Listener listener : mListeners) {
-            listener.onConferenceableCallsChanged(this, mUnmodifiableConferenceableCalls);
+        for (Callback callback : mCallbacks) {
+            callback.onConferenceableCallsChanged(this, mUnmodifiableConferenceableCalls);
         }
     }
 
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 4762031..11632dc 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -200,48 +200,6 @@
     // Next CAPABILITY value: 0x00200000
     //**********************************************************************************************
 
-    /**
-     * Call substate bitmask values
-     */
-
-    /* Default case */
-    /**
-     * @hide
-     */
-    public static final int SUBSTATE_NONE = 0;
-
-    /* Indicates that the call is connected but audio attribute is suspended */
-    /**
-     * @hide
-     */
-    public static final int SUBSTATE_AUDIO_CONNECTED_SUSPENDED = 0x1;
-
-    /* Indicates that the call is connected but video attribute is suspended */
-    /**
-     * @hide
-     */
-    public static final int SUBSTATE_VIDEO_CONNECTED_SUSPENDED = 0x2;
-
-    /* Indicates that the call is established but media retry is needed */
-    /**
-     * @hide
-     */
-    public static final int SUBSTATE_AVP_RETRY = 0x4;
-
-    /* Indicates that the call is multitasking */
-    /**
-     * @hide
-     */
-    public static final int SUBSTATE_MEDIA_PAUSED = 0x8;
-
-    /* Mask containing all the call substate bits set */
-    /**
-     * @hide
-     */
-    public static final int SUBSTATE_ALL = SUBSTATE_AUDIO_CONNECTED_SUSPENDED |
-        SUBSTATE_VIDEO_CONNECTED_SUSPENDED | SUBSTATE_AVP_RETRY |
-        SUBSTATE_MEDIA_PAUSED;
-
     // Flag controlling whether PII is emitted into the logs
     private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
 
@@ -380,7 +338,6 @@
         public void onConferenceParticipantsChanged(Connection c,
                 List<ConferenceParticipant> participants) {}
         public void onConferenceStarted() {}
-        public void onCallSubstateChanged(Connection c, int substate) {}
     }
 
     public static abstract class VideoProvider {
@@ -807,7 +764,6 @@
     private DisconnectCause mDisconnectCause;
     private Conference mConference;
     private ConnectionService mConnectionService;
-    private int mCallSubstate;
 
     /**
      * Create a new Connection.
@@ -866,21 +822,6 @@
     }
 
     /**
-     * Returns the call substate of the call.
-     * Valid values: {@link Connection#SUBSTATE_NONE},
-     * {@link Connection#SUBSTATE_AUDIO_CONNECTED_SUSPENDED},
-     * {@link Connection#SUBSTATE_VIDEO_CONNECTED_SUSPENDED},
-     * {@link Connection#SUBSTATE_AVP_RETRY},
-     * {@link Connection#SUBSTATE_MEDIA_PAUSED}.
-     *
-     * @param callSubstate The new call substate.
-     * @hide
-     */
-    public final int getCallSubstate() {
-        return mCallSubstate;
-    }
-
-    /**
      * @return The audio state of the connection, describing how its audio is currently
      *         being routed by the system. This is {@code null} if this Connection
      *         does not directly know about its audio state.
@@ -1054,25 +995,6 @@
     }
 
     /**
-     * Set the call substate for the connection.
-     * Valid values: {@link Connection#SUBSTATE_NONE},
-     * {@link Connection#SUBSTATE_AUDIO_CONNECTED_SUSPENDED},
-     * {@link Connection#SUBSTATE_VIDEO_CONNECTED_SUSPENDED},
-     * {@link Connection#SUBSTATE_AVP_RETRY},
-     * {@link Connection#SUBSTATE_MEDIA_PAUSED}.
-     *
-     * @param callSubstate The new call substate.
-     * @hide
-     */
-    public final void setCallSubstate(int callSubstate) {
-        Log.d(this, "setCallSubstate %d", callSubstate);
-        mCallSubstate = callSubstate;
-        for (Listener l : mListeners) {
-            l.onCallSubstateChanged(this, mCallSubstate);
-        }
-    }
-
-    /**
      * Sets state to active (e.g., an ongoing connection where two or more parties can actively
      * communicate).
      */
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index e36d32b..73d1644 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -556,13 +556,6 @@
                 mAdapter.setIsConferenced(id, conferenceId);
             }
         }
-
-        @Override
-        public void onCallSubstateChanged(Connection c, int callSubstate) {
-            String id = mIdByConnection.get(c);
-            Log.d(this, "Adapter set call substate %d", callSubstate);
-            mAdapter.setCallSubstate(id, callSubstate);
-        }
     };
 
     /** {@inheritDoc} */
@@ -632,8 +625,7 @@
                         connection.getAudioModeIsVoip(),
                         connection.getStatusHints(),
                         connection.getDisconnectCause(),
-                        createIdList(connection.getConferenceables()),
-                        connection.getCallSubstate()));
+                        createIdList(connection.getConferenceables())));
     }
 
     private void abort(String callId) {
@@ -956,7 +948,7 @@
                     connection.getAudioModeIsVoip(),
                     connection.getStatusHints(),
                     connection.getDisconnectCause(),
-                    emptyList, connection.getCallSubstate());
+                    emptyList);
             mAdapter.addExistingConnection(id, parcelableConnection);
         }
     }
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
index a410976..d026a28 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
@@ -369,26 +369,4 @@
             }
         }
     }
-
-    /**
-     * Set the call substate for the connection.
-     * Valid values: {@link Connection#CALL_SUBSTATE_NONE},
-     * {@link Connection#CALL_SUBSTATE_AUDIO_CONNECTED_SUSPENDED},
-     * {@link Connection#CALL_SUBSTATE_VIDEO_CONNECTED_SUSPENDED},
-     * {@link Connection#CALL_SUBSTATE_AVP_RETRY},
-     * {@link Connection#CALL_SUBSTATE_MEDIA_PAUSED}.
-     *
-     * @param callId The unique ID of the call to set the substate for.
-     * @param callSubstate The new call substate.
-     * @hide
-     */
-    public final void setCallSubstate(String callId, int callSubstate) {
-        Log.v(this, "setCallSubstate: %d", callSubstate);
-        for (IConnectionServiceAdapter adapter : mAdapters) {
-            try {
-                adapter.setCallSubstate(callId, callSubstate);
-            } catch (RemoteException ignored) {
-            }
-        }
-    }
 }
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
index 5f93789..429f296 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
@@ -59,7 +59,6 @@
     private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 20;
     private static final int MSG_ADD_EXISTING_CONNECTION = 21;
     private static final int MSG_ON_POST_DIAL_CHAR = 22;
-    private static final int MSG_SET_CALL_SUBSTATE = 23;
 
     private final IConnectionServiceAdapter mDelegate;
 
@@ -221,10 +220,6 @@
                     }
                     break;
                 }
-                case MSG_SET_CALL_SUBSTATE: {
-                    mDelegate.setCallSubstate((String) msg.obj, msg.arg1);
-                    break;
-                }
             }
         }
     };
@@ -389,12 +384,6 @@
             args.arg2 = connection;
             mHandler.obtainMessage(MSG_ADD_EXISTING_CONNECTION, args).sendToTarget();
         }
-
-        @Override
-        public void setCallSubstate(String connectionId, int callSubstate) {
-            mHandler.obtainMessage(MSG_SET_CALL_SUBSTATE, callSubstate, 0,
-                connectionId).sendToTarget();
-        }
     };
 
     public ConnectionServiceAdapterServant(IConnectionServiceAdapter delegate) {
diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java
index 8d6ae82..07ba6fb 100644
--- a/telecomm/java/android/telecom/InCallService.java
+++ b/telecomm/java/android/telecom/InCallService.java
@@ -363,12 +363,19 @@
     public static abstract class VideoCall {
 
         /**
-         * Sets a listener to invoke callback methods in the InCallUI after performing video
-         * telephony actions.
+         * Registers a callback to receive c ommands and state changes for video calls.
          *
-         * @param videoCallListener The call video client.
+         * @param callback The vdieo call callback.
          */
-        public abstract void setVideoCallListener(VideoCall.Listener videoCallListener);
+        public abstract void registerCallback(VideoCall.Callback callback);
+
+        /**
+         * @deprecated Use {@code VideoCall#registerCallback} instead.
+         */
+        @Deprecated
+        public void setVideoCallListener(VideoCall.Listener videoCallListener) {
+            registerCallback(videoCallListener);
+        }
 
         /**
          * Sets the camera to be used for video recording in a video call.
@@ -411,7 +418,7 @@
         /**
          * Issues a request to modify the properties of the current session.  The request is sent to
          * the remote device where it it handled by
-         * {@link VideoCall.Listener#onSessionModifyRequestReceived}.
+         * {@link VideoCall.Callback#onSessionModifyRequestReceived}.
          * Some examples of session modification requests: upgrade call from audio to video,
          * downgrade call from video to audio, pause video.
          *
@@ -423,9 +430,9 @@
          * Provides a response to a request to change the current call session video
          * properties.
          * This is in response to a request the InCall UI has received via
-         * {@link VideoCall.Listener#onSessionModifyRequestReceived}.
+         * {@link VideoCall.Callback#onSessionModifyRequestReceived}.
          * The response is handled on the remove device by
-         * {@link VideoCall.Listener#onSessionModifyResponseReceived}.
+         * {@link VideoCall.Callback#onSessionModifyResponseReceived}.
          *
          * @param responseProfile The response call video properties.
          */
@@ -434,14 +441,14 @@
         /**
          * Issues a request to the video provider to retrieve the camera capabilities.
          * Camera capabilities are reported back to the caller via
-         * {@link VideoCall.Listener#onCameraCapabilitiesChanged(CameraCapabilities)}.
+         * {@link VideoCall.Callback#onCameraCapabilitiesChanged(CameraCapabilities)}.
          */
         public abstract void requestCameraCapabilities();
 
         /**
          * Issues a request to the video telephony framework to retrieve the cumulative data usage for
          * the current call.  Data usage is reported back to the caller via
-         * {@link VideoCall.Listener#onCallDataUsageChanged}.
+         * {@link VideoCall.Callback#onCallDataUsageChanged}.
          */
         public abstract void requestCallDataUsage();
 
@@ -454,9 +461,9 @@
         public abstract void setPauseImage(String uri);
 
         /**
-         * Listener class which invokes callbacks after video call actions occur.
+         * Callback class which invokes callbacks after video call actions occur.
          */
-        public static abstract class Listener {
+        public static abstract class Callback {
             /**
              * Called when a session modification request is received from the remote device.
              * The remote request is sent via
@@ -533,5 +540,11 @@
              */
             public abstract void onCameraCapabilitiesChanged(CameraCapabilities cameraCapabilities);
         }
+
+        /**
+         * @deprecated Use {@code VideoCall.Callback} instead.
+         */
+        @Deprecated
+        public static abstract class Listener extends Callback { }
     }
 }
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index adc648f..c5c3d11 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -54,7 +54,6 @@
     private final int mVideoState;
     private final List<String> mConferenceableCallIds;
     private final Bundle mExtras;
-    private int mCallSubstate;
 
     public ParcelableCall(
             String id,
@@ -76,8 +75,7 @@
             StatusHints statusHints,
             int videoState,
             List<String> conferenceableCallIds,
-            Bundle extras,
-            int callSubstate) {
+            Bundle extras) {
         mId = id;
         mState = state;
         mDisconnectCause = disconnectCause;
@@ -98,7 +96,6 @@
         mVideoState = videoState;
         mConferenceableCallIds = Collections.unmodifiableList(conferenceableCallIds);
         mExtras = extras;
-        mCallSubstate = callSubstate;
     }
 
     /** The unique ID of the call. */
@@ -235,14 +232,6 @@
         return mExtras;
     }
 
-    /**
-     * The call substate.
-     * @return The substate of the call.
-     */
-    public int getCallSubstate() {
-        return mCallSubstate;
-    }
-
     /** Responsible for creating ParcelableCall objects for deserialized Parcels. */
     public static final Parcelable.Creator<ParcelableCall> CREATOR =
             new Parcelable.Creator<ParcelableCall> () {
@@ -273,7 +262,6 @@
             List<String> conferenceableCallIds = new ArrayList<>();
             source.readList(conferenceableCallIds, classLoader);
             Bundle extras = source.readParcelable(classLoader);
-            int callSubstate = source.readInt();
             return new ParcelableCall(
                     id,
                     state,
@@ -294,8 +282,7 @@
                     statusHints,
                     videoState,
                     conferenceableCallIds,
-                    extras,
-                    callSubstate);
+                    extras);
         }
 
         @Override
@@ -334,7 +321,6 @@
         destination.writeInt(mVideoState);
         destination.writeList(mConferenceableCallIds);
         destination.writeParcelable(mExtras, 0);
-        destination.writeInt(mCallSubstate);
     }
 
     @Override
diff --git a/telecomm/java/android/telecom/ParcelableConnection.java b/telecomm/java/android/telecom/ParcelableConnection.java
index b60b99d..552e250 100644
--- a/telecomm/java/android/telecom/ParcelableConnection.java
+++ b/telecomm/java/android/telecom/ParcelableConnection.java
@@ -46,7 +46,6 @@
     private final StatusHints mStatusHints;
     private final DisconnectCause mDisconnectCause;
     private final List<String> mConferenceableConnectionIds;
-    private final int mCallSubstate;
 
     /** @hide */
     public ParcelableConnection(
@@ -63,8 +62,7 @@
             boolean isVoipAudioMode,
             StatusHints statusHints,
             DisconnectCause disconnectCause,
-            List<String> conferenceableConnectionIds,
-            int callSubstate) {
+            List<String> conferenceableConnectionIds) {
         mPhoneAccount = phoneAccount;
         mState = state;
         mConnectionCapabilities = capabilities;
@@ -79,7 +77,6 @@
         mStatusHints = statusHints;
         mDisconnectCause = disconnectCause;
         this.mConferenceableConnectionIds = conferenceableConnectionIds;
-        mCallSubstate = callSubstate;
     }
 
     public PhoneAccountHandle getPhoneAccount() {
@@ -139,10 +136,6 @@
         return mConferenceableConnectionIds;
     }
 
-    public int getCallSubstate() {
-        return mCallSubstate;
-    }
-
     @Override
     public String toString() {
         return new StringBuilder()
@@ -177,7 +170,6 @@
             DisconnectCause disconnectCause = source.readParcelable(classLoader);
             List<String> conferenceableConnectionIds = new ArrayList<>();
             source.readStringList(conferenceableConnectionIds);
-            int callSubstate = source.readInt();
 
             return new ParcelableConnection(
                     phoneAccount,
@@ -193,8 +185,7 @@
                     audioModeIsVoip,
                     statusHints,
                     disconnectCause,
-                    conferenceableConnectionIds,
-                    callSubstate);
+                    conferenceableConnectionIds);
         }
 
         @Override
@@ -227,6 +218,5 @@
         destination.writeParcelable(mStatusHints, 0);
         destination.writeParcelable(mDisconnectCause, 0);
         destination.writeStringList(mConferenceableConnectionIds);
-        destination.writeInt(mCallSubstate);
     }
 }
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index 009ec5b..4c423f2 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -153,16 +153,6 @@
         public void onVideoStateChanged(RemoteConnection connection, int videoState) {}
 
         /**
-         * Indicates that the call substate of this {@code RemoteConnection} has changed.
-         * See {@link #getCallSubstate()}.
-         *
-         * @param connection The {@code RemoteConnection} invoking this method.
-         * @param callSubstate The new call substate of the {@code RemoteConnection}.
-         * @hide
-         */
-        public void onCallSubstateChanged(RemoteConnection connection, int callSubstate) {}
-
-        /**
          * Indicates that this {@code RemoteConnection} has been destroyed. No further requests
          * should be made to the {@code RemoteConnection}, and references to it should be cleared.
          *
@@ -414,7 +404,6 @@
     private boolean mConnected;
     private int mConnectionCapabilities;
     private int mVideoState;
-    private int mCallSubstate;
     private VideoProvider mVideoProvider;
     private boolean mIsVoipAudioMode;
     private StatusHints mStatusHints;
@@ -595,15 +584,6 @@
     }
 
     /**
-     *
-     * @return The call substate of the {@code RemoteConnection}. See
-     * @hide
-     */
-    public int getCallSubstate() {
-        return mCallSubstate;
-    }
-
-    /**
      * Obtains the video provider of this {@code RemoteConnection}.
      * @return The video provider associated with this {@code RemoteConnection}.
      * @hide
@@ -916,16 +896,6 @@
     /**
      * @hide
      */
-    void setCallSubstate(int callSubstate) {
-        mCallSubstate = callSubstate;
-        for (Callback c : mCallbacks) {
-            c.onCallSubstateChanged(this, callSubstate);
-        }
-    }
-
-    /**
-     * @hide
-     */
     void setVideoProvider(VideoProvider videoProvider) {
         mVideoProvider = videoProvider;
         for (Callback c : mCallbacks) {
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index 7374a3b..a9b725b 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -84,7 +84,6 @@
                 }
                 connection.setConferenceableConnections(conferenceable);
                 connection.setVideoState(parcel.getVideoState());
-                connection.setCallSubstate(parcel.getCallSubstate());
                 if (connection.getState() == Connection.STATE_DISCONNECTED) {
                     // ... then, if it was created in a disconnected state, that indicates
                     // failure on the providing end, so immediately mark it destroyed
@@ -312,12 +311,6 @@
 
             mOurConnectionServiceImpl.addRemoteExistingConnection(remoteConnction);
         }
-
-        @Override
-        public void setCallSubstate(String callId, int callSubstate) {
-            findConnectionForAction(callId, "callSubstate")
-                    .setCallSubstate(callSubstate);
-        }
     };
 
     private final ConnectionServiceAdapterServant mServant =
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 60b9cb9..5abbb50 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -720,20 +720,21 @@
     }
 
     /**
-     * Return whether a given phone account has a voicemail number configured.
+     * Return the voicemail number for a given phone account.
      *
-     * @param accountHandle The handle for the account to check for a voicemail number.
-     * @return {@code true} If the given phone account has a voicemail number.
+     * @param accountHandle The handle for the phone account.
+     * @return The voicemail number for the phone account, and {@code null} if one has not been
+     *         configured.
      */
-    public boolean hasVoiceMailNumber(PhoneAccountHandle accountHandle) {
+    public String getVoiceMailNumber(PhoneAccountHandle accountHandle) {
         try {
             if (isServiceConnected()) {
-                return getTelecomService().hasVoiceMailNumber(accountHandle);
+                return getTelecomService().getVoiceMailNumber(accountHandle);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException calling ITelecomService#hasVoiceMailNumber.", e);
         }
-        return false;
+        return null;
     }
 
     /**
diff --git a/telecomm/java/android/telecom/VideoCallImpl.java b/telecomm/java/android/telecom/VideoCallImpl.java
index 0445448..7bef688 100644
--- a/telecomm/java/android/telecom/VideoCallImpl.java
+++ b/telecomm/java/android/telecom/VideoCallImpl.java
@@ -46,7 +46,7 @@
 
     private final IVideoProvider mVideoProvider;
     private final VideoCallListenerBinder mBinder;
-    private VideoCall.Listener mVideoCallListener;
+    private VideoCall.Callback mCallback;
 
     private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
         @Override
@@ -109,14 +109,14 @@
     private final Handler mHandler = new Handler(Looper.getMainLooper()) {
         @Override
         public void handleMessage(Message msg) {
-            if (mVideoCallListener == null) {
+            if (mCallback == null) {
                 return;
             }
 
             SomeArgs args;
             switch (msg.what) {
                 case MSG_RECEIVE_SESSION_MODIFY_REQUEST:
-                    mVideoCallListener.onSessionModifyRequestReceived((VideoProfile) msg.obj);
+                    mCallback.onSessionModifyRequestReceived((VideoProfile) msg.obj);
                     break;
                 case MSG_RECEIVE_SESSION_MODIFY_RESPONSE:
                     args = (SomeArgs) msg.obj;
@@ -125,34 +125,34 @@
                         VideoProfile requestProfile = (VideoProfile) args.arg2;
                         VideoProfile responseProfile = (VideoProfile) args.arg3;
 
-                        mVideoCallListener.onSessionModifyResponseReceived(
+                        mCallback.onSessionModifyResponseReceived(
                                 status, requestProfile, responseProfile);
                     } finally {
                         args.recycle();
                     }
                     break;
                 case MSG_HANDLE_CALL_SESSION_EVENT:
-                    mVideoCallListener.onCallSessionEvent((int) msg.obj);
+                    mCallback.onCallSessionEvent((int) msg.obj);
                     break;
                 case MSG_CHANGE_PEER_DIMENSIONS:
                     args = (SomeArgs) msg.obj;
                     try {
                         int width = (int) args.arg1;
                         int height = (int) args.arg2;
-                        mVideoCallListener.onPeerDimensionsChanged(width, height);
+                        mCallback.onPeerDimensionsChanged(width, height);
                     } finally {
                         args.recycle();
                     }
                     break;
                 case MSG_CHANGE_CALL_DATA_USAGE:
-                    mVideoCallListener.onCallDataUsageChanged((long) msg.obj);
+                    mCallback.onCallDataUsageChanged((long) msg.obj);
                     break;
                 case MSG_CHANGE_CAMERA_CAPABILITIES:
-                    mVideoCallListener.onCameraCapabilitiesChanged(
+                    mCallback.onCameraCapabilitiesChanged(
                             (CameraCapabilities) msg.obj);
                     break;
                 case MSG_CHANGE_VIDEO_QUALITY:
-                    mVideoCallListener.onVideoQualityChanged(msg.arg1);
+                    mCallback.onVideoQualityChanged(msg.arg1);
                     break;
                 default:
                     break;
@@ -170,8 +170,8 @@
     }
 
     /** {@inheritDoc} */
-    public void setVideoCallListener(VideoCall.Listener videoCallListener) {
-        mVideoCallListener = videoCallListener;
+    public void registerCallback(VideoCall.Callback callback) {
+        mCallback = callback;
     }
 
     /** {@inheritDoc} */
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
index e6c28f3..7e7e9cc 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
@@ -81,6 +81,4 @@
     void setConferenceableConnections(String callId, in List<String> conferenceableCallIds);
 
     void addExistingConnection(String callId, in ParcelableConnection connection);
-
-    void setCallSubstate(String callId, int callSubstate);
 }
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index d2030f2..35db97f 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -121,9 +121,9 @@
     boolean isVoiceMailNumber(in PhoneAccountHandle accountHandle, String number);
 
     /**
-     * @see TelecomServiceImpl#hasVoiceMailNumber
+     * @see TelecomServiceImpl#getVoiceMailNumber
      */
-    boolean hasVoiceMailNumber(in PhoneAccountHandle accountHandle);
+    String getVoiceMailNumber(in PhoneAccountHandle accountHandle);
 
     /**
      * @see TelecomServiceImpl#getLine1Number
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
new file mode 100644
index 0000000..b1fb3a6
--- /dev/null
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -0,0 +1,219 @@
+/*
+ * 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.telephony;
+
+import com.android.internal.telephony.ICarrierConfigLoader;
+
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+/**
+ * Provides access to telephony configuration values that are carrier-specific.
+ * <p>
+ * Users should obtain an instance of this class by calling
+ * {@code mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);}
+ * </p>
+ *
+ * @see Context#getSystemService
+ * @see Context#CARRIER_CONFIG_SERVICE
+ */
+public class CarrierConfigManager {
+    /**
+     * @hide
+     */
+    public CarrierConfigManager() {
+    }
+
+    /**
+     * This intent is broadcast by the system when carrier config changes.
+     */
+    public static final String
+            ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
+
+    /**
+     * Flag specifying whether VoLTE should be available for carrier, independent of carrier
+     * provisioning. If false: hard disabled. If true: then depends on carrier provisioning,
+     * availability, etc.
+     */
+    public static final String BOOL_CARRIER_VOLTE_AVAILABLE = "bool_carrier_volte_available";
+
+    /**
+     * Flag specifying whether VoLTE availability is based on provisioning.
+     */
+    public static final String BOOL_CARRIER_VOLTE_PROVISIONED = "bool_carrier_volte_provisioned";
+
+    /**
+     * Flag specifying whether VoLTE TTY is supported.
+     */
+    public static final String BOOL_CARRIER_VOLTE_TTY_SUPPORTED
+            = "bool_carrier_volte_tty_supported";
+
+    /**
+     * Show APN Settings for some CDMA carriers.
+     */
+    public static final String BOOL_SHOW_APN_SETTING_CDMA = "bool_show_apn_setting_cdma";
+
+    /**
+     * If Voice Radio Technology is RIL_RADIO_TECHNOLOGY_LTE:14 or RIL_RADIO_TECHNOLOGY_UNKNOWN:0
+     * this is the value that should be used instead. A configuration value of
+     * RIL_RADIO_TECHNOLOGY_UNKNOWN:0 means there is no replacement value and that the default
+     * assumption for phone type (GSM) should be used.
+     */
+    public static final String INT_VOLTE_REPLACEMENT_RAT = "int_volte_replacement_rat";
+
+    /* The following 3 fields are related to carrier visual voicemail. */
+
+    /**
+     *  The carrier number MO sms messages are sent to.
+     *
+     *  @hide
+     */
+    @SystemApi
+    public static final String STRING_VVM_DESTINATION_NUMBER = "string_vvm_destination_number";
+
+    /**
+     * The port through which the MO sms messages are sent through.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String SHORT_VVM_PORT_NUMBER = "string_vvm_port_number";
+
+    /**
+     * The type of visual voicemail protocol the carrier adheres to (see below).
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String STRING_VVM_TYPE = "string_vvm_type";
+
+    /* Visual voicemail protocols */
+
+    /**
+     * The OMTP protocol.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String VVM_TYPE_OMTP = "vvm_type_omtp";
+
+    private final static String TAG = "CarrierConfigManager";
+
+    /** The default value for every variable. */
+    private final static Bundle sDefaults;
+
+    static {
+        sDefaults = new Bundle();
+        sDefaults.putBoolean(BOOL_CARRIER_VOLTE_AVAILABLE, false);
+        sDefaults.putBoolean(BOOL_CARRIER_VOLTE_PROVISIONED, false);
+        sDefaults.putBoolean(BOOL_CARRIER_VOLTE_TTY_SUPPORTED, true);
+        sDefaults.putBoolean(BOOL_SHOW_APN_SETTING_CDMA, false);
+
+        sDefaults.putInt(INT_VOLTE_REPLACEMENT_RAT, 0);
+    }
+
+    /**
+     * Gets the configuration values for a particular subscription, which is associated with a
+     * specific SIM card. If an invalid subId is used, the returned config will contain default
+     * values.
+     *
+     * @param subId the subscription ID, normally obtained from {@link SubscriptionManager}.
+     * @return A {@link Bundle} containing the config for the given subId, or default values for an
+     *         invalid subId.
+     */
+    public Bundle getConfigForSubId(int subId) {
+        try {
+            return getICarrierConfigLoader().getConfigForSubId(subId);
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "Error getting config for subId " + Integer.toString(subId) + ": "
+                    + ex.toString());
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "Error getting config for subId " + Integer.toString(subId) + ": "
+                    + ex.toString());
+        }
+        return null;
+    }
+
+    /**
+     * Gets the configuration values for the default subscription.
+     *
+     * @see #getConfigForSubId
+     */
+    public Bundle getConfig() {
+        return getConfigForSubId(SubscriptionManager.getDefaultSubId());
+    }
+
+    /**
+     * Calling this method triggers telephony services to fetch the current carrier configuration.
+     * <p>
+     * Normally this does not need to be called because the platform reloads config on its own. Call
+     * this method if your app wants to update config at an arbitrary moment.
+     * </p>
+     * <p>
+     * This method returns before the reload has completed, and
+     * {@link android.service.carrier.CarrierConfigService#onLoadConfig} will be called from an
+     * arbitrary thread.
+     * </p>
+     */
+    public void reloadCarrierConfigForSubId(int subId) {
+        try {
+            getICarrierConfigLoader().reloadCarrierConfigForSubId(subId);
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "Error reloading config for subId=" + subId + ": " + ex.toString());
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "Error reloading config for subId=" + subId + ": " + ex.toString());
+        }
+    }
+
+    /**
+     * Request the carrier config loader to update the cofig for phoneId.
+     *
+     * Depending on simState, the config may be cleared or loaded from config app.
+     * This is only used by SubscriptionInfoUpdater.
+     *
+     * @hide
+     */
+    @SystemApi
+    public void updateConfigForPhoneId(int phoneId, String simState) {
+        try {
+            getICarrierConfigLoader().updateConfigForPhoneId(phoneId, simState);
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "Error updating config for phoneId=" + phoneId + ": " + ex.toString());
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "Error updating config for phoneId=" + phoneId + ": " + ex.toString());
+        }
+    }
+
+    /**
+     * Returns a bundle with the default value for every supported configuration variable.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static Bundle getDefaultConfig() {
+        return sDefaults;
+    }
+
+    /** @hide */
+    private ICarrierConfigLoader getICarrierConfigLoader() {
+        return ICarrierConfigLoader.Stub
+                .asInterface(ServiceManager.getService(Context.CARRIER_CONFIG_SERVICE));
+    }
+}
diff --git a/telephony/java/com/android/ims/internal/IImsCallSession.aidl b/telephony/java/com/android/ims/internal/IImsCallSession.aidl
index 9b435dc..b1f2d32 100644
--- a/telephony/java/com/android/ims/internal/IImsCallSession.aidl
+++ b/telephony/java/com/android/ims/internal/IImsCallSession.aidl
@@ -255,11 +255,4 @@
      * @return {@code True} if the session is multiparty.
      */
     boolean isMultiparty();
-
-    /**
-     * Gets the call substate for this session.
-     *
-     * @return the call substate for this session.
-     */
-    int getCallSubstate();
 }
diff --git a/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl b/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl
new file mode 100644
index 0000000..b5cdd9a2
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.os.Bundle;
+
+/**
+ * Interface used to interact with the CarrierConfigLoader
+ */
+interface ICarrierConfigLoader {
+
+    Bundle getConfigForSubId(int subId);
+
+    void reloadCarrierConfigForSubId(int subId);
+
+    void updateConfigForPhoneId(int phoneId, String simState);
+}
diff --git a/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java b/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
index aabd3f1..f7654ce 100644
--- a/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.app;
 
-import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
 import android.content.Context;
@@ -30,19 +30,19 @@
  *
  * The methods being re-implemented are the ones responsible for instantiating Fragment objects.
  * Because the classes of these objects are found in the project, these methods need access to
- * {@link IProjectCallback} object. They are however static methods, so the callback is set
- * before the inflation through {@link #setProjectCallback(IProjectCallback)}.
+ * {@link LayoutlibCallback} object. They are however static methods, so the callback is set
+ * before the inflation through {@link #setLayoutlibCallback(LayoutlibCallback)}.
  */
 public class Fragment_Delegate {
 
-    private static IProjectCallback sProjectCallback;
+    private static LayoutlibCallback sLayoutlibCallback;
 
     /**
-     * Sets the current {@link IProjectCallback} to be used to instantiate classes coming
+     * Sets the current {@link LayoutlibCallback} to be used to instantiate classes coming
      * from the project being rendered.
      */
-    public static void setProjectCallback(IProjectCallback projectCallback) {
-        sProjectCallback = projectCallback;
+    public static void setLayoutlibCallback(LayoutlibCallback layoutlibCallback) {
+        sLayoutlibCallback = layoutlibCallback;
     }
 
     /**
@@ -62,17 +62,17 @@
      * This is currently just used to get its ClassLoader.
      * @param fname The class name of the fragment to instantiate.
      * @param args Bundle of arguments to supply to the fragment, which it
-     * can retrieve with {@link #getArguments()}.  May be null.
+     * can retrieve with {@link Fragment#getArguments()}.  May be null.
      * @return Returns a new fragment instance.
-     * @throws InstantiationException If there is a failure in instantiating
+     * @throws Fragment.InstantiationException If there is a failure in instantiating
      * the given fragment class.  This is a runtime exception; it is not
      * normally expected to happen.
      */
     @LayoutlibDelegate
     /*package*/ static Fragment instantiate(Context context, String fname, Bundle args) {
         try {
-            if (sProjectCallback != null) {
-                Fragment f = (Fragment) sProjectCallback.loadView(fname,
+            if (sLayoutlibCallback != null) {
+                Fragment f = (Fragment) sLayoutlibCallback.loadView(fname,
                         new Class[0], new Object[0]);
 
                 if (args != null) {
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
index 96ca250..2c2c672 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
@@ -16,8 +16,8 @@
 
 package android.content.res;
 
-import com.android.ide.common.rendering.api.IProjectCallback;
 import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.BridgeConstants;
@@ -49,7 +49,7 @@
 public final class BridgeResources extends Resources {
 
     private BridgeContext mContext;
-    private IProjectCallback mProjectCallback;
+    private LayoutlibCallback mLayoutlibCallback;
     private boolean[] mPlatformResourceFlag = new boolean[1];
     private TypedValue mTmpValue = new TypedValue();
 
@@ -94,12 +94,12 @@
             AssetManager assets,
             DisplayMetrics metrics,
             Configuration config,
-            IProjectCallback projectCallback) {
+            LayoutlibCallback layoutlibCallback) {
         return Resources.mSystem = new BridgeResources(context,
                 assets,
                 metrics,
                 config,
-                projectCallback);
+                layoutlibCallback);
     }
 
     /**
@@ -109,16 +109,16 @@
     public static void disposeSystem() {
         if (Resources.mSystem instanceof BridgeResources) {
             ((BridgeResources)(Resources.mSystem)).mContext = null;
-            ((BridgeResources)(Resources.mSystem)).mProjectCallback = null;
+            ((BridgeResources)(Resources.mSystem)).mLayoutlibCallback = null;
         }
         Resources.mSystem = null;
     }
 
     private BridgeResources(BridgeContext context, AssetManager assets, DisplayMetrics metrics,
-            Configuration config, IProjectCallback projectCallback) {
+            Configuration config, LayoutlibCallback layoutlibCallback) {
         super(assets, metrics, config);
         mContext = context;
-        mProjectCallback = projectCallback;
+        mLayoutlibCallback = layoutlibCallback;
     }
 
     public BridgeTypedArray newTypeArray(int numEntries, boolean platformFile) {
@@ -138,8 +138,8 @@
         }
 
         // didn't find a match in the framework? look in the project.
-        if (mProjectCallback != null) {
-            resourceInfo = mProjectCallback.resolveResourceId(id);
+        if (mLayoutlibCallback != null) {
+            resourceInfo = mLayoutlibCallback.resolveResourceId(id);
 
             if (resourceInfo != null) {
                 platformResFlag_out[0] = false;
@@ -154,11 +154,6 @@
     }
 
     @Override
-    public Drawable getDrawable(int id) throws NotFoundException {
-        return getDrawable(id, null);
-    }
-
-    @Override
     public Drawable getDrawable(int id, Theme theme) {
         Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
 
@@ -257,7 +252,7 @@
             try {
                 // check if the current parser can provide us with a custom parser.
                 if (mPlatformResourceFlag[0] == false) {
-                    parser = mProjectCallback.getParser(value);
+                    parser = mLayoutlibCallback.getParser(value);
                 }
 
                 // create a new one manually if needed.
@@ -692,8 +687,8 @@
         Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
 
         // if the name is unknown in the framework, get it from the custom view loader.
-        if (resourceInfo == null && mProjectCallback != null) {
-            resourceInfo = mProjectCallback.resolveResourceId(id);
+        if (resourceInfo == null && mLayoutlibCallback != null) {
+            resourceInfo = mLayoutlibCallback.resolveResourceId(id);
         }
 
         String message = null;
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index 18036927..7d4271b 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -16,6 +16,7 @@
 
 package android.content.res;
 
+import com.android.annotations.Nullable;
 import com.android.ide.common.rendering.api.AttrResourceValue;
 import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.ide.common.rendering.api.RenderResources;
@@ -40,9 +41,12 @@
 import android.view.ViewGroup.LayoutParams;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Map;
 
+import static com.android.ide.common.rendering.api.RenderResources.*;
+
 /**
  * Custom implementation of TypedArray to handle non compiled resources.
  */
@@ -56,6 +60,11 @@
     private final String[] mNames;
     private final boolean[] mIsFramework;
 
+    // Contains ids that are @empty. We still store null in mResourceData for that index, since we
+    // want to save on the check against empty, each time a resource value is requested.
+    @Nullable
+    private int[] mEmptyIds;
+
     public BridgeTypedArray(BridgeResources resources, BridgeContext context, int len,
             boolean platformFile) {
         super(resources, null, null, 0);
@@ -90,19 +99,32 @@
         // fills TypedArray.mIndices which is used to implement getIndexCount/getIndexAt
         // first count the array size
         int count = 0;
+        ArrayList<Integer> emptyIds = null;
         for (int i = 0; i < mResourceData.length; i++) {
             ResourceValue data = mResourceData[i];
             if (data != null) {
-                if (RenderResources.REFERENCE_NULL.equals(data.getValue())) {
-                    // No need to store this resource value. This saves needless checking for
-                    // "@null" every time  an attribute is requested.
+                String dataValue = data.getValue();
+                if (REFERENCE_NULL.equals(dataValue) || REFERENCE_UNDEFINED.equals(dataValue)) {
                     mResourceData[i] = null;
+                } else if (REFERENCE_EMPTY.equals(dataValue)) {
+                    mResourceData[i] = null;
+                    if (emptyIds == null) {
+                        emptyIds = new ArrayList<Integer>(4);
+                    }
+                    emptyIds.add(i);
                 } else {
                     count++;
                 }
             }
         }
 
+        if (emptyIds != null) {
+            mEmptyIds = new int[emptyIds.size()];
+            for (int i = 0; i < emptyIds.size(); i++) {
+                mEmptyIds[i] = emptyIds.get(i);
+            }
+        }
+
         // allocate the table with an extra to store the size
         mIndices = new int[count+1];
         mIndices[0] = count;
@@ -624,7 +646,7 @@
                 if (isFrameworkId) {
                     idValue = Bridge.getResourceId(ResourceType.ID, idName);
                 } else {
-                    idValue = mContext.getProjectCallback().getResourceId(ResourceType.ID, idName);
+                    idValue = mContext.getLayoutlibCallback().getResourceId(ResourceType.ID, idName);
                 }
                 return idValue == null ? defValue : idValue;
             }
@@ -644,7 +666,7 @@
             idValue = Bridge.getResourceId(resValue.getResourceType(),
                     resValue.getName());
         } else {
-            idValue = mContext.getProjectCallback().getResourceId(
+            idValue = mContext.getLayoutlibCallback().getResourceId(
                     resValue.getResourceType(), resValue.getName());
         }
 
@@ -748,6 +770,12 @@
         return index >= 0 && index < mResourceData.length && mResourceData[index] != null;
     }
 
+    @Override
+    public boolean hasValueOrEmpty(int index) {
+        return hasValue(index) || index >= 0 && index < mResourceData.length &&
+                mEmptyIds != null && Arrays.binarySearch(mEmptyIds, index) >= 0;
+    }
+
     /**
      * Retrieve the raw TypedValue for the attribute at <var>index</var>
      * and return a temporary object holding its data.  This object is only
diff --git a/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java b/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
index 691339e..138b2d5 100644
--- a/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
+++ b/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
@@ -69,8 +69,8 @@
 
         // this is not an attribute in the android namespace, we query the customviewloader, if
         // the namespaces match.
-        if (mContext.getProjectCallback().getNamespace().equals(ns)) {
-            Integer v = mContext.getProjectCallback().getResourceId(ResourceType.ATTR, name);
+        if (mContext.getLayoutlibCallback().getNamespace().equals(ns)) {
+            Integer v = mContext.getLayoutlibCallback().getResourceId(ResourceType.ATTR, name);
             if (v != null) {
                 return v.intValue();
             }
@@ -273,7 +273,7 @@
             if (mPlatformFile || resource.isFramework()) {
                 id = Bridge.getResourceId(resource.getResourceType(), resource.getName());
             } else {
-                id = mContext.getProjectCallback().getResourceId(
+                id = mContext.getLayoutlibCallback().getResourceId(
                         resource.getResourceType(), resource.getName());
             }
 
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
index 80036e5..9eea663 100644
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
@@ -16,7 +16,7 @@
 
 package android.view;
 
-import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.ide.common.rendering.api.MergeCookie;
 import com.android.ide.common.rendering.api.ResourceReference;
@@ -46,7 +46,7 @@
  */
 public final class BridgeInflater extends LayoutInflater {
 
-    private final IProjectCallback mProjectCallback;
+    private final LayoutlibCallback mLayoutlibCallback;
     private boolean mIsInMerge = false;
     private ResourceReference mResourceReference;
 
@@ -64,21 +64,21 @@
         super(original, newContext);
         newContext = getBaseContext(newContext);
         if (newContext instanceof BridgeContext) {
-            mProjectCallback = ((BridgeContext) newContext).getProjectCallback();
+            mLayoutlibCallback = ((BridgeContext) newContext).getLayoutlibCallback();
         } else {
-            mProjectCallback = null;
+            mLayoutlibCallback = null;
         }
     }
 
     /**
-     * Instantiate a new BridgeInflater with an {@link IProjectCallback} object.
+     * Instantiate a new BridgeInflater with an {@link LayoutlibCallback} object.
      *
      * @param context The Android application context.
-     * @param projectCallback the {@link IProjectCallback} object.
+     * @param layoutlibCallback the {@link LayoutlibCallback} object.
      */
-    public BridgeInflater(Context context, IProjectCallback projectCallback) {
+    public BridgeInflater(Context context, LayoutlibCallback layoutlibCallback) {
         super(context);
-        mProjectCallback = projectCallback;
+        mLayoutlibCallback = layoutlibCallback;
         mConstructorArgs[0] = context;
     }
 
@@ -167,12 +167,13 @@
 
             ResourceValue value = null;
 
+            @SuppressWarnings("deprecation")
             Pair<ResourceType, String> layoutInfo = Bridge.resolveResourceId(resource);
             if (layoutInfo != null) {
                 value = bridgeContext.getRenderResources().getFrameworkResource(
                         ResourceType.LAYOUT, layoutInfo.getSecond());
             } else {
-                layoutInfo = mProjectCallback.resolveResourceId(resource);
+                layoutInfo = mLayoutlibCallback.resolveResourceId(resource);
 
                 if (layoutInfo != null) {
                     value = bridgeContext.getRenderResources().getProjectResource(
@@ -203,7 +204,7 @@
     }
 
     private View loadCustomView(String name, AttributeSet attrs) throws Exception {
-        if (mProjectCallback != null) {
+        if (mLayoutlibCallback != null) {
             // first get the classname in case it's not the node name
             if (name.equals("view")) {
                 name = attrs.getAttributeValue(null, "class");
@@ -211,7 +212,7 @@
 
             mConstructorArgs[1] = attrs;
 
-            Object customView = mProjectCallback.loadView(name, mConstructorSignature,
+            Object customView = mLayoutlibCallback.loadView(name, mConstructorSignature,
                     mConstructorArgs);
 
             if (customView instanceof View) {
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 818940d..82012c1 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -376,6 +376,10 @@
     }
 
     @Override
+    public void setForcedDisplayScalingMode(int displayId, int mode) {
+    }
+
+    @Override
     public void setInTouchMode(boolean arg0) throws RemoteException {
         // TODO Auto-generated method stub
     }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 8e74ce1..1da8bb4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -19,8 +19,8 @@
 import com.android.annotations.Nullable;
 import com.android.ide.common.rendering.api.AssetRepository;
 import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.IProjectCallback;
 import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.RenderResources;
 import com.android.ide.common.rendering.api.ResourceReference;
 import com.android.ide.common.rendering.api.ResourceValue;
@@ -114,7 +114,7 @@
     private final RenderResources mRenderResources;
     private final Configuration mConfig;
     private final ApplicationInfo mApplicationInfo;
-    private final IProjectCallback mProjectCallback;
+    private final LayoutlibCallback mLayoutlibCallback;
     private final WindowManager mWindowManager;
     private final DisplayManager mDisplayManager;
 
@@ -148,13 +148,13 @@
     public BridgeContext(Object projectKey, DisplayMetrics metrics,
             RenderResources renderResources,
             AssetRepository assets,
-            IProjectCallback projectCallback,
+            LayoutlibCallback layoutlibCallback,
             Configuration config,
             int targetSdkVersion,
             boolean hasRtlSupport) {
         mProjectKey = projectKey;
         mMetrics = metrics;
-        mProjectCallback = projectCallback;
+        mLayoutlibCallback = layoutlibCallback;
 
         mRenderResources = renderResources;
         mConfig = config;
@@ -173,7 +173,7 @@
 
     /**
      * Initializes the {@link Resources} singleton to be linked to this {@link Context}, its
-     * {@link DisplayMetrics}, {@link Configuration}, and {@link IProjectCallback}.
+     * {@link DisplayMetrics}, {@link Configuration}, and {@link LayoutlibCallback}.
      *
      * @see #disposeResources()
      */
@@ -185,7 +185,7 @@
                 assetManager,
                 mMetrics,
                 mConfig,
-                mProjectCallback);
+                mLayoutlibCallback);
         mTheme = mSystemResources.newTheme();
     }
 
@@ -224,8 +224,8 @@
         return mMetrics;
     }
 
-    public IProjectCallback getProjectCallback() {
-        return mProjectCallback;
+    public LayoutlibCallback getLayoutlibCallback() {
+        return mLayoutlibCallback;
     }
 
     public RenderResources getRenderResources() {
@@ -284,7 +284,7 @@
         Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resid);
         boolean isFrameworkRes = true;
         if (resourceInfo == null) {
-            resourceInfo = mProjectCallback.resolveResourceId(resid);
+            resourceInfo = mLayoutlibCallback.resolveResourceId(resid);
             isFrameworkRes = false;
         }
 
@@ -340,8 +340,8 @@
         }
 
         // didn't find a match in the framework? look in the project.
-        if (mProjectCallback != null) {
-            resourceInfo = mProjectCallback.resolveResourceId(id);
+        if (mLayoutlibCallback != null) {
+            resourceInfo = mLayoutlibCallback.resolveResourceId(id);
 
             if (resourceInfo != null) {
                 return new ResourceReference(resourceInfo.getSecond(), false);
@@ -439,9 +439,9 @@
     private ILayoutPullParser getParser(ResourceReference resource) {
         ILayoutPullParser parser;
         if (resource instanceof ResourceValue) {
-            parser = mProjectCallback.getParser((ResourceValue) resource);
+            parser = mLayoutlibCallback.getParser((ResourceValue) resource);
         } else {
-            parser = mProjectCallback.getParser(resource.getName());
+            parser = mLayoutlibCallback.getParser(resource.getName());
         }
         return parser;
     }
@@ -694,7 +694,7 @@
             boolean isFrameworkRes = true;
             Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
             if (value == null) {
-                value = mProjectCallback.resolveResourceId(defStyleRes);
+                value = mLayoutlibCallback.resolveResourceId(defStyleRes);
                 isFrameworkRes = false;
             }
 
@@ -732,7 +732,7 @@
             }
         }
 
-        String appNamespace = mProjectCallback.getNamespace();
+        String appNamespace = mLayoutlibCallback.getNamespace();
 
         if (attributeList != null) {
             for (int index = 0 ; index < attributeList.size() ; index++) {
@@ -875,7 +875,7 @@
             if (resolvedResource != null) {
                 isFramework = true;
             } else {
-                resolvedResource = mProjectCallback.resolveResourceId(attr);
+                resolvedResource = mLayoutlibCallback.resolveResourceId(attr);
             }
 
             if (resolvedResource != null) {
@@ -901,7 +901,7 @@
             return Pair.of(info.getSecond(), Boolean.TRUE);
         }
 
-        info = mProjectCallback.resolveResourceId(attr);
+        info = mLayoutlibCallback.resolveResourceId(attr);
         if (info != null) {
             return Pair.of(info.getSecond(), Boolean.FALSE);
         }
@@ -953,8 +953,8 @@
         // getResourceId creates a new resource id if an existing resource id isn't found. So, we
         // check for the existence of the resource before calling it.
         if (getRenderResources().getProjectResource(resType, resName) != null) {
-            if (mProjectCallback != null) {
-                Integer value = mProjectCallback.getResourceId(resType, resName);
+            if (mLayoutlibCallback != null) {
+                Integer value = mLayoutlibCallback.getResourceId(resType, resName);
                 if (value != null) {
                     return value;
                 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
index b72329a..9273ac2 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
@@ -18,8 +18,8 @@
 
 import com.android.annotations.NonNull;
 import com.android.annotations.Nullable;
-import com.android.ide.common.rendering.api.IProjectCallback;
 import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.SessionParams;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.android.BridgeContext;
@@ -30,7 +30,6 @@
 import android.widget.LinearLayout;
 
 import java.lang.reflect.Method;
-import java.util.HashMap;
 
 import static com.android.layoutlib.bridge.util.ReflectionUtils.*;
 
@@ -61,7 +60,7 @@
     public static void setAdapter(@NonNull View recyclerView, @NonNull BridgeContext context,
             @NonNull SessionParams params) {
         try {
-            setLayoutManager(recyclerView, context, params.getProjectCallback());
+            setLayoutManager(recyclerView, context, params.getLayoutlibCallback());
             Object adapter = createAdapter(params);
             setProperty(recyclerView, CN_ADAPTER, adapter, "setAdapter");
         } catch (ReflectionException e) {
@@ -71,7 +70,7 @@
     }
 
     private static void setLayoutManager(@NonNull View recyclerView, @NonNull BridgeContext context,
-            @NonNull IProjectCallback callback) throws ReflectionException {
+            @NonNull LayoutlibCallback callback) throws ReflectionException {
         Object cookie = context.getCookie(recyclerView);
         assert cookie == null || cookie instanceof LayoutManagerType || cookie instanceof String;
         if (!(cookie instanceof LayoutManagerType)) {
@@ -90,7 +89,7 @@
 
     @Nullable
     private static Object createLayoutManager(@Nullable LayoutManagerType type,
-            @NonNull Context context, @NonNull IProjectCallback callback)
+            @NonNull Context context, @NonNull LayoutlibCallback callback)
             throws ReflectionException {
         if (type == null) {
             type = LayoutManagerType.getDefault();
@@ -109,7 +108,7 @@
             return null;
         }
         try {
-            return params.getProjectCallback().loadView(CN_ADAPTER, new Class[0], new Object[0]);
+            return params.getLayoutlibCallback().loadView(CN_ADAPTER, new Class[0], new Object[0]);
         } catch (Exception e) {
             throw new ReflectionException(e);
         }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
index ee57067..dd1f661 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
@@ -70,7 +70,7 @@
         try {
             Class[] constructorParams = {View.class};
             Object[] constructorArgs = {getDecorContent()};
-            mWindowDecorActionBar = params.getProjectCallback().loadView(WINDOW_ACTION_BAR_CLASS,
+            mWindowDecorActionBar = params.getLayoutlibCallback().loadView(WINDOW_ACTION_BAR_CLASS,
                     constructorParams, constructorArgs);
 
             mWindowActionBarClass = mWindowDecorActionBar == null ? null :
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
index 2a83ea1..3d1a9b9 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
@@ -51,7 +51,7 @@
             @NonNull ViewGroup parentView) {
         mBridgeContext = context;
         mParams = params;
-        mCallback = params.getProjectCallback().getActionBarCallback();
+        mCallback = params.getLayoutlibCallback().getActionBarCallback();
         ResourceValue layoutName = getLayoutResource(context);
         if (layoutName == null) {
             throw new RuntimeException("Unable to find the layout for Action Bar.");
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
index 127cb72..c708316 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
@@ -16,10 +16,6 @@
 
 package com.android.layoutlib.bridge.impl;
 
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-
 import com.android.ide.common.rendering.api.HardwareConfig;
 import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.ide.common.rendering.api.RenderParams;
@@ -43,6 +39,10 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.ReentrantLock;
 
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT;
+import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
+
 /**
  * Base class for rendering action.
  *
@@ -120,7 +120,7 @@
 
         // build the context
         mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources,
-                mParams.getAssets(), mParams.getProjectCallback(), getConfiguration(),
+                mParams.getAssets(), mParams.getLayoutlibCallback(), getConfiguration(),
                 mParams.getTargetSdkVersion(), mParams.isRtlSupported());
 
         setUp();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index 7c11284d..d9572591 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -16,20 +16,13 @@
 
 package com.android.layoutlib.bridge.impl;
 
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_ANIM_NOT_FOUND;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-
 import com.android.annotations.NonNull;
 import com.android.annotations.Nullable;
 import com.android.ide.common.rendering.api.AdapterBinding;
 import com.android.ide.common.rendering.api.HardwareConfig;
 import com.android.ide.common.rendering.api.IAnimationListener;
 import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.RenderResources;
 import com.android.ide.common.rendering.api.RenderSession;
 import com.android.ide.common.rendering.api.ResourceReference;
@@ -54,13 +47,13 @@
 import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
 import com.android.layoutlib.bridge.android.RenderParamsFlags;
 import com.android.layoutlib.bridge.android.support.RecyclerViewUtil;
-import com.android.layoutlib.bridge.bars.BridgeActionBar;
 import com.android.layoutlib.bridge.bars.AppCompatActionBar;
+import com.android.layoutlib.bridge.bars.BridgeActionBar;
 import com.android.layoutlib.bridge.bars.Config;
+import com.android.layoutlib.bridge.bars.FrameworkActionBar;
 import com.android.layoutlib.bridge.bars.NavigationBar;
 import com.android.layoutlib.bridge.bars.StatusBar;
 import com.android.layoutlib.bridge.bars.TitleBar;
-import com.android.layoutlib.bridge.bars.FrameworkActionBar;
 import com.android.layoutlib.bridge.impl.binding.FakeAdapter;
 import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter;
 import com.android.resources.Density;
@@ -116,6 +109,13 @@
 import java.util.List;
 import java.util.Map;
 
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_ANIM_NOT_FOUND;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN;
+import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
+
 /**
  * Class implementing the render session.
  * <p/>
@@ -219,7 +219,7 @@
         WindowManagerGlobal_Delegate.setWindowManagerService(iwm);
 
         // build the inflater and parser.
-        mInflater = new BridgeInflater(context, params.getProjectCallback());
+        mInflater = new BridgeInflater(context, params.getLayoutlibCallback());
         context.setBridgeInflater(mInflater);
 
         mBlockParser = new BridgeXmlBlockParser(
@@ -401,7 +401,7 @@
 
             // Sets the project callback (custom view loader) to the fragment delegate so that
             // it can instantiate the custom Fragment.
-            Fragment_Delegate.setProjectCallback(params.getProjectCallback());
+            Fragment_Delegate.setLayoutlibCallback(params.getLayoutlibCallback());
 
             String rootTag = params.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG);
             boolean isPreference = "PreferenceScreen".equals(rootTag);
@@ -416,13 +416,13 @@
             // done with the parser, pop it.
             context.popParser();
 
-            Fragment_Delegate.setProjectCallback(null);
+            Fragment_Delegate.setLayoutlibCallback(null);
 
             // set the AttachInfo on the root view.
             AttachInfo_Accessor.setAttachInfo(mViewRoot);
 
             // post-inflate process. For now this supports TabHost/TabWidget
-            postInflateProcess(view, params.getProjectCallback(), isPreference ? view : null);
+            postInflateProcess(view, params.getLayoutlibCallback(), isPreference ? view : null);
 
             // get the background drawable
             if (mWindowBackground != null) {
@@ -686,7 +686,7 @@
             animationResource = context.getRenderResources().getProjectResource(
                     ResourceType.ANIMATOR, animationName);
             if (animationResource != null) {
-                animationId = context.getProjectCallback().getResourceId(
+                animationId = context.getLayoutlibCallback().getResourceId(
                         ResourceType.ANIMATOR, animationName);
             }
         }
@@ -1257,17 +1257,17 @@
      * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
      * based on the content of the {@link FrameLayout}.
      * @param view the root view to process.
-     * @param projectCallback callback to the project.
+     * @param layoutlibCallback callback to the project.
      * @param skip the view and it's children are not processed.
      */
     @SuppressWarnings("deprecation")  // For the use of Pair
-    private void postInflateProcess(View view, IProjectCallback projectCallback, View skip)
+    private void postInflateProcess(View view, LayoutlibCallback layoutlibCallback, View skip)
             throws PostInflateException {
         if (view == skip) {
             return;
         }
         if (view instanceof TabHost) {
-            setupTabHost((TabHost) view, projectCallback);
+            setupTabHost((TabHost) view, layoutlibCallback);
         } else if (view instanceof QuickContactBadge) {
             QuickContactBadge badge = (QuickContactBadge) view;
             badge.setImageToDefault();
@@ -1286,8 +1286,8 @@
 
                 // if there was no adapter binding, trying to get it from the call back.
                 if (binding == null) {
-                    binding = params.getProjectCallback().getAdapterBinding(listRef,
-                            context.getViewKey(view), view);
+                    binding = layoutlibCallback.getAdapterBinding(
+                            listRef, context.getViewKey(view), view);
                 }
 
                 if (binding != null) {
@@ -1303,7 +1303,7 @@
                             for (int i = 0; i < count; i++) {
                                 Pair<View, Boolean> pair = context.inflateView(
                                         binding.getHeaderAt(i),
-                                        list, false /*attachToRoot*/, skipCallbackParser);
+                                        list, false, skipCallbackParser);
                                 if (pair.getFirst() != null) {
                                     list.addHeaderView(pair.getFirst());
                                 }
@@ -1315,7 +1315,7 @@
                             for (int i = 0; i < count; i++) {
                                 Pair<View, Boolean> pair = context.inflateView(
                                         binding.getFooterAt(i),
-                                        list, false /*attachToRoot*/, skipCallbackParser);
+                                        list, false, skipCallbackParser);
                                 if (pair.getFirst() != null) {
                                     list.addFooterView(pair.getFirst());
                                 }
@@ -1326,17 +1326,14 @@
 
                         if (view instanceof ExpandableListView) {
                             ((ExpandableListView) view).setAdapter(
-                                    new FakeExpandableAdapter(
-                                            listRef, binding, params.getProjectCallback()));
+                                    new FakeExpandableAdapter(listRef, binding, layoutlibCallback));
                         } else {
                             ((AbsListView) view).setAdapter(
-                                    new FakeAdapter(
-                                            listRef, binding, params.getProjectCallback()));
+                                    new FakeAdapter(listRef, binding, layoutlibCallback));
                         }
                     } else if (view instanceof AbsSpinner) {
                         ((AbsSpinner) view).setAdapter(
-                                new FakeAdapter(
-                                        listRef, binding, params.getProjectCallback()));
+                                new FakeAdapter(listRef, binding, layoutlibCallback));
                     }
                 }
             }
@@ -1347,7 +1344,7 @@
             final int count = group.getChildCount();
             for (int c = 0; c < count; c++) {
                 View child = group.getChildAt(c);
-                postInflateProcess(child, projectCallback, skip);
+                postInflateProcess(child, layoutlibCallback, skip);
             }
         }
     }
@@ -1371,10 +1368,10 @@
     /**
      * Sets up a {@link TabHost} object.
      * @param tabHost the TabHost to setup.
-     * @param projectCallback The project callback object to access the project R class.
+     * @param layoutlibCallback The project callback object to access the project R class.
      * @throws PostInflateException
      */
-    private void setupTabHost(TabHost tabHost, IProjectCallback projectCallback)
+    private void setupTabHost(TabHost tabHost, LayoutlibCallback layoutlibCallback)
             throws PostInflateException {
         // look for the TabWidget, and the FrameLayout. They have their own specific names
         View v = tabHost.findViewById(android.R.id.tabs);
@@ -1417,8 +1414,9 @@
 
         if (count == 0) {
             // Create a dummy child to get a single tab
-            TabSpec spec = tabHost.newTabSpec("tag").setIndicator("Tab Label",
-                    tabHost.getResources().getDrawable(android.R.drawable.ic_menu_info_details))
+            TabSpec spec = tabHost.newTabSpec("tag")
+                    .setIndicator("Tab Label", tabHost.getResources()
+                            .getDrawable(android.R.drawable.ic_menu_info_details, null))
                     .setContent(new TabHost.TabContentFactory() {
                         @Override
                         public View createTabContent(String tag) {
@@ -1434,7 +1432,7 @@
                 @SuppressWarnings("ConstantConditions")  // child cannot be null.
                 int id = child.getId();
                 @SuppressWarnings("deprecation")
-                Pair<ResourceType, String> resource = projectCallback.resolveResourceId(id);
+                Pair<ResourceType, String> resource = layoutlibCallback.resolveResourceId(id);
                 String name;
                 if (resource != null) {
                     name = resource.getSecond();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
index 6c998af..9aab340 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
@@ -17,7 +17,7 @@
 package com.android.layoutlib.bridge.impl.binding;
 
 import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.ide.common.rendering.api.ResourceReference;
 import com.android.ide.common.rendering.api.IProjectCallback.ViewAttribute;
@@ -40,7 +40,7 @@
 public class AdapterHelper {
 
     static Pair<View, Boolean> getView(AdapterItem item, AdapterItem parentItem, ViewGroup parent,
-            IProjectCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) {
+            LayoutlibCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) {
         // we don't care about recycling here because we never scroll.
         DataBindingItem dataBindingItem = item.getDataBindingItem();
 
@@ -65,7 +65,7 @@
     }
 
     private static void fillView(BridgeContext context, View view, AdapterItem item,
-            AdapterItem parentItem, IProjectCallback callback, ResourceReference adapterRef) {
+            AdapterItem parentItem, LayoutlibCallback callback, ResourceReference adapterRef) {
         if (view instanceof ViewGroup) {
             ViewGroup group = (ViewGroup) view;
             final int count = group.getChildCount();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
index 9a13f5a..142eac1 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
@@ -18,7 +18,7 @@
 
 import com.android.ide.common.rendering.api.AdapterBinding;
 import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.ResourceReference;
 import com.android.util.Pair;
 
@@ -37,18 +37,17 @@
  * and {@link SpinnerAdapter}.
  *
  */
-@SuppressWarnings("deprecation")
 public class FakeAdapter extends BaseAdapter {
 
     // don't use a set because the order is important.
     private final List<ResourceReference> mTypes = new ArrayList<ResourceReference>();
-    private final IProjectCallback mCallback;
+    private final LayoutlibCallback mCallback;
     private final ResourceReference mAdapterRef;
     private final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
     private boolean mSkipCallbackParser = false;
 
     public FakeAdapter(ResourceReference adapterRef, AdapterBinding binding,
-            IProjectCallback callback) {
+            LayoutlibCallback callback) {
         mAdapterRef = adapterRef;
         mCallback = callback;
 
@@ -111,11 +110,11 @@
     public View getView(int position, View convertView, ViewGroup parent) {
         // we don't care about recycling here because we never scroll.
         AdapterItem item = mItems.get(position);
-        Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentGroup*/, parent,
-                mCallback, mAdapterRef, mSkipCallbackParser);
+        @SuppressWarnings("deprecation")
+        Pair<View, Boolean> pair = AdapterHelper.getView(item, null, parent, mCallback,
+                mAdapterRef, mSkipCallbackParser);
         mSkipCallbackParser = pair.getSecond();
         return pair.getFirst();
-
     }
 
     @Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
index e539579..344b17e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
@@ -18,7 +18,7 @@
 
 import com.android.ide.common.rendering.api.AdapterBinding;
 import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.ResourceReference;
 import com.android.util.Pair;
 
@@ -34,7 +34,7 @@
 @SuppressWarnings("deprecation")
 public class FakeExpandableAdapter implements ExpandableListAdapter, HeterogeneousExpandableList {
 
-    private final IProjectCallback mCallback;
+    private final LayoutlibCallback mCallback;
     private final ResourceReference mAdapterRef;
     private boolean mSkipCallbackParser = false;
 
@@ -45,7 +45,7 @@
     private final List<ResourceReference> mChildrenTypes = new ArrayList<ResourceReference>();
 
     public FakeExpandableAdapter(ResourceReference adapterRef, AdapterBinding binding,
-            IProjectCallback callback) {
+            LayoutlibCallback callback) {
         mAdapterRef = adapterRef;
         mCallback = callback;
 
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png
index e38f437..9bf302a 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
index 565e881..0a5e798 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
@@ -20,7 +20,7 @@
 import com.android.ide.common.rendering.api.ActionBarCallback;
 import com.android.ide.common.rendering.api.AdapterBinding;
 import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.ResourceReference;
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.resources.ResourceType;
@@ -28,10 +28,7 @@
 import com.android.util.Pair;
 import com.android.utils.ILogger;
 
-import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
@@ -40,7 +37,7 @@
 import com.google.android.collect.Maps;
 
 @SuppressWarnings("deprecation") // For Pair
-public class LayoutLibTestCallback extends ClassLoader implements IProjectCallback {
+public class LayoutLibTestCallback extends LayoutlibCallback {
 
     private static final String PROJECT_CLASSES_LOCATION = "/testApp/MyApplication/build/intermediates/classes/debug/";
     private static final String PACKAGE_NAME = "com.android.layoutlib.test.myapplication";
@@ -48,16 +45,16 @@
     private final Map<Integer, Pair<ResourceType, String>> mProjectResources = Maps.newHashMap();
     private final Map<IntArrayWrapper, String> mStyleableValueToNameMap = Maps.newHashMap();
     private final Map<ResourceType, Map<String, Integer>> mResources = Maps.newHashMap();
-    private final Map<String, Class<?>> mClasses = Maps.newHashMap();
     private final ILogger mLog;
     private final ActionBarCallback mActionBarCallback = new ActionBarCallback();
+    private final ClassLoader mModuleClassLoader = new ModuleClassLoader(PROJECT_CLASSES_LOCATION);
 
     public LayoutLibTestCallback(ILogger logger) {
         mLog = logger;
     }
 
     public void initResources() throws ClassNotFoundException {
-        Class<?> rClass = loadClass(PACKAGE_NAME + ".R");
+        Class<?> rClass = mModuleClassLoader.loadClass(PACKAGE_NAME + ".R");
         Class<?>[] nestedClasses = rClass.getDeclaredClasses();
         for (Class<?> resClass : nestedClasses) {
             final ResourceType resType = ResourceType.getEnum(resClass.getSimpleName());
@@ -91,40 +88,11 @@
         }
     }
 
-    @Override
-    protected Class<?> findClass(String name) throws ClassNotFoundException {
-        Class<?> aClass = mClasses.get(name);
-        if (aClass != null) {
-            return aClass;
-        }
-        String pathName = PROJECT_CLASSES_LOCATION.concat(name.replace('.', '/')).concat(".class");
-        InputStream classInputStream = getClass().getResourceAsStream(pathName);
-        if (classInputStream == null) {
-            throw new ClassNotFoundException("Unable to find class " + name + " at " + pathName);
-        }
-        byte[] data;
-        try {
-            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-            int nRead;
-            data = new byte[16384];
-            while ((nRead = classInputStream.read(data, 0, data.length)) != -1) {
-                buffer.write(data, 0, nRead);
-            }
-            buffer.flush();
-            data = buffer.toByteArray();
-        } catch (IOException e) {
-            // Wrap the exception with ClassNotFoundException so that caller can deal with it.
-            throw new ClassNotFoundException("Unable to load class " + name, e);
-        }
-        aClass = defineClass(name, data, 0, data.length);
-        mClasses.put(name, aClass);
-        return aClass;
-    }
 
     @Override
     public Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs)
             throws Exception {
-        Class<?> viewClass = findClass(name);
+        Class<?> viewClass = mModuleClassLoader.loadClass(name);
         Constructor<?> viewConstructor = viewClass.getConstructor(constructorSignature);
         viewConstructor.setAccessible(true);
         return viewConstructor.newInstance(constructorArgs);
@@ -180,4 +148,9 @@
     public ActionBarCallback getActionBarCallback() {
         return mActionBarCallback;
     }
+
+    @Override
+    public boolean supports(int ideFeature) {
+        return false;
+    }
 }
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ModuleClassLoader.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ModuleClassLoader.java
new file mode 100644
index 0000000..110f4c8
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ModuleClassLoader.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.intensive.setup;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+import com.google.android.collect.Maps;
+
+/**
+ * The ClassLoader to load the project's classes.
+ */
+public class ModuleClassLoader extends ClassLoader {
+
+    private final Map<String, Class<?>> mClasses = Maps.newHashMap();
+    private final String mClassLocation;
+
+    public ModuleClassLoader(String classLocation) {
+        mClassLocation = classLocation;
+    }
+
+    @Override
+    protected Class<?> findClass(String name) throws ClassNotFoundException {
+        Class<?> aClass = mClasses.get(name);
+        if (aClass != null) {
+            return aClass;
+        }
+        String pathName = mClassLocation.concat(name.replace('.', '/')).concat(".class");
+        InputStream classInputStream = getClass().getResourceAsStream(pathName);
+        if (classInputStream == null) {
+            throw new ClassNotFoundException("Unable to find class " + name + " at " + pathName);
+        }
+        byte[] data;
+        try {
+            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+            int nRead;
+            data = new byte[16384];  // 16k
+            while ((nRead = classInputStream.read(data, 0, data.length)) != -1) {
+                buffer.write(data, 0, nRead);
+            }
+            buffer.flush();
+            data = buffer.toByteArray();
+        } catch (IOException e) {
+            // Wrap the exception with ClassNotFoundException so that caller can deal with it.
+            throw new ClassNotFoundException("Unable to load class " + name, e);
+        }
+        aClass = defineClass(name, data, 0, data.length);
+        mClasses.put(name, aClass);
+        return aClass;
+    }
+}
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index e8a51e3..5dc70bd 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -261,6 +261,12 @@
         return freq > 4900 && freq < 5900;
     }
 
+    /**
+     *  @hide
+     * storing the raw bytes of full result IEs
+     **/
+    public byte[] bytes;
+
     /** information element from beacon
      * @hide
      */