Merge "Unhide BLAS intrinsics."
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 506730e..ee0ec9b 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";
@@ -1978,6 +1979,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
@@ -7740,6 +7742,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 +15567,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 +15707,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 +15887,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 +15972,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);
@@ -22833,6 +22844,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();
@@ -28554,6 +28567,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);
@@ -30245,10 +30278,17 @@
 
   public abstract class InCallService extends android.app.Service {
     ctor public InCallService();
-    method public final android.telecom.Phone getPhone();
+    method public final boolean canAddCall();
+    method public final android.telecom.AudioState getAudioState();
+    method public final java.util.List<android.telecom.Call> getCalls();
+    method public void onAudioStateChanged(android.telecom.AudioState);
     method public android.os.IBinder onBind(android.content.Intent);
-    method public void onPhoneCreated(android.telecom.Phone);
-    method public void onPhoneDestroyed(android.telecom.Phone);
+    method public void onBringToForeground(boolean);
+    method public void onCallAdded(android.telecom.Call);
+    method public void onCallRemoved(android.telecom.Call);
+    method public void onCanAddCallChanged(boolean);
+    method public final void setAudioRoute(int);
+    method public final void setMuted(boolean);
     field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.InCallService";
   }
 
@@ -30455,9 +30495,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);
@@ -30519,6 +30559,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();
@@ -34524,6 +34576,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 {
@@ -34541,7 +34594,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);
@@ -34552,6 +34609,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 9720cda..f476203 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";
@@ -2057,6 +2058,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
@@ -7956,6 +7958,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 +16779,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 +16920,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 +17100,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 +17185,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);
@@ -24721,6 +24732,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();
@@ -30557,6 +30570,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);
@@ -32345,10 +32378,20 @@
 
   public abstract class InCallService extends android.app.Service {
     ctor public InCallService();
+    method public final boolean canAddCall();
+    method public final android.telecom.AudioState getAudioState();
+    method public final java.util.List<android.telecom.Call> getCalls();
     method public final android.telecom.Phone getPhone();
+    method public void onAudioStateChanged(android.telecom.AudioState);
     method public android.os.IBinder onBind(android.content.Intent);
+    method public void onBringToForeground(boolean);
+    method public void onCallAdded(android.telecom.Call);
+    method public void onCallRemoved(android.telecom.Call);
+    method public void onCanAddCallChanged(boolean);
     method public void onPhoneCreated(android.telecom.Phone);
     method public void onPhoneDestroyed(android.telecom.Phone);
+    method public final void setAudioRoute(int);
+    method public final void setMuted(boolean);
     field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.InCallService";
   }
 
@@ -32570,9 +32613,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();
@@ -32639,6 +32682,20 @@
 
 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";
+  }
+
   public final class CellIdentityCdma implements android.os.Parcelable {
     method public int describeContents();
     method public int getBasestationId();
@@ -36689,6 +36746,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 {
@@ -36706,7 +36764,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);
@@ -36717,6 +36779,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/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/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/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index ea53c0d..ab8a8b6 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -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/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/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/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/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 13877fb..5465212 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2408,6 +2408,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/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..77b56ea 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" />
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/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/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/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/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/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/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java
index 66072da..a17474a 100644
--- a/telecomm/java/android/telecom/InCallService.java
+++ b/telecomm/java/android/telecom/InCallService.java
@@ -17,6 +17,7 @@
 package android.telecom;
 
 import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
 import android.app.Service;
 import android.content.Intent;
 import android.os.Handler;
@@ -30,6 +31,8 @@
 import com.android.internal.telecom.IInCallService;
 
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 
 /**
  * This service is implemented by any app that wishes to provide the user-interface for managing
@@ -63,6 +66,7 @@
             switch (msg.what) {
                 case MSG_SET_IN_CALL_ADAPTER:
                     mPhone = new Phone(new InCallAdapter((IInCallAdapter) msg.obj));
+                    mPhone.addListener(mPhoneListener);
                     onPhoneCreated(mPhone);
                     break;
                 case MSG_ADD_CALL:
@@ -144,6 +148,39 @@
         }
     }
 
+    private Phone.Listener mPhoneListener = new Phone.Listener() {
+        /** ${inheritDoc} */
+        @Override
+        public void onAudioStateChanged(Phone phone, AudioState audioState) {
+            InCallService.this.onAudioStateChanged(audioState);
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onBringToForeground(Phone phone, boolean showDialpad) {
+            InCallService.this.onBringToForeground(showDialpad);
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onCallAdded(Phone phone, Call call) {
+            InCallService.this.onCallAdded(call);
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onCallRemoved(Phone phone, Call call) {
+            InCallService.this.onCallRemoved(call);
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onCanAddCallChanged(Phone phone, boolean canAddCall) {
+            InCallService.this.onCanAddCallChanged(canAddCall);
+        }
+
+    };
+
     private Phone mPhone;
 
     public InCallService() {
@@ -161,8 +198,14 @@
             mPhone = null;
 
             oldPhone.destroy();
+            // destroy sets all the calls to disconnected if any live ones still exist. Therefore,
+            // it is important to remove the Listener *after* the call to destroy so that
+            // InCallService.on* callbacks are appropriately called.
+            oldPhone.removeListener(mPhoneListener);
+
             onPhoneDestroyed(oldPhone);
         }
+
         return false;
     }
 
@@ -172,19 +215,75 @@
      * @return The {@code Phone} object associated with this {@code InCallService}, or {@code null}
      *         if the {@code InCallService} is not in a state where it has an associated
      *         {@code Phone}.
+     * @hide
      */
+    @SystemApi
     public final Phone getPhone() {
         return mPhone;
     }
 
     /**
+     * Obtains the current list of {@code Call}s to be displayed by this in-call experience.
+     *
+     * @return A list of the relevant {@code Call}s.
+     */
+    public final List<Call> getCalls() {
+        return mPhone == null ? Collections.<Call>emptyList() : mPhone.getCalls();
+    }
+
+    /**
+     * Returns if the device can support additional calls.
+     *
+     * @return Whether the phone supports adding more calls.
+     */
+    public final boolean canAddCall() {
+        return mPhone == null ? false : mPhone.canAddCall();
+    }
+
+    /**
+     * Obtains the current phone call audio state.
+     *
+     * @return An object encapsulating the audio state. Returns null if the service is not
+     *         fully initialized.
+     */
+    public final AudioState getAudioState() {
+        return mPhone == null ? null : mPhone.getAudioState();
+    }
+
+    /**
+     * Sets the microphone mute state. When this request is honored, there will be change to
+     * the {@link #getAudioState()}.
+     *
+     * @param state {@code true} if the microphone should be muted; {@code false} otherwise.
+     */
+    public final void setMuted(boolean state) {
+        if (mPhone != null) {
+            mPhone.setMuted(state);
+        }
+    }
+
+    /**
+     * Sets the audio route (speaker, bluetooth, etc...).  When this request is honored, there will
+     * be change to the {@link #getAudioState()}.
+     *
+     * @param route The audio route to use.
+     */
+    public final void setAudioRoute(int route) {
+        if (mPhone != null) {
+            mPhone.setAudioRoute(route);
+        }
+    }
+
+    /**
      * Invoked when the {@code Phone} has been created. This is a signal to the in-call experience
      * to start displaying in-call information to the user. Each instance of {@code InCallService}
      * will have only one {@code Phone}, and this method will be called exactly once in the lifetime
      * of the {@code InCallService}.
      *
      * @param phone The {@code Phone} object associated with this {@code InCallService}.
+     * @hide
      */
+    @SystemApi
     public void onPhoneCreated(Phone phone) {
     }
 
@@ -195,11 +294,64 @@
      * call to {@link #onPhoneCreated(Phone)}.
      *
      * @param phone The {@code Phone} object associated with this {@code InCallService}.
+     * @hide
      */
+    @SystemApi
     public void onPhoneDestroyed(Phone phone) {
     }
 
     /**
+     * Called when the audio state changes.
+     *
+     * @param audioState The new {@link AudioState}.
+     */
+    public void onAudioStateChanged(AudioState audioState) {
+    }
+
+    /**
+     * Called to bring the in-call screen to the foreground. The in-call experience should
+     * respond immediately by coming to the foreground to inform the user of the state of
+     * ongoing {@code Call}s.
+     *
+     * @param showDialpad If true, put up the dialpad when the screen is shown.
+     */
+    public void onBringToForeground(boolean showDialpad) {
+    }
+
+    /**
+     * Called when a {@code Call} has been added to this in-call session. The in-call user
+     * experience should add necessary state listeners to the specified {@code Call} and
+     * immediately start to show the user information about the existence
+     * and nature of this {@code Call}. Subsequent invocations of {@link #getCalls()} will
+     * include this {@code Call}.
+     *
+     * @param call A newly added {@code Call}.
+     */
+    public void onCallAdded(Call call) {
+    }
+
+    /**
+     * Called when a {@code Call} has been removed from this in-call session. The in-call user
+     * experience should remove any state listeners from the specified {@code Call} and
+     * immediately stop displaying any information about this {@code Call}.
+     * Subsequent invocations of {@link #getCalls()} will no longer include this {@code Call}.
+     *
+     * @param call A newly removed {@code Call}.
+     */
+    public void onCallRemoved(Call call) {
+    }
+
+    /**
+     * Called when the ability to add more calls changes.  If the phone cannot
+     * support more calls then {@code canAddCall} is set to {@code false}.  If it can, then it
+     * is set to {@code true}. This can be used to control the visibility of UI to add more calls.
+     *
+     * @param canAddCall Indicates whether an additional call can be added.
+     */
+    public void onCanAddCallChanged(boolean canAddCall) {
+    }
+
+    /**
      * Class to invoke functionality related to video calls.
      */
     public static abstract class VideoCall {
@@ -373,8 +525,7 @@
              *
              * @param cameraCapabilities The changed camera capabilities.
              */
-            public abstract void onCameraCapabilitiesChanged(
-                    CameraCapabilities cameraCapabilities);
+            public abstract void onCameraCapabilitiesChanged(CameraCapabilities cameraCapabilities);
         }
     }
 }
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/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..cdf77b4
--- /dev/null
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -0,0 +1,183 @@
+/*
+ * 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";
+
+    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/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/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
      */