Merge "Add new adb dpm (= DevicePolicyManager) command" into lmp-dev
diff --git a/Android.mk b/Android.mk
index 35d13d7..d0c8070 100644
--- a/Android.mk
+++ b/Android.mk
@@ -156,7 +156,7 @@
 	core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl \
 	core/java/android/hardware/hdmi/IHdmiHotplugEventListener.aidl \
 	core/java/android/hardware/hdmi/IHdmiInputChangeListener.aidl \
-	core/java/android/hardware/hdmi/IHdmiMhlScratchpadCommandListener.aidl \
+	core/java/android/hardware/hdmi/IHdmiMhlVendorCommandListener.aidl \
 	core/java/android/hardware/hdmi/IHdmiRecordListener.aidl \
 	core/java/android/hardware/hdmi/IHdmiSystemAudioModeChangeListener.aidl \
 	core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl \
diff --git a/api/current.txt b/api/current.txt
index 4dbe887..dd0723c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1429,6 +1429,7 @@
     field public static final int windowActionBar = 16843469; // 0x10102cd
     field public static final int windowActionBarOverlay = 16843492; // 0x10102e4
     field public static final int windowActionModeOverlay = 16843485; // 0x10102dd
+    field public static final int windowActivityTransitions = 16843982; // 0x10104ce
     field public static final int windowAllowEnterTransitionOverlap = 16843836; // 0x101043c
     field public static final int windowAllowReturnTransitionOverlap = 16843835; // 0x101043b
     field public static final int windowAnimationStyle = 16842926; // 0x10100ae
@@ -2549,6 +2550,7 @@
     field public static final int Widget_Material_Light_CompoundButton_CheckBox = 16974504; // 0x10302a8
     field public static final int Widget_Material_Light_CompoundButton_RadioButton = 16974505; // 0x10302a9
     field public static final int Widget_Material_Light_CompoundButton_Star = 16974506; // 0x10302aa
+    field public static final int Widget_Material_Light_DatePicker = 16974578; // 0x10302f2
     field public static final int Widget_Material_Light_DropDownItem = 16974507; // 0x10302ab
     field public static final int Widget_Material_Light_DropDownItem_Spinner = 16974508; // 0x10302ac
     field public static final int Widget_Material_Light_EditText = 16974509; // 0x10302ad
@@ -2586,6 +2588,7 @@
     field public static final int Widget_Material_Light_TabWidget = 16974539; // 0x10302cb
     field public static final int Widget_Material_Light_TextView = 16974540; // 0x10302cc
     field public static final int Widget_Material_Light_TextView_SpinnerItem = 16974541; // 0x10302cd
+    field public static final int Widget_Material_Light_TimePicker = 16974577; // 0x10302f1
     field public static final int Widget_Material_Light_WebTextView = 16974542; // 0x10302ce
     field public static final int Widget_Material_Light_WebView = 16974543; // 0x10302cf
     field public static final int Widget_Material_ListPopupWindow = 16974455; // 0x1030277
@@ -2614,6 +2617,7 @@
     field public static final int Widget_Material_TabWidget = 16974476; // 0x103028c
     field public static final int Widget_Material_TextView = 16974477; // 0x103028d
     field public static final int Widget_Material_TextView_SpinnerItem = 16974478; // 0x103028e
+    field public static final int Widget_Material_TimePicker = 16974576; // 0x10302f0
     field public static final int Widget_Material_Toolbar = 16974479; // 0x103028f
     field public static final int Widget_Material_Toolbar_Button_Navigation = 16974480; // 0x1030290
     field public static final int Widget_Material_WebTextView = 16974481; // 0x1030291
@@ -5402,7 +5406,7 @@
     field public static final java.lang.String ACTION_PASSWORD_EXPIRING = "android.app.action.ACTION_PASSWORD_EXPIRING";
     field public static final java.lang.String ACTION_PASSWORD_FAILED = "android.app.action.ACTION_PASSWORD_FAILED";
     field public static final java.lang.String ACTION_PASSWORD_SUCCEEDED = "android.app.action.ACTION_PASSWORD_SUCCEEDED";
-    field public static final java.lang.String ACTION_PROFILE_PROVISIONING_COMPLETE = "android.app.action.ACTION_PROFILE_PROVISIONING_COMPLETE";
+    field public static final java.lang.String ACTION_PROFILE_PROVISIONING_COMPLETE = "android.app.action.PROFILE_PROVISIONING_COMPLETE";
     field public static final java.lang.String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
     field public static final java.lang.String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
     field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
@@ -5453,6 +5457,7 @@
     method public boolean hasCaCertInstalled(android.content.ComponentName, byte[]);
     method public boolean hasGrantedPolicy(android.content.ComponentName, int);
     method public boolean installCaCert(android.content.ComponentName, byte[]);
+    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String);
     method public boolean isActivePasswordSufficient();
     method public boolean isAdminActive(android.content.ComponentName);
     method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String);
@@ -5683,6 +5688,7 @@
     method public int describeContents();
     method public android.os.PersistableBundle getExtras();
     method public int getJobId();
+    method public boolean isOverrideDeadlineExpired();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
   }
@@ -6388,7 +6394,6 @@
     method public void onCharacteristicChanged(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic);
     method public void onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
     method public void onCharacteristicWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
-    method public void onConnectionCongested(android.bluetooth.BluetoothGatt, boolean);
     method public void onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int);
     method public void onDescriptorRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int);
     method public void onDescriptorWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int);
@@ -6488,7 +6493,6 @@
     ctor public BluetoothGattServerCallback();
     method public void onCharacteristicReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattCharacteristic);
     method public void onCharacteristicWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattCharacteristic, boolean, boolean, int, byte[]);
-    method public void onConnectionCongested(android.bluetooth.BluetoothDevice, boolean);
     method public void onConnectionStateChange(android.bluetooth.BluetoothDevice, int, int);
     method public void onDescriptorReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattDescriptor);
     method public void onDescriptorWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattDescriptor, boolean, boolean, int, byte[]);
@@ -16343,10 +16347,10 @@
 package android.media.projection {
 
   public final class MediaProjection {
-    method public void addCallback(android.media.projection.MediaProjection.Callback, android.os.Handler);
     method public android.hardware.display.VirtualDisplay createVirtualDisplay(java.lang.String, int, int, int, int, android.view.Surface, android.hardware.display.VirtualDisplay.Callback, android.os.Handler);
-    method public void removeCallback(android.media.projection.MediaProjection.Callback);
+    method public void registerCallback(android.media.projection.MediaProjection.Callback, android.os.Handler);
     method public void stop();
+    method public void unregisterCallback(android.media.projection.MediaProjection.Callback);
   }
 
   public static abstract class MediaProjection.Callback {
@@ -16355,8 +16359,8 @@
   }
 
   public final class MediaProjectionManager {
+    method public android.content.Intent createScreenCaptureIntent();
     method public android.media.projection.MediaProjection getMediaProjection(int, android.content.Intent);
-    method public android.content.Intent getScreenCaptureIntent();
   }
 
 }
@@ -17535,14 +17539,12 @@
 
   public class VpnService extends android.app.Service {
     ctor public VpnService();
-    method public boolean addAddress(java.net.InetAddress, int);
     method public android.os.IBinder onBind(android.content.Intent);
     method public void onRevoke();
     method public static android.content.Intent prepare(android.content.Context);
     method public boolean protect(int);
     method public boolean protect(java.net.Socket);
     method public boolean protect(java.net.DatagramSocket);
-    method public boolean removeAddress(java.net.InetAddress, int);
     field public static final java.lang.String SERVICE_INTERFACE = "android.net.VpnService";
   }
 
@@ -22251,9 +22253,9 @@
     field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000
     field public static final int PARTIAL_WAKE_LOCK = 1; // 0x1
     field public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32; // 0x20
+    field public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1; // 0x1
     field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa
     field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6
-    field public static final int WAIT_FOR_DISTANT_PROXIMITY = 1; // 0x1
   }
 
   public final class PowerManager.WakeLock {
@@ -28239,6 +28241,8 @@
     method public static android.telecomm.Connection createCanceledConnection();
     method public static android.telecomm.Connection createFailedConnection(int, java.lang.String);
     method public final void destroy();
+    method public final android.net.Uri getAddress();
+    method public final int getAddressPresentation();
     method public final boolean getAudioModeIsVoip();
     method public final android.telecomm.AudioState getAudioState();
     method public final int getCallCapabilities();
@@ -28248,26 +28252,24 @@
     method public final java.util.List<android.telecomm.Connection> getConferenceableConnections();
     method public final int getDisconnectCause();
     method public final java.lang.String getDisconnectMessage();
-    method public final android.net.Uri getHandle();
-    method public final int getHandlePresentation();
     method public final int getState();
     method public final android.telecomm.StatusHints getStatusHints();
-    method public final boolean isRequestingRingback();
+    method public final boolean isRingbackRequested();
     method public void onAbort();
     method public void onAnswer();
+    method public void onAudioStateChanged(android.telecomm.AudioState);
     method public void onConferenceWith(android.telecomm.Connection);
     method public void onDisconnect();
     method public void onHold();
-    method public void onPhoneAccountClicked();
     method public void onPlayDtmfTone(char);
     method public void onPostDialContinue(boolean);
     method public void onReject();
     method public void onSeparate();
-    method public void onSetAudioState(android.telecomm.AudioState);
-    method public void onSetState(int);
+    method public void onStateChanged(int);
     method public void onStopDtmfTone();
     method public void onUnhold();
     method public final void setActive();
+    method public final void setAddress(android.net.Uri, int);
     method public final void setAudioModeIsVoip(boolean);
     method public final void setCallCapabilities(int);
     method public final void setCallerDisplayName(java.lang.String, int);
@@ -28275,12 +28277,11 @@
     method public final void setConnectionService(android.telecomm.ConnectionService);
     method public final void setDialing();
     method public final void setDisconnected(int, java.lang.String);
-    method public final void setHandle(android.net.Uri, int);
     method public final void setInitialized();
     method public final void setInitializing();
     method public final void setOnHold();
     method public final void setPostDialWait(java.lang.String);
-    method public final void setRequestingRingback(boolean);
+    method public final void setRingbackRequested(boolean);
     method public final void setRinging();
     method public final void setStatusHints(android.telecomm.StatusHints);
     method public static java.lang.String stateToString(int);
@@ -28320,9 +28321,9 @@
 
   public class GatewayInfo implements android.os.Parcelable {
     method public int describeContents();
-    method public android.net.Uri getGatewayHandle();
+    method public android.net.Uri getGatewayAddress();
     method public java.lang.String getGatewayProviderPackageName();
-    method public android.net.Uri getOriginalHandle();
+    method public android.net.Uri getOriginalAddress();
     method public boolean isEmpty();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
@@ -28340,9 +28341,12 @@
     method public java.lang.CharSequence getShortDescription();
     method public android.net.Uri getSubscriptionAddress();
     method public java.util.List<java.lang.String> getSupportedUriSchemes();
+    method public boolean hasCapabilities(int);
+    method public boolean isEnabled();
     method public boolean supportsUriScheme(java.lang.String);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int CAPABILITY_CONNECTION_MANAGER = 1; // 0x1
+    field public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 16; // 0x10
     field public static final int CAPABILITY_SIM_SUBSCRIPTION = 4; // 0x4
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final java.lang.String SCHEME_SIP = "sip";
@@ -28352,6 +28356,7 @@
 
   public static class PhoneAccount.Builder {
     ctor public PhoneAccount.Builder(android.telecomm.PhoneAccountHandle, java.lang.CharSequence);
+    ctor public PhoneAccount.Builder(android.telecomm.PhoneAccount);
     method public android.telecomm.PhoneAccount build();
     method public android.telecomm.PhoneAccount.Builder setAddress(android.net.Uri);
     method public android.telecomm.PhoneAccount.Builder setCapabilities(int);
@@ -28373,26 +28378,19 @@
   public final class PhoneCapabilities {
     method public static java.lang.String toString(int);
     field public static final int ADD_CALL = 16; // 0x10
-    field public static final int ALL = 255; // 0xff
+    field public static final int ALL = 12543; // 0x30ff
+    field public static final int DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
     field public static final int HOLD = 1; // 0x1
     field public static final int MANAGE_CONFERENCE = 128; // 0x80
     field public static final int MERGE_CONFERENCE = 4; // 0x4
     field public static final int MUTE = 64; // 0x40
     field public static final int RESPOND_VIA_TEXT = 32; // 0x20
+    field public static final int SEPARATE_FROM_CONFERENCE = 4096; // 0x1000
     field public static final int SUPPORT_HOLD = 2; // 0x2
     field public static final int SWAP_CONFERENCE = 8; // 0x8
   }
 
-  public class PropertyPresentation {
-    ctor public PropertyPresentation();
-    field public static final int ALLOWED = 1; // 0x1
-    field public static final int PAYPHONE = 4; // 0x4
-    field public static final int RESTRICTED = 2; // 0x2
-    field public static final int UNKNOWN = 3; // 0x3
-  }
-
   public final class RemoteConference {
-    method public final void addCallback(android.telecomm.RemoteConference.Callback);
     method public void disconnect();
     method public final int getCallCapabilities();
     method public final java.util.List<android.telecomm.RemoteConnection> getConnections();
@@ -28400,9 +28398,10 @@
     method public java.lang.String getDisconnectMessage();
     method public final int getState();
     method public void hold();
-    method public final void removeCallback(android.telecomm.RemoteConference.Callback);
+    method public final void registerCallback(android.telecomm.RemoteConference.Callback);
     method public void separate(android.telecomm.RemoteConnection);
     method public void unhold();
+    method public final void unregisterCallback(android.telecomm.RemoteConference.Callback);
   }
 
   public static abstract class RemoteConference.Callback {
@@ -28417,57 +28416,48 @@
 
   public final class RemoteConnection {
     method public void abort();
-    method public void addListener(android.telecomm.RemoteConnection.Listener);
     method public void answer();
     method public void disconnect();
-    method public boolean getAudioModeIsVoip();
+    method public android.net.Uri getAddress();
+    method public int getAddressPresentation();
     method public int getCallCapabilities();
-    method public java.lang.String getCallerDisplayName();
+    method public java.lang.CharSequence getCallerDisplayName();
     method public int getCallerDisplayNamePresentation();
-    method public java.util.List<android.telecomm.RemoteConnection> getChildren();
     method public android.telecomm.RemoteConference getConference();
     method public java.util.List<android.telecomm.RemoteConnection> getConferenceableConnections();
     method public int getDisconnectCauseCode();
     method public java.lang.String getDisconnectCauseMessage();
     method public int getFailureCode();
     method public java.lang.String getFailureMessage();
-    method public android.net.Uri getHandle();
-    method public int getHandlePresentation();
-    method public android.telecomm.RemoteConnection getParent();
     method public int getState();
     method public android.telecomm.StatusHints getStatusHints();
     method public void hold();
-    method public boolean isRequestingRingback();
+    method public boolean isRingbackRequested();
+    method public boolean isVoipAudioMode();
     method public void playDtmfTone(char);
     method public void postDialContinue(boolean);
+    method public void registerCallback(android.telecomm.RemoteConnection.Callback);
     method public void reject();
-    method public void removeListener(android.telecomm.RemoteConnection.Listener);
     method public void setAudioState(android.telecomm.AudioState);
     method public void stopDtmfTone();
     method public void unhold();
+    method public void unregisterCallback(android.telecomm.RemoteConnection.Callback);
   }
 
-  public static abstract class RemoteConnection.Listener {
-    ctor public RemoteConnection.Listener();
-    method public void onAudioModeIsVoipChanged(android.telecomm.RemoteConnection, boolean);
+  public static abstract class RemoteConnection.Callback {
+    ctor public RemoteConnection.Callback();
+    method public void onAddressChanged(android.telecomm.RemoteConnection, android.net.Uri, int);
     method public void onCallCapabilitiesChanged(android.telecomm.RemoteConnection, int);
     method public void onCallerDisplayNameChanged(android.telecomm.RemoteConnection, java.lang.String, int);
-    method public void onChildrenChanged(android.telecomm.RemoteConnection, java.util.List<android.telecomm.RemoteConnection>);
     method public void onConferenceChanged(android.telecomm.RemoteConnection, android.telecomm.RemoteConference);
     method public void onConferenceableConnectionsChanged(android.telecomm.RemoteConnection, java.util.List<android.telecomm.RemoteConnection>);
     method public void onDestroyed(android.telecomm.RemoteConnection);
     method public void onDisconnected(android.telecomm.RemoteConnection, int, java.lang.String);
-    method public void onHandleChanged(android.telecomm.RemoteConnection, android.net.Uri, int);
-    method public void onParentChanged(android.telecomm.RemoteConnection, android.telecomm.RemoteConnection);
     method public void onPostDialWait(android.telecomm.RemoteConnection, java.lang.String);
-    method public void onRequestingRingback(android.telecomm.RemoteConnection, boolean);
+    method public void onRingbackRequested(android.telecomm.RemoteConnection, boolean);
     method public void onStateChanged(android.telecomm.RemoteConnection, int);
     method public void onStatusHintsChanged(android.telecomm.RemoteConnection, android.telecomm.StatusHints);
-  }
-
-  public abstract interface Response {
-    method public abstract void onError(IN, int, java.lang.String);
-    method public abstract void onResult(IN, OUT...);
+    method public void onVoipAudioChanged(android.telecomm.RemoteConnection, boolean);
   }
 
   public final class StatusHints implements android.os.Parcelable {
@@ -28485,7 +28475,7 @@
   public class TelecommManager {
     method public void addNewIncomingCall(android.telecomm.PhoneAccountHandle, android.os.Bundle);
     method public void cancelMissedCallsNotification();
-    method public void clearAccounts(java.lang.String);
+    method public void clearAccounts();
     method public android.telecomm.PhoneAccountHandle getConnectionManager();
     method public android.telecomm.PhoneAccountHandle getDefaultOutgoingPhoneAccount(java.lang.String);
     method public java.util.List<android.telecomm.PhoneAccountHandle> getEnabledPhoneAccounts();
@@ -28499,6 +28489,8 @@
     method public void unregisterPhoneAccount(android.telecomm.PhoneAccountHandle);
     field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecomm.action.CHANGE_PHONE_ACCOUNTS";
     field public static final java.lang.String ACTION_CONNECTION_SERVICE_CONFIGURE = "android.telecomm.action.CONNECTION_SERVICE_CONFIGURE";
+    field public static final java.lang.String ACTION_PHONE_ACCOUNT_DISABLED = "android.telecom.action.PHONE_ACCOUNT_DISABLED";
+    field public static final java.lang.String ACTION_PHONE_ACCOUNT_ENABLED = "android.telecom.action.PHONE_ACCOUNT_ENABLED";
     field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecomm.action.SHOW_CALL_SETTINGS";
     field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ','
     field public static final char DTMF_CHARACTER_WAIT = 59; // 0x003b ';'
@@ -28508,6 +28500,12 @@
     field public static final java.lang.String EXTRA_CONNECTION_SERVICE = "android.telecomm.extra.CONNECTION_SERVICE";
     field public static final java.lang.String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telecomm.extra.PHONE_ACCOUNT_HANDLE";
     field public static final java.lang.String EXTRA_START_CALL_WITH_SPEAKERPHONE = "android.telecomm.extra.START_CALL_WITH_SPEAKERPHONE";
+    field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecomm.extra.GATEWAY_ORIGINAL_ADDRESS";
+    field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecomm.extra.GATEWAY_PROVIDER_PACKAGE";
+    field public static final int PRESENTATION_ALLOWED = 1; // 0x1
+    field public static final int PRESENTATION_PAYPHONE = 4; // 0x4
+    field public static final int PRESENTATION_RESTRICTED = 2; // 0x2
+    field public static final int PRESENTATION_UNKNOWN = 3; // 0x3
   }
 
 }
@@ -33838,8 +33836,6 @@
     method public boolean hasTransientState();
     method public boolean hasWindowFocus();
     method public static android.view.View inflate(android.content.Context, int, android.view.ViewGroup);
-    method protected void initializeFadingEdge(android.content.res.TypedArray);
-    method protected void initializeScrollbars(android.content.res.TypedArray);
     method public void invalidate(android.graphics.Rect);
     method public void invalidate(int, int, int, int);
     method public void invalidate();
@@ -34886,6 +34882,7 @@
     field public static final int FEATURE_ACTION_BAR = 8; // 0x8
     field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
     field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+    field public static final int FEATURE_ACTIVITY_TRANSITIONS = 13; // 0xd
     field public static final int FEATURE_CONTENT_TRANSITIONS = 12; // 0xc
     field public static final int FEATURE_CONTEXT_MENU = 6; // 0x6
     field public static final int FEATURE_CUSTOM_TITLE = 7; // 0x7
@@ -39122,9 +39119,7 @@
     method public float getShadowRadius();
     method public final boolean getShowSoftInputOnFocus();
     method public java.lang.CharSequence getText();
-    method public static int getTextColor(android.content.Context, android.content.res.TypedArray, int);
     method public final android.content.res.ColorStateList getTextColors();
-    method public static android.content.res.ColorStateList getTextColors(android.content.Context, android.content.res.TypedArray);
     method public java.util.Locale getTextLocale();
     method public float getTextScaleX();
     method public float getTextSize();
diff --git a/api/removed.txt b/api/removed.txt
index c8a3b4b..8972679 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -24,43 +24,22 @@
 
 package android.view {
 
+  public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
+    method protected void initializeFadingEdge(android.content.res.TypedArray);
+    method protected void initializeScrollbars(android.content.res.TypedArray);
+  }
+
   public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
     field public static final int TYPE_KEYGUARD = 2004; // 0x7d4
   }
 
 }
 
-package android.view.inputmethod {
+package android.widget {
 
-  public class BaseInputConnection implements android.view.inputmethod.InputConnection {
-    method public final boolean requestUpdateCursorAnchorInfo(int);
-  }
-
-  public final class CursorAnchorInfo implements android.os.Parcelable {
-    method public android.graphics.RectF getCharacterRect(int);
-    method public int getCharacterRectFlags(int);
-    method public boolean isInsertionMarkerClipped();
-    field public static final int CHARACTER_RECT_TYPE_FULLY_VISIBLE = 1; // 0x1
-    field public static final int CHARACTER_RECT_TYPE_INVISIBLE = 3; // 0x3
-    field public static final int CHARACTER_RECT_TYPE_MASK = 15; // 0xf
-    field public static final int CHARACTER_RECT_TYPE_NOT_FEASIBLE = 4; // 0x4
-    field public static final int CHARACTER_RECT_TYPE_PARTIALLY_VISIBLE = 2; // 0x2
-    field public static final int CHARACTER_RECT_TYPE_UNSPECIFIED = 0; // 0x0
-  }
-
-  public static final class CursorAnchorInfo.Builder {
-    method public android.view.inputmethod.CursorAnchorInfo.Builder addCharacterRect(int, float, float, float, float, int);
-    method public android.view.inputmethod.CursorAnchorInfo.Builder setInsertionMarkerLocation(float, float, float, float, boolean);
-  }
-
-  public abstract interface InputConnection {
-    method public abstract boolean requestUpdateCursorAnchorInfo(int);
-    field public static final int REQUEST_UPDATE_CURSOR_ANCHOR_INFO_MONITOR = 2; // 0x2
-    field public static final int REQUEST_UPDATE_CURSOR_UPDATE_IMMEDIATE = 1; // 0x1
-  }
-
-  public class InputConnectionWrapper implements android.view.inputmethod.InputConnection {
-    method public final boolean requestUpdateCursorAnchorInfo(int);
+  public class TextView extends android.view.View implements android.view.ViewTreeObserver.OnPreDrawListener {
+    method public static int getTextColor(android.content.Context, android.content.res.TypedArray, int);
+    method public static android.content.res.ColorStateList getTextColors(android.content.Context, android.content.res.TypedArray);
   }
 
 }
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 989b500..57c1505 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -855,7 +855,7 @@
     }
 
     private void sendBroadcast() throws Exception {
-        Intent intent = makeIntent(UserHandle.USER_ALL);
+        Intent intent = makeIntent(UserHandle.USER_CURRENT);
         IntentReceiver receiver = new IntentReceiver();
         System.out.println("Broadcasting: " + intent);
         mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, mReceiverPermission,
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 6e77e13..1bb28c3 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -133,8 +133,7 @@
     // names if the zygote command line decreases in size.
     uintptr_t start = reinterpret_cast<uintptr_t>(argv[0]);
     uintptr_t end = reinterpret_cast<uintptr_t>(argv[argc - 1]);
-    end += strlen(argv[argc - 1]);
-
+    end += strlen(argv[argc - 1]) + 1;
     return (end - start);
 }
 
@@ -220,15 +219,27 @@
     //
     // For zygote starts, all remaining arguments are passed to the zygote.
     // main function.
+    //
+    // Note that we must copy argument string values since we will rewrite the
+    // entire argument block when we apply the nice name to argv0.
 
-
-    int i = runtime.addVmArguments(argc, argv);
+    int i;
+    for (i = 0; i < argc; i++) {
+        if (argv[i][0] != '-') {
+            break;
+        }
+        if (argv[i][1] == '-' && argv[i][2] == 0) {
+            ++i; // Skip --.
+            break;
+        }
+        runtime.addOption(strdup(argv[i]));
+    }
 
     // Parse runtime arguments.  Stop at first unrecognized option.
     bool zygote = false;
     bool startSystemServer = false;
     bool application = false;
-    const char* niceName = NULL;
+    String8 niceName;
     String8 className;
 
     ++i;  // Skip unused "parent dir" argument.
@@ -242,7 +253,7 @@
         } else if (strcmp(arg, "--application") == 0) {
             application = true;
         } else if (strncmp(arg, "--nice-name=", 12) == 0) {
-            niceName = arg + 12;
+            niceName.setTo(arg + 12);
         } else if (strncmp(arg, "--", 2) != 0) {
             className.setTo(arg);
             break;
@@ -287,9 +298,9 @@
         }
     }
 
-    if (niceName && *niceName) {
-        runtime.setArgv0(niceName);
-        set_process_name(niceName);
+    if (!niceName.isEmpty()) {
+        runtime.setArgv0(niceName.string());
+        set_process_name(niceName.string());
     }
 
     if (zygote) {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 89a9692..701ab1d 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -4756,7 +4756,7 @@
      * Activity through a returning activity transition, giving you the resultCode
      * and any additional data from it. This method will only be called if the activity
      * set a result code other than {@link #RESULT_CANCELED} and it supports activity
-     * transitions with {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+     * transitions with {@link Window#FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * <p>The purpose of this function is to let the called Activity send a hint about
      * its state so that this underlying Activity can prepare to be exposed. A call to
@@ -5781,7 +5781,7 @@
      * When {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
      * android.view.View, String)} was used to start an Activity, <var>callback</var>
      * will be called to handle shared elements on the <i>launched</i> Activity. This requires
-     * {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+     * {@link Window#FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * @param callback Used to manipulate shared element transitions on the launched Activity.
      */
@@ -5797,7 +5797,7 @@
      * android.view.View, String)} was used to start an Activity, <var>callback</var>
      * will be called to handle shared elements on the <i>launching</i> Activity. Most
      * calls will only come when returning from the started Activity.
-     * This requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+     * This requires {@link Window#FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * @param callback Used to manipulate shared element transitions on the launching Activity.
      */
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 213c7f6..cd6a4f5 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -414,7 +414,7 @@
      * exit Transition. The position of the shared element in the launched Activity will be the
      * epicenter of its entering Transition.
      *
-     * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be
+     * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be
      * enabled on the calling Activity to cause an exit transition. The same must be in
      * the called Activity to get an entering transition.</p>
      * @param activity The Activity whose window contains the shared elements.
@@ -438,7 +438,7 @@
      * will be used as the epicenter for the exit Transition. The position of the associated
      * shared element in the launched Activity will be the epicenter of its entering Transition.
      *
-     * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be
+     * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be
      * enabled on the calling Activity to cause an exit transition. The same must be in
      * the called Activity to get an entering transition.</p>
      * @param activity The Activity whose window contains the shared elements.
@@ -453,7 +453,7 @@
     public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
             Pair<View, String>... sharedElements) {
         ActivityOptions opts = new ActivityOptions();
-        if (!activity.getWindow().hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) {
+        if (!activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) {
             opts.mAnimationType = ANIM_DEFAULT;
             return opts;
         }
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
index ad4a22b..bc2e6ca 100644
--- a/core/java/android/app/ActivityTransitionState.java
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -144,7 +144,7 @@
     }
 
     public void setEnterActivityOptions(Activity activity, ActivityOptions options) {
-        if (activity.getWindow().hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)
+        if (activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
                 && options != null && mEnterActivityOptions == null
                 && mEnterTransitionCoordinator == null
                 && options.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
@@ -272,7 +272,7 @@
     }
 
     public void startExitOutTransition(Activity activity, Bundle options) {
-        if (!activity.getWindow().hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) {
+        if (!activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) {
             return;
         }
         ActivityOptions activityOptions = new ActivityOptions(options);
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index e2f175c..836f682 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -221,6 +221,12 @@
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_PROFILE_PROVISIONING_COMPLETE =
+            "android.app.action.PROFILE_PROVISIONING_COMPLETE";
+
+    /**
+     * Do not use, replaced by {@link #ACTION_PROFILE_PROVISIONING_COMPLETE}
+     */
+    private static final String LEGACY_ACTION_PROFILE_PROVISIONING_COMPLETE =
             "android.app.action.ACTION_PROFILE_PROVISIONING_COMPLETE";
 
     /**
@@ -431,6 +437,9 @@
             onPasswordExpiring(context, intent);
         } else if (ACTION_PROFILE_PROVISIONING_COMPLETE.equals(action)) {
             onProfileProvisioningComplete(context, intent);
+        // TODO: remove when nobody depends on this 
+        } else if (LEGACY_ACTION_PROFILE_PROVISIONING_COMPLETE.equals(action)) {
+            onProfileProvisioningComplete(context, intent);
         } else if (ACTION_LOCK_TASK_ENTERING.equals(action)) {
             String pkg = intent.getStringExtra(EXTRA_LOCK_TASK_PACKAGE);
             onLockTaskModeEntering(context, intent, pkg);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 8f1343d..4a21913 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -38,6 +38,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.security.Credentials;
 import android.service.restrictions.RestrictionsReceiver;
 import android.util.Log;
 
@@ -49,6 +50,8 @@
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.Proxy;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
@@ -1838,6 +1841,32 @@
     }
 
     /**
+     * Called by a device or profile owner to install a certificate and private key pair. The
+     * keypair will be visible to all apps within the profile.
+     *
+     * @param who Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param privKey The private key to install.
+     * @param cert The certificate to install.
+     * @param alias The private key alias under which to install the certificate. If a certificate
+     * with that alias already exists, it will be overwritten.
+     * @return {@code true} if the keys were installed, {@code false} otherwise.
+     */
+    public boolean installKeyPair(ComponentName who, PrivateKey privKey, Certificate cert,
+            String alias) {
+        try {
+            final byte[] pemCert = Credentials.convertToPem(cert);
+            return mService.installKeyPair(who, privKey.getEncoded(), pemCert, alias);
+        } catch (CertificateException e) {
+            Log.w(TAG, "Error encoding certificate", e);
+        } catch (IOException e) {
+            Log.w(TAG, "Error writing certificate", e);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed talking with device policy service", e);
+        }
+        return false;
+    }
+
+    /**
      * Returns the alias of a given CA certificate in the certificate store, or null if it
      * doesn't exist.
      */
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 57d8b95..c8e1780 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -126,6 +126,8 @@
     void uninstallCaCert(in ComponentName admin, in String alias);
     void enforceCanManageCaCerts(in ComponentName admin);
 
+    boolean installKeyPair(in ComponentName who, in byte[] privKeyBuffer, in byte[] certBuffer, String alias);
+
     void addPersistentPreferredActivity(in ComponentName admin, in IntentFilter filter, in ComponentName activity);
     void clearPackagePersistentPreferredActivities(in ComponentName admin, String packageName);
 
diff --git a/core/java/android/app/job/JobParameters.java b/core/java/android/app/job/JobParameters.java
index 724856a..62734f2 100644
--- a/core/java/android/app/job/JobParameters.java
+++ b/core/java/android/app/job/JobParameters.java
@@ -32,12 +32,15 @@
     private final int jobId;
     private final PersistableBundle extras;
     private final IBinder callback;
+    private final boolean overrideDeadlineExpired;
 
     /** @hide */
-    public JobParameters(int jobId, PersistableBundle extras, IBinder callback) {
+    public JobParameters(IBinder callback, int jobId, PersistableBundle extras,
+                         boolean overrideDeadlineExpired) {
         this.jobId = jobId;
         this.extras = extras;
         this.callback = callback;
+        this.overrideDeadlineExpired = overrideDeadlineExpired;
     }
 
     /**
@@ -56,6 +59,16 @@
         return extras;
     }
 
+    /**
+     * For jobs with {@link android.app.job.JobInfo.Builder#setOverrideDeadline(long)} set, this
+     * provides an easy way to tell whether the job is being executed due to the deadline
+     * expiring. Note: If the job is running because its deadline expired, it implies that its
+     * constraints will not be met.
+     */
+    public boolean isOverrideDeadlineExpired() {
+        return overrideDeadlineExpired;
+    }
+
     /** @hide */
     public IJobCallback getCallback() {
         return IJobCallback.Stub.asInterface(callback);
@@ -65,6 +78,7 @@
         jobId = in.readInt();
         extras = in.readPersistableBundle();
         callback = in.readStrongBinder();
+        overrideDeadlineExpired = in.readInt() == 1;
     }
 
     @Override
@@ -77,6 +91,7 @@
         dest.writeInt(jobId);
         dest.writePersistableBundle(extras);
         dest.writeStrongBinder(callback);
+        dest.writeInt(overrideDeadlineExpired ? 1 : 0);
     }
 
     public static final Creator<JobParameters> CREATOR = new Creator<JobParameters>() {
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index d77a77b..2276229 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -51,6 +51,7 @@
     private int mConnState;
     private final Object mStateLock = new Object();
     private Boolean mDeviceBusy = false;
+    private Boolean mIsCongested = false;
     private int mTransport;
 
     private static final int CONN_STATE_IDLE = 0;
@@ -616,7 +617,7 @@
                         + " congested=" + congested);
                 if (!address.equals(mDevice.getAddress())) return;
                 try {
-                    mCallback.onConnectionCongested(BluetoothGatt.this, congested);
+                    mIsCongested = congested;
                 } catch (Exception ex) {
                     Log.w(TAG, "Unhandled exception in callback", ex);
                 }
diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java
index 19900ec..a915620 100644
--- a/core/java/android/bluetooth/BluetoothGattCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattCallback.java
@@ -152,18 +152,4 @@
      */
     public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
     }
-
-    /**
-     * Callback indicating that a remote device connection congestestion status has changed.
-     *
-     * An application should refrain from sending additional data to a remote device when
-     * a callback is received with the congested flag set to true. Once the congestion status
-     * is cleared up, the application will receive an additional callback with the congested
-     * flag set to false.
-     *
-     * @param gatt The GATT client associated with the remote device
-     * @param congested true, if the connection is currently congested
-     */
-    public void onConnectionCongested(BluetoothGatt gatt, boolean congested) {
-    }
 }
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index c8df60e..a7f117b 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -48,6 +48,7 @@
     private BluetoothAdapter mAdapter;
     private IBluetoothGatt mService;
     private BluetoothGattServerCallback mCallback;
+    private Boolean mIsCongested = false;
 
     private Object mServerIfLock = new Object();
     private int mServerIf;
@@ -297,7 +298,7 @@
                 if (device == null) return;
 
                 try {
-                    mCallback.onConnectionCongested(device, congested);
+                    mIsCongested = congested;
                 } catch (Exception ex) {
                     Log.w(TAG, "Unhandled exception in callback", ex);
                 }
diff --git a/core/java/android/bluetooth/BluetoothGattServerCallback.java b/core/java/android/bluetooth/BluetoothGattServerCallback.java
index b0ddc26..1dd06f2 100644
--- a/core/java/android/bluetooth/BluetoothGattServerCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattServerCallback.java
@@ -145,18 +145,4 @@
      */
     public void onNotificationSent(BluetoothDevice device, int status) {
     }
-
-    /**
-     * Callback indicating that a remote device connection congestestion status has changed.
-     *
-     * An application should refrain from sending additional data (notifications, indications
-     * etc.) to a remote device when a callback is received with the congested flag set
-     * to true. Once the congestion status is cleared up, the application will receive an
-     * additional callback with the congested flag set to false.
-     *
-     * @param device The remote device that triggered the congestion state change
-     * @param congested true, if the connection is currently congested
-     */
-    public void onConnectionCongested(BluetoothDevice device, boolean congested) {
-    }
 }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 61dd747..4f20705 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2037,6 +2037,7 @@
      * argument for use by system server and other multi-user aware code.
      * @hide
      */
+    @SystemApi
     public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags, UserHandle user) {
         throw new RuntimeException("Not implemented. Must override in a subclass.");
     }
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 8d3126d..641f843e 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -657,6 +657,7 @@
         softInputMode = orig.softInputMode;
         uiOptions = orig.uiOptions;
         parentActivityName = orig.parentActivityName;
+        maxRecents = orig.maxRecents;
     }
     
     /**
@@ -728,6 +729,7 @@
         dest.writeInt(uiOptions);
         dest.writeString(parentActivityName);
         dest.writeInt(persistableMode);
+        dest.writeInt(maxRecents);
     }
 
     public static final Parcelable.Creator<ActivityInfo> CREATOR
@@ -754,5 +756,6 @@
         uiOptions = source.readInt();
         parentActivityName = source.readString();
         persistableMode = source.readInt();
+        maxRecents = source.readInt();
     }
 }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index ddb0a6d..ffde7ce 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3308,7 +3308,8 @@
         info.softInputMode = target.info.softInputMode;
         info.uiOptions = target.info.uiOptions;
         info.parentActivityName = target.info.parentActivityName;
-        
+        info.maxRecents = target.info.maxRecents;
+
         Activity a = new Activity(mParseActivityAliasArgs, info);
         if (outError[0] != null) {
             sa.recycle();
diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
index 3c0e0e4..c36b63a 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
@@ -165,6 +165,12 @@
 
     private static void mapCharacteristicsFromParameters(CameraMetadataNative m,
             Camera.Parameters p) {
+
+        /*
+         * colorCorrection.*
+         */
+        m.set(COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
+                new int[] { COLOR_CORRECTION_ABERRATION_MODE_FAST });
         /*
          * control.ae*
          */
@@ -196,6 +202,12 @@
         mapJpeg(m, p);
 
         /*
+         * noiseReduction.*
+         */
+        m.set(NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
+                new int[] { NOISE_REDUCTION_MODE_FAST });
+
+        /*
          * scaler.*
          */
         mapScaler(m, p);
@@ -626,6 +638,7 @@
             // Note: We only list public keys. Native HALs should list ALL keys regardless of visibility.
 
             Key<?> availableKeys[] = new Key<?>[] {
+                    CameraCharacteristics.COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES     ,
                     CameraCharacteristics.CONTROL_AE_AVAILABLE_ANTIBANDING_MODES          ,
                     CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES                      ,
                     CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES          ,
@@ -642,6 +655,7 @@
                     CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES                  ,
                     CameraCharacteristics.LENS_FACING                                     ,
                     CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS               ,
+                    CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES ,
                     CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES                  ,
                     CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_STREAMS                  ,
                     CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT                    ,
@@ -653,6 +667,7 @@
                     CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE                   ,
                     CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE                       ,
                     CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE                    ,
+                    CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE                    ,
                     CameraCharacteristics.SENSOR_ORIENTATION                              ,
                     CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES     ,
                     CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT                  ,
@@ -676,6 +691,7 @@
          */
         {
             CaptureRequest.Key<?> defaultAvailableKeys[] = new CaptureRequest.Key<?>[] {
+                    CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE,
                     CaptureRequest.CONTROL_AE_ANTIBANDING_MODE,
                     CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION,
                     CaptureRequest.CONTROL_AE_LOCK,
@@ -699,6 +715,7 @@
                     CaptureRequest.JPEG_THUMBNAIL_QUALITY,
                     CaptureRequest.JPEG_THUMBNAIL_SIZE,
                     CaptureRequest.LENS_FOCAL_LENGTH,
+                    CaptureRequest.NOISE_REDUCTION_MODE,
                     CaptureRequest.SCALER_CROP_REGION,
                     CaptureRequest.STATISTICS_FACE_DETECT_MODE,
             };
@@ -723,6 +740,7 @@
          */
         {
             CaptureResult.Key<?> defaultAvailableKeys[] = new CaptureResult.Key<?>[] {
+                    CaptureResult.COLOR_CORRECTION_ABERRATION_MODE                 ,
                     CaptureResult.CONTROL_AE_ANTIBANDING_MODE                      ,
                     CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION                 ,
                     CaptureResult.CONTROL_AE_LOCK                                  ,
@@ -740,6 +758,7 @@
                     CaptureResult.JPEG_QUALITY                                     ,
                     CaptureResult.JPEG_THUMBNAIL_QUALITY                           ,
                     CaptureResult.LENS_FOCAL_LENGTH                                ,
+                    CaptureResult.NOISE_REDUCTION_MODE                             ,
                     CaptureResult.REQUEST_PIPELINE_DEPTH                           ,
                     CaptureResult.SCALER_CROP_REGION                               ,
                     CaptureResult.SENSOR_TIMESTAMP                                 ,
@@ -844,6 +863,13 @@
 
             m.set(SENSOR_INFO_PHYSICAL_SIZE, new SizeF(width, height)); // in mm
         }
+
+        /*
+         * sensor.info.timestampSource
+         */
+        {
+            m.set(SENSOR_INFO_TIMESTAMP_SOURCE, SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN);
+        }
     }
 
     private static void mapStatistics(CameraMetadataNative m, Parameters p) {
diff --git a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
index 42ee4fa..42fe897 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
@@ -80,6 +80,20 @@
             }
         }
 
+        /*
+         * colorCorrection.*
+         */
+        // colorCorrection.aberrationMode
+        {
+            int aberrationMode = ParamsUtils.getOrDefault(request,
+                    COLOR_CORRECTION_ABERRATION_MODE,
+                    /*defaultValue*/COLOR_CORRECTION_ABERRATION_MODE_FAST);
+
+            if (aberrationMode != COLOR_CORRECTION_ABERRATION_MODE_FAST) {
+                Log.w(TAG, "convertRequestToMetadata - Ignoring unsupported " +
+                        "colorCorrection.aberrationMode = " + aberrationMode);
+            }
+        }
 
         /*
          * control.ae*
@@ -419,6 +433,21 @@
                 }
             }
         }
+
+        /*
+         * noiseReduction.*
+         */
+        // noiseReduction.mode
+        {
+            int mode = ParamsUtils.getOrDefault(request,
+                    NOISE_REDUCTION_MODE,
+                    /*defaultValue*/NOISE_REDUCTION_MODE_FAST);
+
+            if (mode != NOISE_REDUCTION_MODE_FAST) {
+                Log.w(TAG, "convertRequestToMetadata - Ignoring unsupported " +
+                        "noiseReduction.mode = " + mode);
+            }
+        }
     }
 
     private static boolean checkForCompleteGpsData(Location location) {
diff --git a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
index ddaa6ee..bad1d28 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
@@ -28,14 +28,12 @@
 import android.hardware.camera2.params.MeteringRectangle;
 import android.hardware.camera2.utils.ListUtils;
 import android.hardware.camera2.utils.ParamsUtils;
-import android.location.Location;
 import android.util.Log;
 import android.util.Size;
 
 import java.util.ArrayList;
 import java.util.List;
 
-import static com.android.internal.util.Preconditions.*;
 import static android.hardware.camera2.CaptureResult.*;
 
 /**
@@ -73,7 +71,7 @@
             result = new CameraMetadataNative(mCachedResult);
             cached = true;
         } else {
-            result = convertResultMetadata(legacyRequest, timestamp);
+            result = convertResultMetadata(legacyRequest);
             cached = false;
 
             // Always cache a *copy* of the metadata result,
@@ -106,12 +104,9 @@
      * Generate capture result metadata from the legacy camera request.
      *
      * @param legacyRequest a non-{@code null} legacy request containing the latest parameters
-     * @param timestamp the timestamp to use for this result in nanoseconds.
-     *
      * @return a {@link CameraMetadataNative} object containing result metadata.
      */
-    private static CameraMetadataNative convertResultMetadata(LegacyRequest legacyRequest,
-                                                      long timestamp) {
+    private static CameraMetadataNative convertResultMetadata(LegacyRequest legacyRequest) {
         CameraCharacteristics characteristics = legacyRequest.characteristics;
         CaptureRequest request = legacyRequest.captureRequest;
         Size previewSize = legacyRequest.previewSize;
@@ -125,6 +120,15 @@
                 request.get(CaptureRequest.SCALER_CROP_REGION), previewSize, params);
 
         /*
+         * colorCorrection
+         */
+        // colorCorrection.aberrationMode
+        {
+            // Always hardcoded to FAST
+            result.set(COLOR_CORRECTION_ABERRATION_MODE, COLOR_CORRECTION_ABERRATION_MODE_FAST);
+        }
+
+        /*
          * control
          */
 
@@ -274,7 +278,12 @@
             Log.w(TAG, "Null thumbnail size received from parameters.");
         }
 
-        // TODO: Remaining result metadata tags conversions.
+        /*
+         * noiseReduction.*
+         */
+        // noiseReduction.mode
+        result.set(NOISE_REDUCTION_MODE, NOISE_REDUCTION_MODE_FAST);
+
         return result;
     }
 
diff --git a/core/java/android/hardware/hdmi/HdmiTvClient.java b/core/java/android/hardware/hdmi/HdmiTvClient.java
index c37fb5b..9d92fd9 100644
--- a/core/java/android/hardware/hdmi/HdmiTvClient.java
+++ b/core/java/android/hardware/hdmi/HdmiTvClient.java
@@ -36,9 +36,9 @@
     private static final String TAG = "HdmiTvClient";
 
     /**
-     * Size of MHL scratchpad register.
+     * Size of MHL register for vendor command
      */
-    public static final int SCRATCHPAD_DATA_SIZE = 16;
+    public static final int VENDOR_DATA_SIZE = 16;
 
     HdmiTvClient(IHdmiControlService service) {
         super(service);
@@ -332,31 +332,31 @@
     }
 
     /**
-     * Interface used to get incoming MHL scratchpad command.
+     * Interface used to get incoming MHL vendor command.
      */
-    public interface HdmiMhlScratchpadCommandListener {
+    public interface HdmiMhlVendorCommandListener {
         void onReceived(int portId, int offset, int length, byte[] data);
     }
 
     /**
-     * Set {@link HdmiMhlScratchpadCommandListener} to get incoming MHL sSratchpad command.
+     * Set {@link HdmiMhlVendorCommandListener} to get incoming MHL vendor command.
      *
-     * @param listener to receive incoming MHL Scratchpad command
+     * @param listener to receive incoming MHL vendor command
      */
-    public void setHdmiMhlScratchpadCommandListener(HdmiMhlScratchpadCommandListener listener) {
+    public void setHdmiMhlVendorCommandListener(HdmiMhlVendorCommandListener listener) {
         if (listener == null) {
             throw new IllegalArgumentException("listener must not be null.");
         }
         try {
-            mService.addHdmiMhlScratchpadCommandListener(getListenerWrapper(listener));
+            mService.addHdmiMhlVendorCommandListener(getListenerWrapper(listener));
         } catch (RemoteException e) {
-            Log.e(TAG, "failed to set hdmi mhl scratchpad command listener: ", e);
+            Log.e(TAG, "failed to set hdmi mhl vendor command listener: ", e);
         }
     }
 
-    private IHdmiMhlScratchpadCommandListener getListenerWrapper(
-            final HdmiMhlScratchpadCommandListener listener) {
-        return new IHdmiMhlScratchpadCommandListener.Stub() {
+    private IHdmiMhlVendorCommandListener getListenerWrapper(
+            final HdmiMhlVendorCommandListener listener) {
+        return new IHdmiMhlVendorCommandListener.Stub() {
             @Override
             public void onReceived(int portId, int offset, int length, byte[] data) {
                 listener.onReceived(portId, offset, length, data);
@@ -365,29 +365,29 @@
     }
 
     /**
-     * Send MHL Scratchpad command to the device connected to a port of the given portId.
+     * Send MHL vendor command to the device connected to a port of the given portId.
      *
-     * @param portId id of port to send MHL Scratchpad command
+     * @param portId id of port to send MHL vendor command
      * @param offset offset in the in given data
      * @param length length of data. offset + length should be bound to length of data.
-     * @param data container for Scratchpad data. It should be 16 bytes.
+     * @param data container for vendor command data. It should be 16 bytes.
      * @throws IllegalArgumentException if the given parameters are invalid
      */
-    public void sendScratchpadCommand(int portId, int offset, int length, byte[] data) {
-        if (data == null || data.length != SCRATCHPAD_DATA_SIZE) {
-            throw new IllegalArgumentException("Invalid scratchpad data.");
+    public void sendMhlVendorCommand(int portId, int offset, int length, byte[] data) {
+        if (data == null || data.length != VENDOR_DATA_SIZE) {
+            throw new IllegalArgumentException("Invalid vendor command data.");
         }
-        if (offset < 0 || offset >= SCRATCHPAD_DATA_SIZE) {
+        if (offset < 0 || offset >= VENDOR_DATA_SIZE) {
             throw new IllegalArgumentException("Invalid offset:" + offset);
         }
-        if (length < 0 || offset + length > SCRATCHPAD_DATA_SIZE) {
+        if (length < 0 || offset + length > VENDOR_DATA_SIZE) {
             throw new IllegalArgumentException("Invalid length:" + length);
         }
 
         try {
-            mService.sendScratchpadCommand(portId, offset, length, data);
+            mService.sendMhlVendorCommand(portId, offset, length, data);
         } catch (RemoteException e) {
-            Log.e(TAG, "failed to send scratchpad command: ", e);
+            Log.e(TAG, "failed to send vendor command: ", e);
         }
     }
 }
diff --git a/core/java/android/hardware/hdmi/IHdmiControlService.aidl b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
index 3bd45ed..4866a9a 100644
--- a/core/java/android/hardware/hdmi/IHdmiControlService.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
@@ -22,7 +22,7 @@
 import android.hardware.hdmi.IHdmiDeviceEventListener;
 import android.hardware.hdmi.IHdmiHotplugEventListener;
 import android.hardware.hdmi.IHdmiInputChangeListener;
-import android.hardware.hdmi.IHdmiMhlScratchpadCommandListener;
+import android.hardware.hdmi.IHdmiMhlVendorCommandListener;
 import android.hardware.hdmi.IHdmiRecordListener;
 import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener;
 import android.hardware.hdmi.IHdmiVendorCommandListener;
@@ -62,11 +62,12 @@
     void sendVendorCommand(int deviceType, int targetAddress, in byte[] params,
             boolean hasVendorId);
     void addVendorCommandListener(IHdmiVendorCommandListener listener, int deviceType);
+    void sendStandby(int deviceType, int deviceId);
     void setHdmiRecordListener(IHdmiRecordListener callback);
     void startOneTouchRecord(int recorderAddress, in byte[] recordSource);
     void stopOneTouchRecord(int recorderAddress);
     void startTimerRecording(int recorderAddress, int sourceType, in byte[] recordSource);
     void clearTimerRecording(int recorderAddress, int sourceType, in byte[] recordSource);
-    void sendScratchpadCommand(int portId, int offset, int length, in byte[] data);
-    void addHdmiMhlScratchpadCommandListener(IHdmiMhlScratchpadCommandListener listener);
+    void sendMhlVendorCommand(int portId, int offset, int length, in byte[] data);
+    void addHdmiMhlVendorCommandListener(IHdmiMhlVendorCommandListener listener);
 }
diff --git a/core/java/android/hardware/hdmi/IHdmiMhlScratchpadCommandListener.aidl b/core/java/android/hardware/hdmi/IHdmiMhlVendorCommandListener.aidl
similarity index 84%
rename from core/java/android/hardware/hdmi/IHdmiMhlScratchpadCommandListener.aidl
rename to core/java/android/hardware/hdmi/IHdmiMhlVendorCommandListener.aidl
index 4176597..4696677 100644
--- a/core/java/android/hardware/hdmi/IHdmiMhlScratchpadCommandListener.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiMhlVendorCommandListener.aidl
@@ -17,11 +17,10 @@
 package android.hardware.hdmi;
 
  /**
- * Callback interface definition for MHL client to get the scratchpad
- * command.
+ * Callback interface definition for MHL client to get the vendor command.
  *
  * @hide
  */
- oneway interface IHdmiMhlScratchpadCommandListener {
+ oneway interface IHdmiMhlVendorCommandListener {
       void onReceived(int portId, int offset, int length, in byte[] data);
  }
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index 050be40..c848993 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -62,7 +62,8 @@
  * conflict with each other. The system takes several actions to address
  * these issues. Here are some key points:
  * <ul>
- *   <li>User action is required to create a VPN connection.</li>
+ *   <li>User action is required the first time an application creates a VPN
+ *       connection.</li>
  *   <li>There can be only one VPN connection running at the same time. The
  *       existing interface is deactivated when a new one is created.</li>
  *   <li>A system-managed notification is shown during the lifetime of a
@@ -82,8 +83,8 @@
  * other methods in this class, and the right can be revoked at any time.
  * Here are the general steps to create a VPN connection:
  * <ol>
- *   <li>When the user press the button to connect, call {@link #prepare}
- *       and launch the returned intent.</li>
+ *   <li>When the user presses the button to connect, call {@link #prepare}
+ *       and launch the returned intent, if non-null.</li>
  *   <li>When the application becomes prepared, start the service.</li>
  *   <li>Create a tunnel to the remote server and negotiate the network
  *       parameters for the VPN connection.</li>
@@ -130,7 +131,8 @@
 
     /**
      * Prepare to establish a VPN connection. This method returns {@code null}
-     * if the VPN application is already prepared. Otherwise, it returns an
+     * if the VPN application is already prepared or if the user has previously
+     * consented to the VPN application. Otherwise, it returns an
      * {@link Intent} to a system activity. The application should launch the
      * activity using {@link Activity#startActivityForResult} to get itself
      * prepared. The activity may pop up a dialog to require user action, and
@@ -144,6 +146,10 @@
      * it becomes prepared again, subsequent calls to other methods in this
      * class will fail.
      *
+     * <p>The user may disable the VPN at any time while it is activated, in
+     * which case this method will return an intent the next time it is
+     * executed to obtain the user's consent again.
+     *
      * @see #onRevoke
      */
     public static Intent prepare(Context context) {
@@ -212,6 +218,8 @@
      *
      * @return {@code true} on success.
      * @see Builder#addAddress
+     *
+     * @hide
      */
     public boolean addAddress(InetAddress address, int prefixLength) {
         check(address, prefixLength);
@@ -240,6 +248,8 @@
      * @param prefixLength The prefix length of the address.
      *
      * @return {@code true} on success.
+     *
+     * @hide
      */
     public boolean removeAddress(InetAddress address, int prefixLength) {
         check(address, prefixLength);
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 3286627..b5295fb 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -41,6 +41,7 @@
     int getUserSerialNumber(int userHandle);
     int getUserHandle(int userSerialNumber);
     Bundle getUserRestrictions(int userHandle);
+    boolean hasUserRestriction(in String restrictionKey, int userHandle);
     void setUserRestrictions(in Bundle restrictions, int userHandle);
     void setApplicationRestrictions(in String packageName, in Bundle restrictions,
             int userHandle);
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 00e2e22..18b2082 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -248,7 +248,7 @@
      * {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK} wake lock until the proximity sensor
      * indicates that an object is not in close proximity.
      */
-    public static final int WAIT_FOR_DISTANT_PROXIMITY = 1;
+    public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1;
 
     /**
      * Brightness value for fully on.
@@ -961,8 +961,8 @@
          * </p>
          *
          * @param flags Combination of flag values to modify the release behavior.
-         * Currently only {@link #WAIT_FOR_DISTANT_PROXIMITY} is supported. Passing 0 is
-         * equivalent to calling {@link #release()}.
+         * Currently only {@link #RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY} is supported.
+         * Passing 0 is equivalent to calling {@link #release()}.
          */
         public void release(int flags) {
             synchronized (mToken) {
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 33fda4a..c76ff11 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -630,7 +630,13 @@
      * @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
      */
     public boolean hasUserRestriction(String restrictionKey, UserHandle userHandle) {
-        return getUserRestrictions(userHandle).getBoolean(restrictionKey, false);
+        try {
+            return mService.hasUserRestriction(restrictionKey,
+                    userHandle.getIdentifier());
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not check user restrictions", re);
+            return false;
+        }
     }
 
     /**
diff --git a/core/java/android/transition/TransitionSet.java b/core/java/android/transition/TransitionSet.java
index 56db674..669621eb3 100644
--- a/core/java/android/transition/TransitionSet.java
+++ b/core/java/android/transition/TransitionSet.java
@@ -390,7 +390,20 @@
             ArrayList<TransitionValues> endValuesList) {
         startValues = removeExcludes(startValues);
         endValues = removeExcludes(endValues);
-        for (Transition childTransition : mTransitions) {
+        long startDelay = getStartDelay();
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; i++) {
+            Transition childTransition = mTransitions.get(i);
+            // We only set the start delay on the first transition if we are playing
+            // the transitions sequentially.
+            if (startDelay > 0 && (mPlayTogether || i == 0)) {
+                long childStartDelay = childTransition.getStartDelay();
+                if (childStartDelay > 0) {
+                    childTransition.setStartDelay(startDelay + childStartDelay);
+                } else {
+                    childTransition.setStartDelay(startDelay);
+                }
+            }
             childTransition.createAnimators(sceneRoot, startValues, endValues, startValuesList,
                     endValuesList);
         }
@@ -419,11 +432,17 @@
      */
     @Override
     protected void runAnimators() {
+        if (mTransitions.isEmpty()) {
+            start();
+            end();
+            return;
+        }
         setupStartEndListeners();
+        int numTransitions = mTransitions.size();
         if (!mPlayTogether) {
             // Setup sequence with listeners
             // TODO: Need to add listeners in such a way that we can remove them later if canceled
-            for (int i = 1; i < mTransitions.size(); ++i) {
+            for (int i = 1; i < numTransitions; ++i) {
                 Transition previousTransition = mTransitions.get(i - 1);
                 final Transition nextTransition = mTransitions.get(i);
                 previousTransition.addListener(new TransitionListenerAdapter() {
@@ -439,8 +458,8 @@
                 firstTransition.runAnimators();
             }
         } else {
-            for (Transition childTransition : mTransitions) {
-                childTransition.runAnimators();
+            for (int i = 0; i < numTransitions; ++i) {
+                mTransitions.get(i).runAnimators();
             }
         }
     }
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index edb3798..d23e115 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -339,7 +339,8 @@
      * @param attachInfo AttachInfo tied to the specified view.
      * @param callbacks Callbacks invoked when drawing happens.
      */
-    abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks);
+    abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
+            boolean isStartingWindow);
 
     /**
      * Creates a new hardware layer. A hardware layer built by calling this
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 5d2822d..3d1332c 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.graphics.Color;
 import com.android.internal.R;
 
 import android.content.Context;
@@ -267,7 +268,8 @@
         view.mRecreateDisplayList = false;
     }
 
-    private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks) {
+    private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks,
+            boolean isStartingWindow) {
         Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
         updateViewTreeDisplayList(view);
 
@@ -279,6 +281,12 @@
                 callbacks.onHardwarePreDraw(canvas);
 
                 canvas.insertReorderBarrier();
+                if (isStartingWindow) {
+                    // Compensate for some situations in which a hw-accelerated surface
+                    // will not be filled with anything by default; this is equivalent
+                    // to the old behavior when the system process was not hw-accelerated
+                    canvas.drawColor(Color.BLACK);
+                }
                 canvas.drawRenderNode(view.getDisplayList());
                 canvas.insertInorderBarrier();
 
@@ -298,7 +306,8 @@
     }
 
     @Override
-    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
+    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
+            boolean isStartingWindow) {
         attachInfo.mIgnoreDirtyState = true;
         long frameTimeNanos = mChoreographer.getFrameTimeNanos();
         attachInfo.mDrawingTime = frameTimeNanos / TimeUtils.NANOS_PER_MS;
@@ -308,7 +317,7 @@
             recordDuration = System.nanoTime();
         }
 
-        updateRootDisplayList(view, callbacks);
+        updateRootDisplayList(view, callbacks, isStartingWindow);
 
         if (mProfilingEnabled) {
             recordDuration = System.nanoTime() - recordDuration;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 82c5425..eb8f3bf 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4299,6 +4299,8 @@
      * </p>
      *
      * @param a the styled attributes set to initialize the fading edges from
+     *
+     * @removed
      */
     protected void initializeFadingEdge(TypedArray a) {
         // This method probably shouldn't have been included in the SDK to begin with.
@@ -4439,6 +4441,8 @@
      * </p>
      *
      * @param a the styled attributes set to initialize the scrollbars from
+     *
+     * @removed
      */
     protected void initializeScrollbars(TypedArray a) {
         // It's not safe to use this method from apps. The parameter 'a' must have been obtained
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 43ab4ef..ae6e4e7 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -711,17 +711,10 @@
             // can be used by code on the system process to escape that and enable
             // HW accelerated drawing.  (This is basically for the lock screen.)
 
-            final boolean fakeHwAccelerated = (attrs.privateFlags &
-                    WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED) != 0;
             final boolean forceHwAccelerated = (attrs.privateFlags &
                     WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED) != 0;
 
-            if (fakeHwAccelerated) {
-                // This is exclusively for the preview windows the window manager
-                // shows for launching applications, so they will look more like
-                // the app being launched.
-                mAttachInfo.mHardwareAccelerationRequested = true;
-            } else if (!HardwareRenderer.sRendererDisabled
+            if (!HardwareRenderer.sRendererDisabled
                     || (HardwareRenderer.sSystemRendererDisabled && forceHwAccelerated)) {
                 if (mAttachInfo.mHardwareRenderer != null) {
                     mAttachInfo.mHardwareRenderer.destroy();
@@ -2486,7 +2479,8 @@
                 dirty.setEmpty();
 
                 mBlockResizeBuffer = false;
-                mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this);
+                mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this,
+                        params.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
             } else {
                 // If we get here with a disabled & requested hardware renderer, something went
                 // wrong (an invalidate posted right before we destroyed the hardware surface
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index ebc683a..63ab7d2 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -111,10 +111,19 @@
     public static final int FEATURE_CONTENT_TRANSITIONS = 12;
 
     /**
+     * Enables Activities to run Activity Transitions either through sending or receiving
+     * ActivityOptions bundle created with
+     * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(android.app.Activity,
+     * android.util.Pair[])} or {@link android.app.ActivityOptions#makeSceneTransitionAnimation(
+     * android.app.Activity, View, String)}.
+     */
+    public static final int FEATURE_ACTIVITY_TRANSITIONS = 13;
+
+    /**
      * Max value used as a feature ID
      * @hide
      */
-    public static final int FEATURE_MAX = FEATURE_CONTENT_TRANSITIONS;
+    public static final int FEATURE_MAX = FEATURE_ACTIVITY_TRANSITIONS;
 
     /** Flag for setting the progress bar's visibility to VISIBLE */
     public static final int PROGRESS_VISIBILITY_ON = -1;
@@ -1459,7 +1468,7 @@
      * have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
      * {@link android.transition.Visibility} as exiting is governed by changing visibility
      * from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null, the views will
-     * remain unaffected. Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     * remain unaffected. Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * @param transition The Transition to use to move Views out of the scene when calling a
      *                   new Activity.
@@ -1475,7 +1484,7 @@
      * visibility from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null,
      * the views will remain unaffected. If nothing is set, the default will be to use the same
      * transition as {@link #setExitTransition(android.transition.Transition)}.
-     * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * @param transition The Transition to use to move Views into the scene when reentering from a
      *                   previously-started Activity.
@@ -1489,7 +1498,7 @@
      * {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
      * {@link android.transition.Visibility} as entering is governed by changing visibility from
      * {@link View#INVISIBLE} to {@link View#VISIBLE}. If <code>transition</code> is null,
-     * entering Views will remain unaffected.  Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     * entering Views will remain unaffected.  Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * @return the Transition to use to move Views into the initial Scene.
      * @attr ref android.R.styleable#Window_windowEnterTransition
@@ -1517,7 +1526,7 @@
      * have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
      * {@link android.transition.Visibility} as exiting is governed by changing visibility
      * from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null, the views will
-     * remain unaffected. Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     * remain unaffected. Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * @return the Transition to use to move Views out of the scene when calling a
      * new Activity.
@@ -1531,7 +1540,7 @@
      * or ViewGroups that have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions
      * will extend {@link android.transition.Visibility} as exiting is governed by changing
      * visibility from {@link View#VISIBLE} to {@link View#INVISIBLE}.
-     * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * @return The Transition to use to move Views into the scene when reentering from a
      *         previously-started Activity.
@@ -1544,7 +1553,7 @@
      * Scene. Typical Transitions will affect size and location, such as
      * {@link android.transition.ChangeBounds}. A null
      * value will cause transferred shared elements to blink to the final position.
-     * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * @param transition The Transition to use for shared elements transferred into the content
      *                   Scene.
@@ -1559,7 +1568,7 @@
      * value will cause transferred shared elements to blink to the final position.
      * If no value is set, the default will be to use the same value as
      * {@link #setSharedElementEnterTransition(android.transition.Transition)}.
-     * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * @param transition The Transition to use for shared elements transferred out of the content
      *                   Scene.
@@ -1569,7 +1578,7 @@
 
     /**
      * Returns the Transition that will be used for shared elements transferred into the content
-     * Scene. Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     * Scene. Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * @return Transition to use for sharend elements transferred into the content Scene.
      * @attr ref android.R.styleable#Window_windowSharedElementEnterTransition
@@ -1578,7 +1587,7 @@
 
     /**
      * Returns the Transition that will be used for shared elements transferred back to a
-     * calling Activity. Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     * calling Activity. Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * @return Transition to use for sharend elements transferred into the content Scene.
      * @attr ref android.R.styleable#Window_windowSharedElementReturnTransition
@@ -1590,7 +1599,7 @@
      * before the shared elements are transferred to the called Activity. If the shared elements
      * must animate during the exit transition, this Transition should be used. Upon completion,
      * the shared elements may be transferred to the started Activity.
-     * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * @param transition The Transition to use for shared elements in the launching Window
      *                   prior to transferring to the launched Activity's Window.
@@ -1603,7 +1612,7 @@
      * Activity after it has returned the shared element to it start location. If no value
      * is set, this will default to
      * {@link #setSharedElementExitTransition(android.transition.Transition)}.
-     * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * @param transition The Transition to use for shared elements in the launching Window
      *                   after the shared element has returned to the Window.
@@ -1614,7 +1623,7 @@
     /**
      * Returns the Transition to use for shared elements in the launching Window prior
      * to transferring to the launched Activity's Window.
-     * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * @return the Transition to use for shared elements in the launching Window prior
      * to transferring to the launched Activity's Window.
@@ -1625,7 +1634,7 @@
     /**
      * Returns the Transition that will be used for shared elements reentering from a started
      * Activity after it has returned the shared element to it start location.
-     * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
      *
      * @return the Transition that will be used for shared elements reentering from a started
      * Activity after it has returned the shared element to it start location.
@@ -1703,7 +1712,7 @@
      * Returns the duration, in milliseconds, of the window background fade
      * when transitioning into or away from an Activity when called with an Activity Transition.
      * <p>When executing the enter transition, the background starts transparent
-     * and fades in. This requires {@link #FEATURE_CONTENT_TRANSITIONS}. The default is
+     * and fades in. This requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. The default is
      * 300 milliseconds.</p>
      *
      * @return The duration of the window background fade to opaque during enter transition.
@@ -1716,7 +1725,7 @@
      * Sets the duration, in milliseconds, of the window background fade
      * when transitioning into or away from an Activity when called with an Activity Transition.
      * <p>When executing the enter transition, the background starts transparent
-     * and fades in. This requires {@link #FEATURE_CONTENT_TRANSITIONS}. The default is
+     * and fades in. This requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. The default is
      * 300 milliseconds.</p>
      *
      * @param fadeDurationMillis The duration of the window background fade to or from opaque
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 47ee52e..273ec9d 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1024,26 +1024,6 @@
         public int flags;
 
         /**
-         * If the window has requested hardware acceleration, but this is not
-         * allowed in the process it is in, then still render it as if it is
-         * hardware accelerated.  This is used for the starting preview windows
-         * in the system process, which don't need to have the overhead of
-         * hardware acceleration (they are just a static rendering), but should
-         * be rendered as such to match the actual window of the app even if it
-         * is hardware accelerated.
-         * Even if the window isn't hardware accelerated, still do its rendering
-         * as if it was.
-         * Like {@link #FLAG_HARDWARE_ACCELERATED} except for trusted system windows
-         * that need hardware acceleration (e.g. LockScreen), where hardware acceleration
-         * is generally disabled. This flag must be specified in addition to 
-         * {@link #FLAG_HARDWARE_ACCELERATED} to enable hardware acceleration for system
-         * windows.
-         * 
-         * @hide
-         */
-        public static final int PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED = 0x00000001;
-
-        /**
          * In the system process, we globally do not use hardware acceleration
          * because there are many threads doing UI there and they conflict.
          * If certain parts of the UI that really do want to use hardware
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 2ed125d..fec7550 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -638,6 +638,11 @@
     public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs);
 
     /**
+     * Return the window that is hiding the keyguard, if such a thing exists.
+     */
+    public WindowState getWinShowWhenLockedLw();
+
+    /**
      * Called when the system would like to show a UI to indicate that an
      * application is starting.  You can use this to add a
      * APPLICATION_STARTING_TYPE window with the given appToken to the window
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index 20adfe4..ba5d6c2 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -436,14 +436,6 @@
     }
 
     /**
-     * The default implementation does nothing.
-     * @removed
-     */
-    public final boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) {
-        return false;
-    }
-
-    /**
      * The default implementation places the given text into the editable,
      * replacing any existing composing text.  The new text is marked as
      * in a composing state with the composing style.
diff --git a/core/java/android/view/inputmethod/CursorAnchorInfo.java b/core/java/android/view/inputmethod/CursorAnchorInfo.java
index 600fffe..fd73432 100644
--- a/core/java/android/view/inputmethod/CursorAnchorInfo.java
+++ b/core/java/android/view/inputmethod/CursorAnchorInfo.java
@@ -120,38 +120,6 @@
      */
     public static final int FLAG_IS_RTL = 0x04;
 
-    /**
-     * @removed
-     */
-    public static final int CHARACTER_RECT_TYPE_MASK = 0x0f;
-    /**
-     * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the editor did not specify any type of this
-     * character. Editor authors should not use this flag.
-     * @removed
-     */
-    public static final int CHARACTER_RECT_TYPE_UNSPECIFIED = 0;
-    /**
-     * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the character is entirely visible.
-     * @removed
-     */
-    public static final int CHARACTER_RECT_TYPE_FULLY_VISIBLE = 1;
-    /**
-     * Type for {@link #CHARACTER_RECT_TYPE_MASK}: some area of the character is invisible.
-     * @removed
-     */
-    public static final int CHARACTER_RECT_TYPE_PARTIALLY_VISIBLE = 2;
-    /**
-     * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the character is entirely invisible.
-     * @removed
-     */
-    public static final int CHARACTER_RECT_TYPE_INVISIBLE = 3;
-    /**
-     * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the editor gave up to calculate the rectangle
-     * for this character. Input method authors should ignore the returned rectangle.
-     * @removed
-     */
-    public static final int CHARACTER_RECT_TYPE_NOT_FEASIBLE = 4;
-
     public CursorAnchorInfo(final Parcel source) {
         mSelectionStart = source.readInt();
         mSelectionEnd = source.readInt();
@@ -318,20 +286,6 @@
         }
 
         /**
-         * @removed
-         */
-        public Builder setInsertionMarkerLocation(final float horizontalPosition,
-                final float lineTop, final float lineBaseline, final float lineBottom,
-                final boolean clipped){
-            mInsertionMarkerHorizontal = horizontalPosition;
-            mInsertionMarkerTop = lineTop;
-            mInsertionMarkerBaseline = lineBaseline;
-            mInsertionMarkerBottom = lineBottom;
-            mInsertionMarkerFlags = clipped ? FLAG_HAS_INVISIBLE_REGION : 0;
-            return this;
-        }
-
-        /**
          * Sets the location of the text insertion point (zero width cursor) as a rectangle in
          * local coordinates. Calling this can be skipped when there is no text insertion point;
          * however if there is an insertion point, editors must call this method.
@@ -390,43 +344,6 @@
         }
 
         /**
-         * Adds the bounding box of the character specified with the index.
-         *
-         * @param index index of the character in Java chars units. Must be specified in
-         * ascending order across successive calls.
-         * @param leadingEdgeX x coordinate of the leading edge of the character in local
-         * coordinates, that is, left edge for LTR text and right edge for RTL text.
-         * @param leadingEdgeY y coordinate of the leading edge of the character in local
-         * coordinates.
-         * @param trailingEdgeX x coordinate of the trailing edge of the character in local
-         * coordinates, that is, right edge for LTR text and left edge for RTL text.
-         * @param trailingEdgeY y coordinate of the trailing edge of the character in local
-         * coordinates.
-         * @param flags flags for this character rect. See {@link #FLAG_HAS_VISIBLE_REGION} for
-         * example.
-         * @throws IllegalArgumentException If the index is a negative value, or not greater than
-         * all of the previously called indices.
-         * @removed
-         */
-        public Builder addCharacterRect(final int index, final float leadingEdgeX,
-                final float leadingEdgeY, final float trailingEdgeX, final float trailingEdgeY,
-                final int flags) {
-            final int newFlags;
-            final float left;
-            final float right;
-            if (leadingEdgeX <= trailingEdgeX) {
-                newFlags = flags;
-                left = leadingEdgeX;
-                right = trailingEdgeX;
-            } else {
-                newFlags = flags | FLAG_IS_RTL;
-                left = trailingEdgeX;
-                right = leadingEdgeX;
-            }
-            return addCharacterBounds(index, left, leadingEdgeY, right, trailingEdgeY, newFlags);
-        }
-
-        /**
          * Sets the matrix that transforms local coordinates into screen coordinates.
          * @param matrix transformation matrix from local coordinates into screen coordinates. null
          * is interpreted as an identity matrix.
@@ -538,15 +455,6 @@
     }
 
     /**
-     * Returns the visibility of the insertion marker.
-     * @return {@code true} if the insertion marker is partially or entirely clipped.
-     * @removed
-     */
-    public boolean isInsertionMarkerClipped() {
-        return (mInsertionMarkerFlags & FLAG_HAS_VISIBLE_REGION) != 0;
-    }
-
-    /**
      * Returns the horizontal start of the insertion marker, in the local coordinates that will
      * be transformed with {@link #getMatrix()} when rendered on the screen.
      * @return x coordinate that is compatible with {@link Layout#getPrimaryHorizontal(int)}.
@@ -602,25 +510,6 @@
     }
 
     /**
-     * Returns a new instance of {@link RectF} that indicates the location of the character
-     * specified with the index.
-     * <p>
-     * Note that coordinates are not necessarily contiguous or even monotonous, especially when
-     * RTL text and LTR text are mixed.
-     * </p>
-     * @param index index of the character in a Java chars.
-     * @return a new instance of {@link RectF} that represents the location of the character in
-     * local coordinates. null if the character is invisible or the application did not provide
-     * the location. Note that the {@code left} field can be greater than the {@code right} field
-     * if the character is in RTL text. Returns {@code null} if no location information is
-     * available.
-     * @removed
-     */
-    public RectF getCharacterRect(final int index) {
-        return getCharacterBounds(index);
-    }
-
-    /**
      * Returns the flags associated with the character bounds specified with the index.
      * @param index index of the character in a Java chars.
      * @return {@code 0} if no flag is specified.
@@ -633,16 +522,6 @@
     }
 
     /**
-     * Returns the flags associated with the character rect specified with the index.
-     * @param index index of the character in a Java chars.
-     * @return {@code 0} if no flag is specified.
-     * @removed
-     */
-    public int getCharacterRectFlags(final int index) {
-        return getCharacterBoundsFlags(index);
-    }
-
-    /**
      * Returns a new instance of {@link android.graphics.Matrix} that indicates the transformation
      * matrix that is to be applied other positional data in this class.
      * @return a new instance (copy) of the transformation matrix.
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 093fb2f..c51d8a7 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -756,19 +756,4 @@
      * {@link InputMethodManager#updateCursorAnchorInfo(android.view.View, CursorAnchorInfo)}.
      */
     public boolean requestCursorUpdates(int cursorUpdateMode);
-
-    /**
-     * @removed
-     */
-    public static final int REQUEST_UPDATE_CURSOR_UPDATE_IMMEDIATE = 1 << 0;
-
-    /**
-     * @removed
-     */
-    public static final int REQUEST_UPDATE_CURSOR_ANCHOR_INFO_MONITOR = 1 << 1;
-
-    /**
-     * @removed
-     */
-    public boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode);
 }
diff --git a/core/java/android/view/inputmethod/InputConnectionWrapper.java b/core/java/android/view/inputmethod/InputConnectionWrapper.java
index 87853de..231aa07 100644
--- a/core/java/android/view/inputmethod/InputConnectionWrapper.java
+++ b/core/java/android/view/inputmethod/InputConnectionWrapper.java
@@ -129,11 +129,4 @@
     public boolean requestCursorUpdates(int cursorUpdateMode) {
         return mTarget.requestCursorUpdates(cursorUpdateMode);
     }
-
-    /**
-     * @removed
-     */
-    public final boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) {
-        return mTarget.requestCursorUpdates(cursorUpdateMode);
-    }
 }
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 94d52d5..3859e48 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -5721,14 +5721,6 @@
         public boolean requestCursorUpdates(int cursorUpdateMode) {
             return getTarget().requestCursorUpdates(cursorUpdateMode);
         }
-
-        /**
-         * @removed
-         */
-        @Override
-        public boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) {
-            return getTarget().requestCursorUpdates(cursorUpdateMode);
-        }
     }
 
     /**
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a81ff97..1509e80 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8178,6 +8178,8 @@
      * Returns the TextView_textColor attribute from the TypedArray, if set, or
      * the TextAppearance_textColor from the TextView_textAppearance attribute,
      * if TextView_textColor was not set directly.
+     *
+     * @removed
      */
     public static ColorStateList getTextColors(Context context, TypedArray attrs) {
         // It's not safe to use this method from apps. The parameter 'attrs'
@@ -8205,6 +8207,8 @@
      * AttributeSet, if set, or the default color from the
      * TextAppearance_textColor from the TextView_textAppearance attribute, if
      * TextView_textColor was not set directly.
+     *
+     * @removed
      */
     public static int getTextColor(Context context, TypedArray attrs, int def) {
         final ColorStateList colors = getTextColors(context, attrs);
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index be28199..ba2d5b8 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -37,7 +37,6 @@
 import android.view.ViewGroup;
 
 import com.android.internal.R;
-import com.android.internal.app.ToolbarActionBar;
 import com.android.internal.view.menu.MenuBuilder;
 import com.android.internal.view.menu.MenuItemImpl;
 import com.android.internal.view.menu.MenuPresenter;
@@ -1007,8 +1006,15 @@
     }
 
     private void addSystemView(View v) {
-        final LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
-                LayoutParams.WRAP_CONTENT);
+        final ViewGroup.LayoutParams vlp = v.getLayoutParams();
+        final LayoutParams lp;
+        if (vlp == null) {
+            lp = generateDefaultLayoutParams();
+        } else if (!checkLayoutParams(vlp)) {
+            lp = generateLayoutParams(vlp);
+        } else {
+            lp = (LayoutParams) vlp;
+        }
         lp.mViewType = LayoutParams.SYSTEM;
         addView(v, lp);
     }
@@ -1280,27 +1286,36 @@
         final int[] collapsingMargins = mTempMargins;
         collapsingMargins[0] = collapsingMargins[1] = 0;
 
+        // Align views within the minimum toolbar height, if set.
+        final int alignmentHeight = getMinimumHeight();
+
         if (shouldLayout(mNavButtonView)) {
             if (isRtl) {
-                right = layoutChildRight(mNavButtonView, right, collapsingMargins);
+                right = layoutChildRight(mNavButtonView, right, collapsingMargins,
+                        alignmentHeight);
             } else {
-                left = layoutChildLeft(mNavButtonView, left, collapsingMargins);
+                left = layoutChildLeft(mNavButtonView, left, collapsingMargins,
+                        alignmentHeight);
             }
         }
 
         if (shouldLayout(mCollapseButtonView)) {
             if (isRtl) {
-                right = layoutChildRight(mCollapseButtonView, right, collapsingMargins);
+                right = layoutChildRight(mCollapseButtonView, right, collapsingMargins,
+                        alignmentHeight);
             } else {
-                left = layoutChildLeft(mCollapseButtonView, left, collapsingMargins);
+                left = layoutChildLeft(mCollapseButtonView, left, collapsingMargins,
+                        alignmentHeight);
             }
         }
 
         if (shouldLayout(mMenuView)) {
             if (isRtl) {
-                left = layoutChildLeft(mMenuView, left, collapsingMargins);
+                left = layoutChildLeft(mMenuView, left, collapsingMargins,
+                        alignmentHeight);
             } else {
-                right = layoutChildRight(mMenuView, right, collapsingMargins);
+                right = layoutChildRight(mMenuView, right, collapsingMargins,
+                        alignmentHeight);
             }
         }
 
@@ -1311,17 +1326,21 @@
 
         if (shouldLayout(mExpandedActionView)) {
             if (isRtl) {
-                right = layoutChildRight(mExpandedActionView, right, collapsingMargins);
+                right = layoutChildRight(mExpandedActionView, right, collapsingMargins,
+                        alignmentHeight);
             } else {
-                left = layoutChildLeft(mExpandedActionView, left, collapsingMargins);
+                left = layoutChildLeft(mExpandedActionView, left, collapsingMargins,
+                        alignmentHeight);
             }
         }
 
         if (shouldLayout(mLogoView)) {
             if (isRtl) {
-                right = layoutChildRight(mLogoView, right, collapsingMargins);
+                right = layoutChildRight(mLogoView, right, collapsingMargins,
+                        alignmentHeight);
             } else {
-                left = layoutChildLeft(mLogoView, left, collapsingMargins);
+                left = layoutChildLeft(mLogoView, left, collapsingMargins,
+                        alignmentHeight);
             }
         }
 
@@ -1434,13 +1453,15 @@
         addCustomViewsWithGravity(mTempViews, Gravity.LEFT);
         final int leftViewsCount = mTempViews.size();
         for (int i = 0; i < leftViewsCount; i++) {
-            left = layoutChildLeft(mTempViews.get(i), left, collapsingMargins);
+            left = layoutChildLeft(mTempViews.get(i), left, collapsingMargins,
+                    alignmentHeight);
         }
 
         addCustomViewsWithGravity(mTempViews, Gravity.RIGHT);
         final int rightViewsCount = mTempViews.size();
         for (int i = 0; i < rightViewsCount; i++) {
-            right = layoutChildRight(mTempViews.get(i), right, collapsingMargins);
+            right = layoutChildRight(mTempViews.get(i), right, collapsingMargins,
+                    alignmentHeight);
         }
 
         // Centered views try to center with respect to the whole bar, but views pinned
@@ -1459,8 +1480,10 @@
 
         final int centerViewsCount = mTempViews.size();
         for (int i = 0; i < centerViewsCount; i++) {
-            centerLeft = layoutChildLeft(mTempViews.get(i), centerLeft, collapsingMargins);
+            centerLeft = layoutChildLeft(mTempViews.get(i), centerLeft, collapsingMargins,
+                    alignmentHeight);
         }
+
         mTempViews.clear();
     }
 
@@ -1483,46 +1506,49 @@
         return width;
     }
 
-    private int layoutChildLeft(View child, int left, int[] collapsingMargins) {
+    private int layoutChildLeft(View child, int left, int[] collapsingMargins,
+            int alignmentHeight) {
         final LayoutParams lp = (LayoutParams) child.getLayoutParams();
         final int l = lp.leftMargin - collapsingMargins[0];
         left += Math.max(0, l);
         collapsingMargins[0] = Math.max(0, -l);
-        final int top = getChildTop(child);
+        final int top = getChildTop(child, alignmentHeight);
         final int childWidth = child.getMeasuredWidth();
         child.layout(left, top, left + childWidth, top + child.getMeasuredHeight());
         left += childWidth + lp.rightMargin;
         return left;
     }
 
-    private int layoutChildRight(View child, int right, int[] collapsingMargins) {
+    private int layoutChildRight(View child, int right, int[] collapsingMargins,
+            int alignmentHeight) {
         final LayoutParams lp = (LayoutParams) child.getLayoutParams();
         final int r = lp.rightMargin - collapsingMargins[1];
         right -= Math.max(0, r);
         collapsingMargins[1] = Math.max(0, -r);
-        final int top = getChildTop(child);
+        final int top = getChildTop(child, alignmentHeight);
         final int childWidth = child.getMeasuredWidth();
         child.layout(right - childWidth, top, right, top + child.getMeasuredHeight());
         right -= childWidth + lp.leftMargin;
         return right;
     }
 
-    private int getChildTop(View child) {
+    private int getChildTop(View child, int alignmentHeight) {
         final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+        final int childHeight = child.getMeasuredHeight();
+        final int alignmentOffset = alignmentHeight > 0 ? (childHeight - alignmentHeight) / 2 : 0;
         switch (getChildVerticalGravity(lp.gravity)) {
             case Gravity.TOP:
-                return getPaddingTop();
+                return getPaddingTop() - alignmentOffset;
 
             case Gravity.BOTTOM:
-                return getHeight() - getPaddingBottom() -
-                        child.getMeasuredHeight() - lp.bottomMargin;
+                return getHeight() - getPaddingBottom() - childHeight
+                        - lp.bottomMargin - alignmentOffset;
 
             default:
             case Gravity.CENTER_VERTICAL:
                 final int paddingTop = getPaddingTop();
                 final int paddingBottom = getPaddingBottom();
                 final int height = getHeight();
-                final int childHeight = child.getMeasuredHeight();
                 final int space = height - paddingTop - paddingBottom;
                 int spaceAbove = (space - childHeight) / 2;
                 if (spaceAbove < lp.topMargin) {
diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java
index 99c87ea..4410f25 100644
--- a/core/java/com/android/internal/app/ToolbarActionBar.java
+++ b/core/java/com/android/internal/app/ToolbarActionBar.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
 import android.view.ActionMode;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -33,7 +32,6 @@
 import android.view.WindowCallbackWrapper;
 import android.widget.SpinnerAdapter;
 import android.widget.Toolbar;
-import com.android.internal.R;
 import com.android.internal.view.menu.MenuBuilder;
 import com.android.internal.view.menu.MenuPresenter;
 import com.android.internal.widget.DecorToolbar;
@@ -48,8 +46,6 @@
     private Window.Callback mWindowCallback;
     private boolean mMenuCallbackSet;
 
-    private CharSequence mHomeDescription;
-
     private boolean mLastMenuVisibility;
     private ArrayList<OnMenuVisibilityListener> mMenuVisibilityListeners =
             new ArrayList<OnMenuVisibilityListener>();
@@ -76,8 +72,6 @@
         mDecorToolbar.setWindowCallback(mWindowCallback);
         toolbar.setOnMenuItemClickListener(mMenuClicker);
         mDecorToolbar.setWindowTitle(title);
-        mHomeDescription = mToolbar.getNavigationContentDescription();
-        updateNavDescription();
     }
 
     public Window.Callback getWrappedWindowCallback() {
@@ -168,8 +162,7 @@
 
     @Override
     public void setHomeActionContentDescription(CharSequence description) {
-        mToolbar.setNavigationContentDescription(description);
-        mHomeDescription = description;
+        mDecorToolbar.setNavigationContentDescription(description);
     }
 
     @Override
@@ -179,8 +172,7 @@
 
     @Override
     public void setHomeActionContentDescription(int resId) {
-        mToolbar.setNavigationContentDescription(resId);
-        mHomeDescription = mToolbar.getNavigationContentDescription();
+        mDecorToolbar.setNavigationContentDescription(resId);
     }
 
     @Override
@@ -258,21 +250,7 @@
     @Override
     public void setDisplayOptions(@DisplayOptions int options, @DisplayOptions int mask) {
         final int currentOptions = mDecorToolbar.getDisplayOptions();
-        final int changed = (options ^ currentOptions) & mask;
         mDecorToolbar.setDisplayOptions(options & mask | currentOptions & ~mask);
-        if ((changed & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
-            updateNavDescription();
-        }
-    }
-
-    private void updateNavDescription() {
-        if ((mDecorToolbar.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
-            if (TextUtils.isEmpty(mHomeDescription)) {
-                mToolbar.setNavigationContentDescription(R.string.action_bar_up_description);
-            } else {
-                mToolbar.setNavigationContentDescription(mHomeDescription);
-            }
-        }
     }
 
     @Override
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 0aee0e3..40c9ed2 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -254,12 +254,20 @@
         preloadClasses();
         preloadResources();
         preloadOpenGL();
+        preloadSharedLibraries();
         // Ask the WebViewFactory to do any initialization that must run in the zygote process,
         // for memory sharing purposes.
         WebViewFactory.prepareWebViewInZygote();
         Log.d(TAG, "end preload");
     }
 
+    private static void preloadSharedLibraries() {
+        Log.i(TAG, "Preloading shared libraries...");
+        System.loadLibrary("android");
+        System.loadLibrary("compiler_rt");
+        System.loadLibrary("jnigraphics");
+    }
+
     private static void preloadOpenGL() {
         if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false)) {
             EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java
index 0c65ad1..7dc927f 100644
--- a/core/java/com/android/internal/view/InputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/InputConnectionWrapper.java
@@ -445,11 +445,4 @@
         }
         return result;
     }
-
-    /**
-     * @removed
-     */
-    public boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) {
-        return requestCursorUpdates(cursorUpdateMode);
-    }
 }
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index e53af69..fb44e58 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -135,6 +135,7 @@
 
     private ExpandedActionViewMenuPresenter mExpandedMenuPresenter;
     View mExpandedActionView;
+    private int mDefaultUpDescription = R.string.action_bar_up_description;
 
     Window.Callback mWindowCallback;
 
@@ -187,7 +188,7 @@
         mExpandedHomeLayout.setShowUp(true);
         mExpandedHomeLayout.setOnClickListener(mExpandedActionViewUpListener);
         mExpandedHomeLayout.setContentDescription(getResources().getText(
-                R.string.action_bar_up_description));
+                mDefaultUpDescription));
 
         // This needs to highlight/be focusable on its own.
         // TODO: Clean up the handoff between expanded/normal.
@@ -579,7 +580,7 @@
             homeDesc = mHomeDescription;
         } else {
             if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
-                homeDesc = mContext.getResources().getText(R.string.action_bar_up_description);
+                homeDesc = mContext.getResources().getText(mDefaultUpDescription);
             } else {
                 homeDesc = mContext.getResources().getText(R.string.action_bar_home_description);
             }
@@ -1330,6 +1331,15 @@
         updateHomeAccessibility(mUpGoerFive.isEnabled());
     }
 
+    @Override
+    public void setDefaultNavigationContentDescription(int defaultNavigationContentDescription) {
+        if (mDefaultUpDescription == defaultNavigationContentDescription) {
+            return;
+        }
+        mDefaultUpDescription = defaultNavigationContentDescription;
+        updateHomeAccessibility(mUpGoerFive.isEnabled());
+    }
+
     static class SavedState extends BaseSavedState {
         int expandedMenuItemId;
         boolean isOverflowOpen;
diff --git a/core/java/com/android/internal/widget/DecorToolbar.java b/core/java/com/android/internal/widget/DecorToolbar.java
index 5281045..fee3015 100644
--- a/core/java/com/android/internal/widget/DecorToolbar.java
+++ b/core/java/com/android/internal/widget/DecorToolbar.java
@@ -89,6 +89,7 @@
     void setNavigationIcon(int resId);
     void setNavigationContentDescription(CharSequence description);
     void setNavigationContentDescription(int resId);
+    void setDefaultNavigationContentDescription(int defaultNavigationContentDescription);
     void saveHierarchyState(SparseArray<Parcelable> toolbarStates);
     void restoreHierarchyState(SparseArray<Parcelable> toolbarStates);
 }
diff --git a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
index 250bbac..8446e06 100644
--- a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
+++ b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
@@ -76,14 +76,21 @@
     private boolean mTitleSet;
     private CharSequence mTitle;
     private CharSequence mSubtitle;
+    private CharSequence mHomeDescription;
 
     private Window.Callback mWindowCallback;
     private boolean mMenuPrepared;
     private ActionMenuPresenter mActionMenuPresenter;
 
     private int mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD;
+    private int mDefaultNavigationContentDescription = 0;
 
     public ToolbarWidgetWrapper(Toolbar toolbar, boolean style) {
+        this(toolbar, style, R.string.action_bar_up_description);
+    }
+
+    public ToolbarWidgetWrapper(Toolbar toolbar, boolean style,
+            int defaultNavigationContentDescription) {
         mToolbar = toolbar;
 
         mTitle = toolbar.getTitle();
@@ -166,10 +173,8 @@
             mDisplayOpts = detectDisplayOptions();
         }
 
-        if (TextUtils.isEmpty(mToolbar.getNavigationContentDescription())) {
-            mToolbar.setNavigationContentDescription(
-                    getContext().getResources().getText(R.string.action_bar_up_description));
-        }
+        setDefaultNavigationContentDescription(defaultNavigationContentDescription);
+        mHomeDescription = mToolbar.getNavigationContentDescription();
 
         mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
             final ActionMenuItem mNavItem = new ActionMenuItem(mToolbar.getContext(),
@@ -183,6 +188,17 @@
         });
     }
 
+    @Override
+    public void setDefaultNavigationContentDescription(int defaultNavigationContentDescription) {
+        if (defaultNavigationContentDescription == mDefaultNavigationContentDescription) {
+            return;
+        }
+        mDefaultNavigationContentDescription = defaultNavigationContentDescription;
+        if (TextUtils.isEmpty(mToolbar.getNavigationContentDescription())) {
+            setNavigationContentDescription(mDefaultNavigationContentDescription);
+        }
+    }
+
     private int detectDisplayOptions() {
         int opts = ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME |
                 ActionBar.DISPLAY_USE_LOGO;
@@ -395,6 +411,7 @@
             if ((changed & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
                 if ((newOpts & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
                     mToolbar.setNavigationIcon(mNavIcon);
+                    updateHomeAccessibility();
                 } else {
                     mToolbar.setNavigationIcon(null);
                 }
@@ -602,12 +619,23 @@
 
     @Override
     public void setNavigationContentDescription(CharSequence description) {
-        mToolbar.setNavigationContentDescription(description);
+        mHomeDescription = description;
+        updateHomeAccessibility();
     }
 
     @Override
     public void setNavigationContentDescription(int resId) {
-        mToolbar.setNavigationContentDescription(resId);
+        setNavigationContentDescription(resId == 0 ? null : getContext().getString(resId));
+    }
+
+    private void updateHomeAccessibility() {
+        if ((mDisplayOpts & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+            if (TextUtils.isEmpty(mHomeDescription)) {
+                mToolbar.setNavigationContentDescription(mDefaultNavigationContentDescription);
+            } else {
+                mToolbar.setNavigationContentDescription(mHomeDescription);
+            }
+        }
     }
 
     @Override
diff --git a/core/java/com/android/server/BootReceiver.java b/core/java/com/android/server/BootReceiver.java
index 7249985..468d7f1 100644
--- a/core/java/com/android/server/BootReceiver.java
+++ b/core/java/com/android/server/BootReceiver.java
@@ -123,8 +123,15 @@
         }
 
         if (SystemProperties.getLong("ro.runtime.firstboot", 0) == 0) {
-            String now = Long.toString(System.currentTimeMillis());
-            SystemProperties.set("ro.runtime.firstboot", now);
+            if ("encrypted".equals(SystemProperties.get("ro.crypto.state"))
+                && "trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))){
+                // Encrypted, first boot to get PIN/pattern/password so data is tmpfs
+                // Don't set ro.runtime.firstboot so that we will do this again
+                // when data is properly mounted
+            } else {
+                String now = Long.toString(System.currentTimeMillis());
+                SystemProperties.set("ro.runtime.firstboot", now);
+            }
             if (db != null) db.addText("SYSTEM_BOOT", headers);
 
             // Negative sizes mean to take the *tail* of the file (see FileUtils.readTextFile())
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index a63258c..1573106 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -271,6 +271,7 @@
 }
 
 void AndroidRuntime::setArgv0(const char* argv0) {
+    memset(mArgBlockStart, 0, mArgBlockLength);
     strlcpy(mArgBlockStart, argv0, mArgBlockLength);
 }
 
@@ -345,28 +346,6 @@
     return state && state->getStrictModePolicy() != 0;
 }
 
-
-/**
- * Add VM arguments to the to-be-executed VM
- * Stops at first non '-' argument (also stops at an argument of '--')
- * Returns the number of args consumed
- */
-int AndroidRuntime::addVmArguments(int argc, const char* const argv[])
-{
-    int i;
-
-    for (i = 0; i<argc; i++) {
-        if (argv[i][0] != '-') {
-            return i;
-        }
-        if (argv[i][1] == '-' && argv[i][2] == 0) {
-            return i+1;
-        }
-        addOption(argv[i]);
-    }
-    return i;
-}
-
 static int hasDir(const char* dir)
 {
     struct stat s;
diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp
index 6ef1d2c..9d3e74b 100644
--- a/core/jni/android/graphics/Path.cpp
+++ b/core/jni/android/graphics/Path.cpp
@@ -435,19 +435,32 @@
         std::vector<float> lengths;
         float errorSquared = acceptableError * acceptableError;
 
-        while ((verb = pathIter.next(points)) != SkPath::kDone_Verb) {
+        while ((verb = pathIter.next(points, false)) != SkPath::kDone_Verb) {
             createVerbSegments(verb, points, segmentPoints, lengths, errorSquared);
         }
 
         if (segmentPoints.empty()) {
-            return NULL;
+            int numVerbs = path->countVerbs();
+            if (numVerbs == 1) {
+                addMove(segmentPoints, lengths, path->getPoint(0));
+            } else {
+                // Invalid or empty path. Fall back to point(0,0)
+                addMove(segmentPoints, lengths, SkPoint());
+            }
+        }
+
+        float totalLength = lengths.back();
+        if (totalLength == 0) {
+            // Lone Move instructions should still be able to animate at the same value.
+            segmentPoints.push_back(segmentPoints.back());
+            lengths.push_back(1);
+            totalLength = 1;
         }
 
         size_t numPoints = segmentPoints.size();
         size_t approximationArraySize = numPoints * 3;
 
         float* approximation = new float[approximationArraySize];
-        float totalLength = lengths.back();
 
         int approximationIndex = 0;
         for (size_t i = 0; i < numPoints; i++) {
diff --git a/core/res/res/layout/alert_dialog_material.xml b/core/res/res/layout/alert_dialog_material.xml
index be89e41..e5ef629 100644
--- a/core/res/res/layout/alert_dialog_material.xml
+++ b/core/res/res/layout/alert_dialog_material.xml
@@ -56,8 +56,7 @@
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:orientation="vertical"
-        android:minHeight="64dp"
-        android:paddingTop="@dimen/alert_dialog_padding_top_material">
+        android:minHeight="64dp">
         <ScrollView android:id="@+id/scrollView"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
@@ -67,6 +66,7 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:paddingStart="@dimen/alert_dialog_padding_material"
+                android:paddingTop="@dimen/alert_dialog_padding_top_material"
                 android:paddingEnd="@dimen/alert_dialog_padding_material" />
         </ScrollView>
     </LinearLayout>
diff --git a/core/res/res/layout/preference_material.xml b/core/res/res/layout/preference_material.xml
index a137149..39c979c 100644
--- a/core/res/res/layout/preference_material.xml
+++ b/core/res/res/layout/preference_material.xml
@@ -42,6 +42,7 @@
             android:id="@+id/icon"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:adjustViewBounds="true"
             android:maxWidth="48dp"
             android:maxHeight="48dp" />
     </LinearLayout>
diff --git a/core/res/res/values-mcc234-mnc20/config.xml b/core/res/res/values-mcc234-mnc20/config.xml
index 1ed53dc..619e517 100644
--- a/core/res/res/values-mcc234-mnc20/config.xml
+++ b/core/res/res/values-mcc234-mnc20/config.xml
@@ -21,6 +21,22 @@
      for different hardware and product builds. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+        <item>1</item>
+        <item>4</item>
+        <item>7</item>
+        <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string translatable="false" name="config_tether_apndata">3hotspot,3hotspot,,,,,,,,,234,20,0,DUN</string>
+
     <!-- Configure mobile network MTU. Carrier specific value is set here.
     -->
     <integer name="config_mobile_mtu">1440</integer>
diff --git a/core/res/res/values-mcc235-mnc94/config.xml b/core/res/res/values-mcc235-mnc94/config.xml
index d602c9f..723af3d 100644
--- a/core/res/res/values-mcc235-mnc94/config.xml
+++ b/core/res/res/values-mcc235-mnc94/config.xml
@@ -21,6 +21,22 @@
      for different hardware and product builds. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+        <item>1</item>
+        <item>4</item>
+        <item>7</item>
+        <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string translatable="false" name="config_tether_apndata">3hotspot,3hotspot,,,,,,,,,235,94,0,DUN</string>
+
     <!-- Configure mobile network MTU. Carrier specific value is set here.
     -->
     <integer name="config_mobile_mtu">1440</integer>
diff --git a/core/res/res/values-mcc310-mnc120/config.xml b/core/res/res/values-mcc310-mnc120/config.xml
index 62001d9..24e55b1 100644
--- a/core/res/res/values-mcc310-mnc120/config.xml
+++ b/core/res/res/values-mcc310-mnc120/config.xml
@@ -25,4 +25,6 @@
     -->
     <integer name="config_mobile_mtu">1422</integer>
 
+    <!-- Sprint need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">70</integer>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc220/config.xml b/core/res/res/values-mcc311-mnc220/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc220/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc221/config.xml b/core/res/res/values-mcc311-mnc221/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc221/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc222/config.xml b/core/res/res/values-mcc311-mnc222/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc222/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc223/config.xml b/core/res/res/values-mcc311-mnc223/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc223/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc224/config.xml b/core/res/res/values-mcc311-mnc224/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc224/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc225/config.xml b/core/res/res/values-mcc311-mnc225/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc225/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc226/config.xml b/core/res/res/values-mcc311-mnc226/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc226/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc227/config.xml b/core/res/res/values-mcc311-mnc227/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc227/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc228/config.xml b/core/res/res/values-mcc311-mnc228/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc228/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc229/config.xml b/core/res/res/values-mcc311-mnc229/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc229/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc490/config.xml b/core/res/res/values-mcc311-mnc490/config.xml
new file mode 100644
index 0000000..defe78d
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc490/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Sprint need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">70</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc580/config.xml b/core/res/res/values-mcc311-mnc580/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc580/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc581/config.xml b/core/res/res/values-mcc311-mnc581/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc581/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc582/config.xml b/core/res/res/values-mcc311-mnc582/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc582/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc583/config.xml b/core/res/res/values-mcc311-mnc583/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc583/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc584/config.xml b/core/res/res/values-mcc311-mnc584/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc584/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc585/config.xml b/core/res/res/values-mcc311-mnc585/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc585/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc586/config.xml b/core/res/res/values-mcc311-mnc586/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc586/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc587/config.xml b/core/res/res/values-mcc311-mnc587/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc587/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc588/config.xml b/core/res/res/values-mcc311-mnc588/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc588/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc589/config.xml b/core/res/res/values-mcc311-mnc589/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc589/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- USC need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc870/config.xml b/core/res/res/values-mcc311-mnc870/config.xml
new file mode 100644
index 0000000..24e55b1
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc870/config.xml
@@ -0,0 +1,30 @@
+<?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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1422</integer>
+
+    <!-- Sprint need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">70</integer>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc530/config.xml b/core/res/res/values-mcc312-mnc530/config.xml
new file mode 100644
index 0000000..24e55b1
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc530/config.xml
@@ -0,0 +1,30 @@
+<?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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1422</integer>
+
+    <!-- Sprint need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">70</integer>
+</resources>
diff --git a/core/res/res/values-mcc425-mnc01/config.xml b/core/res/res/values-mcc425-mnc01/config.xml
deleted file mode 100644
index f4854da..0000000
--- a/core/res/res/values-mcc425-mnc01/config.xml
+++ /dev/null
@@ -1,40 +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 my 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.
-*/
--->
-
-<!-- These resources are around just to allow their values to be customized
-     for different hardware and product builds. -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
-    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
-    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
-    <integer-array translatable="false" name="config_tether_upstream_types">
-      <item>1</item>
-      <item>4</item>
-      <item>7</item>
-      <item>9</item>
-    </integer-array>
-
-    <!-- String containing the apn value for tethering.  May be overriden by secure settings
-         TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
-         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">DUN,modem.orange.net.il,,,,,,,,,425,01,,DUN</string>
-
-</resources>
diff --git a/core/res/res/values-sw600dp-land/dimens_material.xml b/core/res/res/values-sw600dp-land/dimens_material.xml
new file mode 100644
index 0000000..f8f16e2
--- /dev/null
+++ b/core/res/res/values-sw600dp-land/dimens_material.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+<resources>
+
+    <!-- Use the default title sizes on tablets. -->
+    <dimen name="text_size_title_material_toolbar">@dimen/text_size_title_material</dimen>
+    <!-- Use the default subtitle sizes on tablets. -->
+    <dimen name="text_size_subtitle_material_toolbar">@dimen/text_size_subhead_material</dimen>
+
+</resources>
diff --git a/core/res/res/values-sw720dp/styles.xml b/core/res/res/values-sw720dp/styles.xml
index fee1c24f..94ec0a6 100644
--- a/core/res/res/values-sw720dp/styles.xml
+++ b/core/res/res/values-sw720dp/styles.xml
@@ -16,10 +16,9 @@
 
 <resources>
     <style name="PreferencePanel">
-        <item name="android:layout_marginStart">@dimen/preference_screen_side_margin</item>
-        <item name="android:layout_marginEnd">@dimen/preference_screen_side_margin</item>
-        <item name="android:layout_marginTop">@dimen/preference_screen_top_margin</item>
-        <item name="android:layout_marginBottom">@dimen/preference_screen_bottom_margin</item>
-        <item name="android:background">?attr/detailsElementBackground</item>
+        <item name="layout_marginStart">@dimen/preference_screen_side_margin</item>
+        <item name="layout_marginEnd">@dimen/preference_screen_side_margin</item>
+        <item name="layout_marginTop">@dimen/preference_screen_top_margin</item>
+        <item name="layout_marginBottom">@dimen/preference_screen_bottom_margin</item>
     </style>
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 13b1dd920..438d1fb 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -458,6 +458,10 @@
              transitions between different window content. -->
         <attr name="windowContentTransitionManager" format="reference" />
 
+        <!-- Flag indicating whether this window allows Activity Transitions.
+             Corresponds to {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS}. -->
+        <attr name="windowActivityTransitions" format="boolean" />
+
         <!-- Reference to a Transition XML resource defining the desired Transition
              used to move Views into the initial Window's content Scene. Corresponds to
              {@link android.view.Window#setEnterTransition(android.transition.Transition)}. -->
@@ -1792,6 +1796,7 @@
         <attr name="windowTranslucentNavigation" />
         <attr name="windowSwipeToDismiss" />
         <attr name="windowContentTransitions" />
+        <attr name="windowActivityTransitions" />
         <attr name="windowContentTransitionManager" />
         <attr name="windowActionBarFullscreenDecorLayout" />
 
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d67690a..3907fc5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -360,6 +360,9 @@
     <!-- Boolean indicating associated network selection is allowed -->
     <bool translatable="false" name="config_wifi_framework_enable_associated_network_selection">true</bool>
 
+    <!-- Boolean indicating that wifi only link configuratios that have exact same credentials (i.e PSK) -->
+    <bool translatable="false" name="config_wifi_only_link_same_credential_configurations">true</bool>
+
     <!-- Wifi driver stop delay, in milliseconds.
          Default value is 2 minutes. -->
     <integer translatable="false" name="config_wifi_driver_stop_delay">120000</integer>
@@ -1746,4 +1749,7 @@
          (3) If the config_default_vm_number array has gid special item but it doesn't match the
          current sim's gid, the last one without gid will be picked -->
     <string-array translatable="false" name="config_default_vm_number" />
+
+    <!-- Sprint need a 70 ms delay for 3way call -->
+    <integer name="config_cdma_3waycall_flash_delay">0</integer>
 </resources>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index 275a5ec..3e64f30 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -41,11 +41,11 @@
     <dimen name="text_size_headline_material">24sp</dimen>
     <dimen name="text_size_title_material">20sp</dimen>
     <dimen name="text_size_subhead_material">16sp</dimen>
-    <dimen name="text_size_title_material_toolbar">20dp</dimen>
-    <dimen name="text_size_subtitle_material_toolbar">16dp</dimen>
+    <dimen name="text_size_title_material_toolbar">@dimen/text_size_title_material</dimen>
+    <dimen name="text_size_subtitle_material_toolbar">@dimen/text_size_subhead_material</dimen>
     <dimen name="text_size_menu_material">16sp</dimen>
-    <dimen name="text_size_body_2_material">14sp</dimen>
-    <dimen name="text_size_body_1_material">14sp</dimen>
+    <dimen name="text_size_body_2_material">16sp</dimen>
+    <dimen name="text_size_body_1_material">16sp</dimen>
     <dimen name="text_size_caption_material">12sp</dimen>
     <dimen name="text_size_button_material">14sp</dimen>
 
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 38b1e13..99918a0 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2293,6 +2293,7 @@
   <public type="attr" name="patternPathData" />
   <public type="attr" name="strokeAlpha" />
   <public type="attr" name="fillAlpha" />
+  <public type="attr" name="windowActivityTransitions" />
 
   <public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
 
@@ -2561,6 +2562,9 @@
 
   <public type="style" name="Widget.Material.SearchView" />
   <public type="style" name="Widget.Material.Light.SearchView" />
+  <public type="style" name="Widget.Material.TimePicker" />
+  <public type="style" name="Widget.Material.Light.TimePicker" />
+  <public type="style" name="Widget.Material.Light.DatePicker" />
 
   <public-padding type="string" name="l_resource_pad" end="0x01040030" />
 
diff --git a/core/res/res/values/styles_leanback.xml b/core/res/res/values/styles_leanback.xml
index 7606c86..aaeaadd 100644
--- a/core/res/res/values/styles_leanback.xml
+++ b/core/res/res/values/styles_leanback.xml
@@ -36,24 +36,28 @@
     <!-- Setup and form wizard themes -->
     <style name="TextAppearance.Leanback.FormWizard" parent="@style/TextAppearance.Material">
         <item name="textSize">18sp</item>
+        <item name="lineSpacingExtra">24sp</item>
         <item name="fontFamily">sans-serif-light</item>
         <item name="textColor">?attr/textColorPrimary</item>
     </style>
 
     <style name="TextAppearance.Leanback.FormWizard.Small" parent="@style/TextAppearance.Material.Small">
-        <item name="textSize">18sp</item>
+        <item name="textSize">14sp</item>
+        <item name="lineSpacingExtra">24sp</item>
         <item name="fontFamily">sans-serif-light</item>
         <item name="textColor">?attr/textColorPrimary</item>
     </style>
 
     <style name="TextAppearance.Leanback.FormWizard.Medium" parent="@style/TextAppearance.Material.Medium">
         <item name="textSize">36sp</item>
+        <item name="lineSpacingExtra">40sp</item>
         <item name="fontFamily">sans-serif-thin</item>
         <item name="textColor">?attr/textColorPrimary</item>
     </style>
 
     <style name="TextAppearance.Leanback.FormWizard.Large" parent="@style/TextAppearance.Material.Large">
-        <item name="textSize">56sp</item>
+        <item name="textSize">42sp</item>
+        <item name="lineSpacingExtra">48sp</item>
         <item name="fontFamily">sans-serif-thin</item>
         <item name="textColor">?attr/textColorPrimary</item>
     </style>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 26c7d10..836f886 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -851,10 +851,7 @@
         <item name="src">@drawable/ic_menu_moreoverflow_material</item>
         <item name="background">?attr/actionBarItemBackground</item>
         <item name="contentDescription">@string/action_menu_overflow_description</item>
-        <item name="minWidth">@dimen/action_button_min_width_material</item>
-        <item name="minHeight">@dimen/action_button_min_height_material</item>
         <item name="paddingEnd">12dp</item>
-        <item name="scaleType">center</item>
     </style>
 
     <style name="Widget.Material.ActionBar.TabView" parent="Widget.ActionBar.TabView">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 221269d..7fc522f 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -296,7 +296,7 @@
   <java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" />
   <java-symbol type="bool" name="config_wifi_framework_enable_associated_autojoin_scan" />
   <java-symbol type="bool" name="config_wifi_framework_enable_associated_network_selection" />
-
+  <java-symbol type="bool" name="config_wifi_only_link_same_credential_configurations" />
   <java-symbol type="integer" name="config_bluetooth_max_advertisers" />
   <java-symbol type="integer" name="config_bluetooth_max_scan_filters" />
   <java-symbol type="integer" name="config_cursorWindowSize" />
@@ -2014,4 +2014,5 @@
   <java-symbol type="attr" name="closeItemLayout" />
   <java-symbol type="layout" name="resolver_different_item_header" />
   <java-symbol type="array" name="config_default_vm_number" />
+  <java-symbol type="integer" name="config_cdma_3waycall_flash_delay"/>
 </resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 48de5ad..d0097aac 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -192,6 +192,7 @@
         <item name="navigationBarColor">@color/black</item>
         <item name="windowActionBarFullscreenDecorLayout">@layout/screen_action_bar</item>
         <item name="windowContentTransitions">false</item>
+        <item name="windowActivityTransitions">false</item>
 
         <!-- Define these here; ContextThemeWrappers around themes that define them should
              always clear these values. -->
@@ -816,6 +817,7 @@
     <!-- Theme for the dialog shown when an app crashes or ANRs. -->
     <style name="Theme.Dialog.AppError" parent="Theme.DeviceDefault.Light.Dialog.Alert">
         <item name="windowContentTransitions">false</item>
+        <item name="windowActivityTransitions">false</item>
         <item name="windowCloseOnTouchOutside">false</item>
     </style>
 
@@ -827,6 +829,7 @@
         <item name="textColor">@color/secondary_text_nofocus</item>
         <item name="windowCloseOnTouchOutside">false</item>
         <item name="windowContentTransitions">false</item>
+        <item name="windowActivityTransitions">false</item>
     </style>
 
     <!-- Theme for a window that looks like a toast. -->
@@ -836,6 +839,7 @@
         <item name="backgroundDimEnabled">false</item>
         <item name="windowCloseOnTouchOutside">false</item>
         <item name="windowContentTransitions">false</item>
+        <item name="windowActivityTransitions">false</item>
     </style>
 
 </resources>
diff --git a/core/res/res/values/themes_leanback.xml b/core/res/res/values/themes_leanback.xml
index 720733f..82cf288 100644
--- a/core/res/res/values/themes_leanback.xml
+++ b/core/res/res/values/themes_leanback.xml
@@ -76,6 +76,7 @@
 
     <style name="Theme.Leanback.Dialog.AppError" parent="Theme.Leanback.Dialog">
         <item name="windowContentTransitions">false</item>
+        <item name="windowActivityTransitions">false</item>
         <item name="windowCloseOnTouchOutside">false</item>
     </style>
 
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 485ea08..008e170 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -157,7 +157,8 @@
         <item name="windowTitleStyle">@style/WindowTitle.Material</item>
         <item name="windowTitleSize">@dimen/action_bar_default_height_material</item>
         <item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Material</item>
-        <item name="windowContentTransitions">true</item>
+        <item name="windowContentTransitions">false</item>
+        <item name="windowActivityTransitions">true</item>
         <item name="windowAnimationStyle">@style/Animation.Material.Activity</item>
         <item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
         <item name="windowActionBar">true</item>
@@ -511,7 +512,8 @@
         <item name="windowEnterTransition">@transition/fade</item>
         <item name="windowSharedElementEnterTransition">@transition/move</item>
         <item name="windowSharedElementExitTransition">@transition/move</item>
-        <item name="windowContentTransitions">true</item>
+        <item name="windowContentTransitions">false</item>
+        <item name="windowActivityTransitions">true</item>
 
         <!-- Dialog attributes -->
         <item name="dialogTheme">@style/Theme.Material.Light.Dialog</item>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiAssociationTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiAssociationTestRunner.java
index 2354484..f4ea6f2 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiAssociationTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiAssociationTestRunner.java
@@ -16,17 +16,12 @@
 
 package com.android.connectivitymanagertest;
 
-import android.content.Context;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
 import android.test.InstrumentationTestRunner;
 import android.test.InstrumentationTestSuite;
-import android.util.Log;
 
 import com.android.connectivitymanagertest.functional.WifiAssociationTest;
 
 import junit.framework.TestSuite;
-import junit.framework.Assert;
 
 /**
  * Instrumentation Test Runner for wifi association test.
@@ -39,8 +34,6 @@
  * -w com.android.connectivitymanagertest/.WifiAssociationTestRunner"
  */
 public class WifiAssociationTestRunner extends InstrumentationTestRunner {
-    private static final String TAG = "WifiAssociationTestRunner";
-    public int mBand;
 
     @Override
     public TestSuite getAllTests() {
@@ -53,35 +46,4 @@
     public ClassLoader getLoader() {
         return WifiAssociationTestRunner.class.getClassLoader();
     }
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        String mFrequencyBand = icicle.getString("frequency-band");
-        if (mFrequencyBand != null) {
-            setFrequencyBand(mFrequencyBand);
-        }
-    }
-
-    private void setFrequencyBand(String band) {
-        WifiManager mWifiManager = (WifiManager)getContext().getSystemService(Context.WIFI_SERVICE);
-        if (band.equals("2.4")) {
-            Log.v(TAG, "set frequency band to 2.4");
-            mBand = WifiManager.WIFI_FREQUENCY_BAND_2GHZ;
-        } else if (band.equals("5.0")) {
-            Log.v(TAG, "set frequency band to 5.0");
-            mBand = WifiManager.WIFI_FREQUENCY_BAND_5GHZ;
-        } else if (band.equals("auto")) {
-            Log.v(TAG, "set frequency band to auto");
-            mBand = WifiManager.WIFI_FREQUENCY_BAND_AUTO;
-        } else {
-            Assert.fail("invalid frequency band");
-        }
-        int currentFreq = mWifiManager.getFrequencyBand();
-        if (mBand == currentFreq) {
-            Log.v(TAG, "frequency band has been set");
-            return;
-        }
-        mWifiManager.setFrequencyBand(mBand, true);
-    }
 }
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
index c2b80dc..68f3179 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
@@ -16,14 +16,13 @@
 
 package com.android.connectivitymanagertest.functional;
 
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo.State;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.AuthAlgorithm;
 import android.net.wifi.WifiConfiguration.GroupCipher;
 import android.net.wifi.WifiConfiguration.PairwiseCipher;
 import android.net.wifi.WifiConfiguration.Protocol;
 import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.test.suitebuilder.annotation.LargeTest;
 
@@ -39,13 +38,7 @@
  * -w com.android.connectivitymanagertest/.WifiAssociationTestRunner"
  */
 public class WifiAssociationTest extends ConnectivityManagerTestBase {
-    private String mSsid = null;
-    private String mPassword = null;
-    private String mSecurityType = null;
-    private String mFrequencyBand = null;
-    private int mBand;
-
-    enum SECURITY_TYPE {
+    private enum SecurityType {
         OPEN, WEP64, WEP128, WPA_TKIP, WPA2_AES
     }
 
@@ -53,86 +46,106 @@
         super(WifiAssociationTest.class.getSimpleName());
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        WifiAssociationTestRunner runner = (WifiAssociationTestRunner)getInstrumentation();
-        Bundle arguments = runner.getArguments();
-        mSecurityType = arguments.getString("security-type");
-        mSsid = arguments.getString("ssid");
-        mPassword = arguments.getString("password");
-        mFrequencyBand = arguments.getString("frequency-band");
-        mBand = runner.mBand;
-        assertNotNull("security type is empty", mSecurityType);
-        assertNotNull("ssid is empty", mSsid);
-        validateFrequencyBand();
-
-        // enable wifi and verify wpa_supplicant is started
-        assertTrue("enable Wifi failed", enableWifi());
-        assertTrue("wifi not connected", waitForNetworkState(
-                ConnectivityManager.TYPE_WIFI, State.CONNECTED, LONG_TIMEOUT));
-        WifiInfo wi = mWifiManager.getConnectionInfo();
-        assertNotNull("no active wifi info", wi);
-        assertTrue("failed to ping wpa_supplicant ", mWifiManager.pingSupplicant());
-    }
-
-    private void validateFrequencyBand() {
-        if (mFrequencyBand != null) {
-            int currentFreq = mWifiManager.getFrequencyBand();
-            logv("read frequency band: " + currentFreq);
-            assertEquals("specified frequency band does not match operational band of WifiManager",
-                    currentFreq, mBand);
-         }
-    }
-
+    /**
+     * Test that the wifi can associate with a given access point.
+     */
     @LargeTest
     public void testWifiAssociation() {
-        assertNotNull("no test ssid", mSsid);
+        WifiAssociationTestRunner runner = (WifiAssociationTestRunner) getInstrumentation();
+        Bundle arguments = runner.getArguments();
+
+        String ssid = arguments.getString("ssid");
+        assertNotNull("ssid is empty", ssid);
+
+        String securityTypeStr = arguments.getString("security-type");
+        assertNotNull("security-type is empty", securityTypeStr);
+        SecurityType securityType = SecurityType.valueOf(securityTypeStr);
+
+        String password = arguments.getString("password");
+
+        String freqStr = arguments.getString("frequency-band");
+        if (freqStr != null) {
+            setFrequencyBand(freqStr);
+        }
+
+        assertTrue("enable Wifi failed", enableWifi());
+        WifiInfo wi = mWifiManager.getConnectionInfo();
+        logv("%s", wi);
+        assertNotNull("no active wifi info", wi);
+
+        WifiConfiguration config = getConfig(ssid, securityType, password);
+
+        logv("Network config: %s", config.toString());
+        connectToWifi(config);
+    }
+
+    /**
+     * Set the frequency band and verify that it has been set.
+     */
+    private void setFrequencyBand(String frequencyBandStr) {
+        int frequencyBand = -1;
+        if ("2.4".equals(frequencyBandStr)) {
+            frequencyBand = WifiManager.WIFI_FREQUENCY_BAND_2GHZ;
+        } else if ("5.0".equals(frequencyBandStr)) {
+            frequencyBand = WifiManager.WIFI_FREQUENCY_BAND_5GHZ;
+        } else if ("auto".equals(frequencyBandStr)) {
+            frequencyBand = WifiManager.WIFI_FREQUENCY_BAND_AUTO;
+        } else {
+            fail("Invalid frequency-band");
+        }
+        if (mWifiManager.getFrequencyBand() != frequencyBand) {
+            logv("Set frequency band to %s", frequencyBandStr);
+            mWifiManager.setFrequencyBand(frequencyBand, true);
+        }
+        assertEquals("Specified frequency band does not match operational band",
+                frequencyBand, mWifiManager.getFrequencyBand());
+    }
+
+    /**
+     * Get the {@link WifiConfiguration} based on ssid, security, and password.
+     */
+    private WifiConfiguration getConfig(String ssid, SecurityType securityType, String password) {
+        logv("Security type is %s", securityType.toString());
+
         WifiConfiguration config = null;
-        SECURITY_TYPE security = SECURITY_TYPE.valueOf(mSecurityType);
-        logv("Security type is " + security.toString());
-        switch (security) {
-            // set network configurations
+        switch (securityType) {
             case OPEN:
-                config = WifiConfigurationHelper.createOpenConfig(mSsid);
+                config = WifiConfigurationHelper.createOpenConfig(ssid);
                 break;
             case WEP64:
-                assertNotNull("password is empty", mPassword);
+                assertNotNull("password is empty", password);
                 // always use hex pair for WEP-40
-                assertTrue(WifiConfigurationHelper.isHex(mPassword, 10));
-                config = WifiConfigurationHelper.createWepConfig(mSsid, mPassword);
+                assertTrue(WifiConfigurationHelper.isHex(password, 10));
+                config = WifiConfigurationHelper.createWepConfig(ssid, password);
                 config.allowedGroupCiphers.set(GroupCipher.WEP40);
                 break;
             case WEP128:
-                assertNotNull("password is empty", mPassword);
+                assertNotNull("password is empty", password);
                 // always use hex pair for WEP-104
-                assertTrue(WifiConfigurationHelper.isHex(mPassword, 26));
-                config = WifiConfigurationHelper.createWepConfig(mSsid, mPassword);
+                assertTrue(WifiConfigurationHelper.isHex(password, 26));
+                config = WifiConfigurationHelper.createWepConfig(ssid, password);
                 config.allowedGroupCiphers.set(GroupCipher.WEP104);
                 break;
             case WPA_TKIP:
-                assertNotNull("password is empty", mPassword);
-                config = WifiConfigurationHelper.createPskConfig(mSsid, mPassword);
+                assertNotNull("password is empty", password);
+                config = WifiConfigurationHelper.createPskConfig(ssid, password);
                 config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
                 config.allowedProtocols.set(Protocol.WPA);
                 config.allowedPairwiseCiphers.set(PairwiseCipher.TKIP);
                 config.allowedGroupCiphers.set(GroupCipher.TKIP);
                 break;
             case WPA2_AES:
-                assertNotNull("password is empty", mPassword);
-                config = WifiConfigurationHelper.createPskConfig(mSsid, mPassword);
+                assertNotNull("password is empty", password);
+                config = WifiConfigurationHelper.createPskConfig(ssid, password);
                 config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
                 config.allowedProtocols.set(Protocol.RSN);
                 config.allowedPairwiseCiphers.set(PairwiseCipher.CCMP);
                 config.allowedGroupCiphers.set(GroupCipher.CCMP);
                 break;
             default:
-                fail("Not a valid security type: " + mSecurityType);
+                fail("Not a valid security type: " + securityType);
                 break;
         }
-        logv("network config: %s", config.toString());
-        connectToWifi(config);
-        // verify that connection actually works
-        assertTrue("no network connectivity at end of test", checkNetworkConnectivity());
+        return config;
     }
 }
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 0927ffd..f45c0cb 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -250,11 +250,6 @@
     public void insertInorderBarrier() {}
 
     /**
-     * @hide
-     */
-    public void initializeLight(float lightX, float lightY, float lightZ, float lightRadius) {}
-
-    /**
      * Return true if the device that the current layer draws into is opaque
      * (i.e. does not support per-pixel alpha).
      *
@@ -416,10 +411,10 @@
      * @return       value to pass to restoreToCount() to balance this save()
      */
     public int saveLayer(@Nullable RectF bounds, @Nullable Paint paint, @Saveflags int saveFlags) {
-        return native_saveLayer(mNativeCanvasWrapper,
-                bounds.left, bounds.top, bounds.right, bounds.bottom,
-                paint != null ? paint.mNativePaint : 0,
-                saveFlags);
+        if (bounds == null) {
+            bounds = new RectF(getClipBounds());
+        }
+        return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags);
     }
 
     /**
@@ -462,17 +457,17 @@
      * @param saveFlags see _SAVE_FLAG constants
      * @return          value to pass to restoreToCount() to balance this call
      */
-    public int saveLayerAlpha(@NonNull RectF bounds, int alpha, @Saveflags int saveFlags) {
-        alpha = Math.min(255, Math.max(0, alpha));
-        return native_saveLayerAlpha(mNativeCanvasWrapper,
-                bounds.left, bounds.top, bounds.right, bounds.bottom,
-                alpha, saveFlags);
+    public int saveLayerAlpha(@Nullable RectF bounds, int alpha, @Saveflags int saveFlags) {
+        if (bounds == null) {
+            bounds = new RectF(getClipBounds());
+        }
+        return saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, alpha, saveFlags);
     }
 
     /**
      * Convenience for saveLayerAlpha(bounds, alpha, {@link #ALL_SAVE_FLAG})
      */
-    public int saveLayerAlpha(@NonNull RectF bounds, int alpha) {
+    public int saveLayerAlpha(@Nullable RectF bounds, int alpha) {
         return saveLayerAlpha(bounds, alpha, ALL_SAVE_FLAG);
     }
 
@@ -481,6 +476,7 @@
      */
     public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
             @Saveflags int saveFlags) {
+        alpha = Math.min(255, Math.max(0, alpha));
         return native_saveLayerAlpha(mNativeCanvasWrapper, left, top, right, bottom,
                                      alpha, saveFlags);
     }
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index e1c88cb..2916d6c 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -1638,6 +1638,11 @@
                 }
             }
 
+            // An unfilled shape is not opaque over bounds or shape
+            if (mColors == null && mColorStateList == null) {
+                return;
+            }
+
             // Colors are opaque, so opaqueOverShape=true,
             mOpaqueOverShape = true;
             // and opaqueOverBounds=true if shape fills bounds
diff --git a/include/android_runtime/AndroidRuntime.h b/include/android_runtime/AndroidRuntime.h
index 51e47e6..f3cfd97 100644
--- a/include/android_runtime/AndroidRuntime.h
+++ b/include/android_runtime/AndroidRuntime.h
@@ -45,6 +45,7 @@
     };
 
     void setArgv0(const char* argv0);
+    void addOption(const char* optionString, void* extra_info = NULL);
 
     /**
      * Register a set of methods in the specified class.
@@ -63,8 +64,6 @@
      */
     static jclass findClass(JNIEnv* env, const char* className);
 
-    int addVmArguments(int argc, const char* const argv[]);
-
     void start(const char *classname, const Vector<String8>& options);
 
     void exit(int code);
@@ -116,7 +115,6 @@
 
 private:
     static int startReg(JNIEnv* env);
-    void addOption(const char* optionString, void* extra_info = NULL);
     bool parseRuntimeOption(const char* property,
                             char* buffer,
                             const char* runtimeArg,
diff --git a/keystore/java/android/security/IKeyChainService.aidl b/keystore/java/android/security/IKeyChainService.aidl
index a93891a..20c94c5 100644
--- a/keystore/java/android/security/IKeyChainService.aidl
+++ b/keystore/java/android/security/IKeyChainService.aidl
@@ -31,6 +31,9 @@
     // APIs used by CertInstaller
     void installCaCertificate(in byte[] caCertificate);
 
+    // APIs used by DevicePolicyManager
+    boolean installKeyPair(in byte[] privateKey, in byte[] userCert, String alias);
+
     // APIs used by Settings
     boolean deleteCaCertificate(String alias);
     boolean reset();
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index dbd273d..0415efa 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -54,10 +54,6 @@
 namespace android {
 namespace uirenderer {
 
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
 static GLenum getFilter(const SkPaint* paint) {
     if (!paint || paint->getFilterLevel() != SkPaint::kNone_FilterLevel) {
         return GL_LINEAR;
@@ -1748,10 +1744,13 @@
         glUniform4f(mCaches.currentProgram->getUniform("roundRectInnerRectLTRB"),
                 innerRect.left, innerRect.top,
                 innerRect.right, innerRect.bottom);
-        glUniform1f(mCaches.currentProgram->getUniform("roundRectRadius"),
-                state->radius);
         glUniformMatrix4fv(mCaches.currentProgram->getUniform("roundRectInvTransform"),
                 1, GL_FALSE, &state->matrix.data[0]);
+
+        // add half pixel to round out integer rect space to cover pixel centers
+        float roundedOutRadius = state->radius + 0.5f;
+        glUniform1f(mCaches.currentProgram->getUniform("roundRectRadius"),
+                roundedOutRadius);
     }
 }
 
@@ -3044,21 +3043,35 @@
 }
 
 void OpenGLRenderer::setupPaintFilter(int clearBits, int setBits) {
+    // TODO: don't bother with boolean, it's redundant with clear/set bits
     mDrawModifiers.mHasDrawFilter = true;
     mDrawModifiers.mPaintFilterClearBits = clearBits & SkPaint::kAllFlags;
     mDrawModifiers.mPaintFilterSetBits = setBits & SkPaint::kAllFlags;
 }
 
 const SkPaint* OpenGLRenderer::filterPaint(const SkPaint* paint) {
+    // TODO: use CompatFlagsDrawFilter here, and combine logic with android/graphics/DrawFilter.cpp
+    // to avoid clobbering 0x02 paint flag
+
+    // Equivalent to the Java Paint's FILTER_BITMAP_FLAG.
+    static const uint32_t sFilterBitmapFlag = 0x02;
+
     if (CC_LIKELY(!mDrawModifiers.mHasDrawFilter || !paint)) {
         return paint;
     }
 
-    uint32_t flags = paint->getFlags();
+    const uint32_t clearBits = mDrawModifiers.mPaintFilterClearBits;
+    const uint32_t setBits = mDrawModifiers.mPaintFilterSetBits;
 
+    const uint32_t flags = (paint->getFlags() & ~clearBits) | setBits;
     mFilteredPaint = *paint;
-    mFilteredPaint.setFlags((flags & ~mDrawModifiers.mPaintFilterClearBits) |
-            mDrawModifiers.mPaintFilterSetBits);
+    mFilteredPaint.setFlags(flags);
+
+    // check if paint filter trying to override bitmap filter
+    if ((clearBits | setBits) & sFilterBitmapFlag) {
+        mFilteredPaint.setFilterLevel(flags & sFilterBitmapFlag
+                ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel);
+    }
 
     return &mFilteredPaint;
 }
diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp
index 9e62f36..1e38f9e 100644
--- a/libs/hwui/TessellationCache.cpp
+++ b/libs/hwui/TessellationCache.cpp
@@ -216,7 +216,7 @@
 
     // tessellate caster outline into a 2d polygon
     Vector<Vertex> casterVertices2d;
-    const float casterRefinementThresholdSquared = 20.0f; // TODO: experiment with this value
+    const float casterRefinementThresholdSquared = 4.0f;
     PathTessellator::approximatePathOutlineVertices(*casterPerimeter,
             casterRefinementThresholdSquared, casterVertices2d);
     if (!ShadowTessellator::isClockwisePath(*casterPerimeter)) {
diff --git a/media/java/android/media/projection/IMediaProjection.aidl b/media/java/android/media/projection/IMediaProjection.aidl
index 3d25aa6..19fc052 100644
--- a/media/java/android/media/projection/IMediaProjection.aidl
+++ b/media/java/android/media/projection/IMediaProjection.aidl
@@ -26,6 +26,6 @@
     boolean canProjectVideo();
     boolean canProjectSecureVideo();
     int applyVirtualDisplayFlags(int flags);
-    void addCallback(IMediaProjectionCallback callback);
-    void removeCallback(IMediaProjectionCallback callback);
+    void registerCallback(IMediaProjectionCallback callback);
+    void unregisterCallback(IMediaProjectionCallback callback);
 }
diff --git a/media/java/android/media/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java
index 3a74d93..e6dadf9 100644
--- a/media/java/android/media/projection/MediaProjection.java
+++ b/media/java/android/media/projection/MediaProjection.java
@@ -40,7 +40,7 @@
  *
  * <p>
  * A screen capture session can be started through {@link
- * MediaProjectionManager#getScreenCaptureIntent}. This grants the ability to
+ * MediaProjectionManager#createScreenCaptureIntent}. This grants the ability to
  * capture screen contents, but not system audio.
  * </p>
  */
@@ -70,9 +70,9 @@
      * @param handler The handler on which the callback should be invoked, or
      * null if the callback should be invoked on the calling thread's looper.
      *
-     * @see #removeCallback
+     * @see #unregisterCallback
      */
-    public void addCallback(Callback callback, Handler handler) {
+    public void registerCallback(Callback callback, Handler handler) {
         if (callback == null) {
             throw new IllegalArgumentException("callback should not be null");
         }
@@ -83,9 +83,9 @@
      *
      * @param callback The callback to unregister.
      *
-     * @see #addCallback
+     * @see #registerCallback
      */
-    public void removeCallback(Callback callback) {
+    public void unregisterCallback(Callback callback) {
         if (callback == null) {
             throw new IllegalArgumentException("callback should not be null");
         }
diff --git a/media/java/android/media/projection/MediaProjectionManager.java b/media/java/android/media/projection/MediaProjectionManager.java
index 50d66c6..a1cfc35 100644
--- a/media/java/android/media/projection/MediaProjectionManager.java
+++ b/media/java/android/media/projection/MediaProjectionManager.java
@@ -75,7 +75,7 @@
      * the user whether to allow screen capture.  The result of this
      * activity should be passed to getMediaProjection.
      */
-    public Intent getScreenCaptureIntent() {
+    public Intent createScreenCaptureIntent() {
         Intent i = new Intent();
         i.setClassName("com.android.systemui",
                 "com.android.systemui.media.MediaProjectionPermissionActivity");
diff --git a/packages/PrintSpooler/res/layout/print_activity_controls.xml b/packages/PrintSpooler/res/layout/print_activity_controls.xml
index c2a0da9..f0b8adf 100644
--- a/packages/PrintSpooler/res/layout/print_activity_controls.xml
+++ b/packages/PrintSpooler/res/layout/print_activity_controls.xml
@@ -55,7 +55,7 @@
                     android:text="@string/label_copies">
                 </TextView>
 
-                <EditText
+                <com.android.printspooler.widget.CustomErrorEditText
                     android:id="@+id/copies_edittext"
                     android:layout_width="fill_parent"
                     android:layout_height="wrap_content"
@@ -63,7 +63,7 @@
                     android:singleLine="true"
                     android:ellipsize="end"
                     android:inputType="numberDecimal">
-                </EditText>
+                </com.android.printspooler.widget.CustomErrorEditText>
 
             </LinearLayout>
 
@@ -197,7 +197,7 @@
                     android:visibility="visible">
                 </TextView>
 
-                <EditText
+                <com.android.printspooler.widget.CustomErrorEditText
                     android:id="@+id/page_range_edittext"
                     android:layout_width="fill_parent"
                     android:layout_height="wrap_content"
@@ -206,7 +206,7 @@
                     android:ellipsize="end"
                     android:visibility="visible"
                     android:inputType="textNoSuggestions">
-                </EditText>
+                </com.android.printspooler.widget.CustomErrorEditText>
 
             </LinearLayout>
 
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java
index 06723c3..8537d6c 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java
@@ -20,7 +20,9 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.os.Debug;
 import android.os.IBinder;
+import android.util.Log;
 
 public class PrintSpoolerProvider implements ServiceConnection {
     private final Context mContext;
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
index 1e7a011..239f006 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
@@ -74,7 +74,7 @@
 
     private final Looper mLooper;
     private final IPrintDocumentAdapter mPrintDocumentAdapter;
-    private final DocumentObserver mDocumentObserver;
+    private final RemoteAdapterDeathObserver mAdapterDeathObserver;
 
     private final UpdateResultCallbacks mUpdateCallbacks;
 
@@ -135,7 +135,7 @@
     private final DeathRecipient mDeathRecipient = new DeathRecipient() {
         @Override
         public void binderDied() {
-            finish();
+            mAdapterDeathObserver.onDied();
         }
     };
 
@@ -144,8 +144,8 @@
     private AsyncCommand mCurrentCommand;
     private AsyncCommand mNextCommand;
 
-    public interface DocumentObserver {
-        public void onDestroy();
+    public interface RemoteAdapterDeathObserver {
+        public void onDied();
     }
 
     public interface UpdateResultCallbacks {
@@ -155,12 +155,12 @@
     }
 
     public RemotePrintDocument(Context context, IPrintDocumentAdapter adapter,
-            MutexFileProvider fileProvider, DocumentObserver destroyListener,
+            MutexFileProvider fileProvider, RemoteAdapterDeathObserver deathObserver,
             UpdateResultCallbacks callbacks) {
         mPrintDocumentAdapter = adapter;
         mLooper = context.getMainLooper();
         mContext = context;
-        mDocumentObserver = destroyListener;
+        mAdapterDeathObserver = deathObserver;
         mDocumentInfo = new RemotePrintDocumentInfo();
         mDocumentInfo.fileProvider = fileProvider;
         mUpdateCallbacks = callbacks;
@@ -180,7 +180,7 @@
         } catch (RemoteException re) {
             Log.e(LOG_TAG, "Error calling start()", re);
             mState = STATE_FAILED;
-            mDocumentObserver.onDestroy();
+            mAdapterDeathObserver.onDied();
         }
     }
 
@@ -269,7 +269,7 @@
         } catch (RemoteException re) {
             Log.e(LOG_TAG, "Error calling finish()", re);
             mState = STATE_FAILED;
-            mDocumentObserver.onDestroy();
+            mAdapterDeathObserver.onDied();
         }
     }
 
@@ -302,7 +302,6 @@
         mState = STATE_DESTROYED;
 
         disconnectFromRemoteDocument();
-        mDocumentObserver.onDestroy();
     }
 
     public boolean isUpdating() {
@@ -1124,7 +1123,7 @@
                 new Handler(document.mLooper).post(new Runnable() {
                     @Override
                     public void run() {
-                        document.mDocumentObserver.onDestroy();
+                        document.mAdapterDeathObserver.onDied();
                     }
                 });
             }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 967efd4..dc2d5b1 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -284,11 +284,14 @@
                 mFileProvider);
         mPrintedDocument = new RemotePrintDocument(PrintActivity.this,
                 IPrintDocumentAdapter.Stub.asInterface(documentAdapter),
-                mFileProvider, new RemotePrintDocument.DocumentObserver() {
+                mFileProvider, new RemotePrintDocument.RemoteAdapterDeathObserver() {
             @Override
-            public void onDestroy() {
+            public void onDied() {
+                if (isFinishing()) {
+                    return;
+                }
                 setState(STATE_PRINT_CANCELED);
-                finish();
+                doFinish();
             }
         }, PrintActivity.this);
         mProgressMessageController = new ProgressMessageController(
@@ -342,17 +345,6 @@
                     spooler.setPrintJobState(mPrintJob.getId(), PrintJobInfo.STATE_CANCELED, null);
                 } break;
             }
-
-            mProgressMessageController.cancel();
-            mPrinterRegistry.setTrackedPrinter(null);
-            mPrintPreviewController.destroy();
-            mSpoolerProvider.destroy();
-
-            if (mPrintedDocument.isUpdating()) {
-                mPrintedDocument.cancel();
-            }
-            mPrintedDocument.finish();
-            mPrintedDocument.destroy();
         }
 
         mPrinterAvailabilityDetector.cancel();
@@ -372,7 +364,12 @@
     @Override
     public boolean onKeyUp(int keyCode, KeyEvent event) {
         if (mState == STATE_INITIALIZING) {
-            finish();
+            doFinish();
+            return true;
+        }
+
+        if (mState == STATE_PRINT_CANCELED ||mState == STATE_PRINT_CONFIRMED
+                || mState == STATE_PRINT_COMPLETED) {
             return true;
         }
 
@@ -430,7 +427,7 @@
             } break;
 
             case STATE_PRINT_CANCELED: {
-                finish();
+                doFinish();
             } break;
         }
     }
@@ -467,7 +464,7 @@
             } break;
 
             case STATE_PRINT_CANCELED: {
-                finish();
+                doFinish();
             } break;
 
             default: {
@@ -600,7 +597,7 @@
             mDestinationSpinner.post(new Runnable() {
                 @Override
                 public void run() {
-                    finish();
+                    doFinish();
                 }
             });
         }
@@ -962,7 +959,7 @@
         if (mPrintedDocument.isUpdating()) {
             mPrintedDocument.cancel();
         }
-        finish();
+        doFinish();
     }
 
     private void confirmPrint() {
@@ -1539,11 +1536,23 @@
                 if (writeToUri != null) {
                     mPrintedDocument.writeContent(getContentResolver(), writeToUri);
                 }
-                finish();
+                doFinish();
             }
         }).shred();
     }
 
+    private void doFinish() {
+        if (mState != STATE_INITIALIZING) {
+            mProgressMessageController.cancel();
+            mPrinterRegistry.setTrackedPrinter(null);
+            mPrintPreviewController.destroy();
+            mSpoolerProvider.destroy();
+            mPrintedDocument.finish();
+            mPrintedDocument.destroy();
+        }
+        finish();
+    }
+
     private final class SpinnerItem<T> {
         final T value;
         final CharSequence label;
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java
index a3d7f01..7f48217 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java
@@ -26,6 +26,7 @@
 import android.print.PrinterId;
 import android.print.PrinterInfo;
 import com.android.internal.os.SomeArgs;
+import com.android.printspooler.model.PrintSpoolerService;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -68,23 +69,40 @@
     }
 
     public void addHistoricalPrinter(PrinterInfo printer) {
-        getPrinterProvider().addHistoricalPrinter(printer);
+        FusedPrintersProvider provider = getPrinterProvider();
+        if (provider != null) {
+            getPrinterProvider().addHistoricalPrinter(printer);
+        }
     }
 
     public void forgetFavoritePrinter(PrinterId printerId) {
-        getPrinterProvider().forgetFavoritePrinter(printerId);
+        FusedPrintersProvider provider = getPrinterProvider();
+        if (provider != null) {
+            provider.forgetFavoritePrinter(printerId);
+        }
     }
 
     public boolean isFavoritePrinter(PrinterId printerId) {
-        return getPrinterProvider().isFavoritePrinter(printerId);
+        FusedPrintersProvider provider = getPrinterProvider();
+        if (provider != null) {
+            return provider.isFavoritePrinter(printerId);
+        }
+        return false;
     }
 
     public void setTrackedPrinter(PrinterId printerId) {
-        getPrinterProvider().setTrackedPrinter(printerId);
+        FusedPrintersProvider provider = getPrinterProvider();
+        if (provider != null) {
+            provider.setTrackedPrinter(printerId);
+        }
     }
 
     public boolean areHistoricalPrintersLoaded() {
-        return getPrinterProvider().areHistoricalPrintersLoaded();
+        FusedPrintersProvider provider = getPrinterProvider();
+        if (provider != null) {
+            return getPrinterProvider().areHistoricalPrintersLoaded();
+        }
+        return false;
     }
 
     private FusedPrintersProvider getPrinterProvider() {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/CustomErrorEditText.java b/packages/PrintSpooler/src/com/android/printspooler/widget/CustomErrorEditText.java
new file mode 100644
index 0000000..b2aa008
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/widget/CustomErrorEditText.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.printspooler.widget;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.EditText;
+
+/**
+ * EditText that shows an error without a popup.
+ */
+public final class CustomErrorEditText extends EditText {
+    private CharSequence mError;
+
+    public CustomErrorEditText(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public CharSequence getError() {
+        return mError;
+    }
+
+    @Override
+    public void setError(CharSequence error, Drawable icon) {
+        setCompoundDrawables(null, null, icon, null);
+        mError = error;
+    }
+}
\ No newline at end of file
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 4ef2189..30ccd2c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -789,8 +789,15 @@
                             Slog.v(TAG, "putting to additional user "
                                     + mManagedProfiles.get(i).id);
                         }
-                        insertForUser(Settings.Secure.CONTENT_URI, values,
-                                mManagedProfiles.get(i).id);
+                        try {
+                            insertForUser(Settings.Secure.CONTENT_URI, values,
+                                    mManagedProfiles.get(i).id);
+                        } catch (SecurityException e) {
+                            // Temporary fix, see b/17450158
+                            Slog.w(TAG, "Cannot clone request '" + request + "' with value '"
+                                    + newValue + "' to managed profile (id "
+                                    + mManagedProfiles.get(i).id + ")", e);
+                        }
                     }
                 } finally {
                     Binder.restoreCallingIdentity(token);
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 5a1c318..f899572 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -191,11 +191,21 @@
     <!-- Doze: maximum brightness to use when pulsing -->
     <integer name="doze_pulse_brightness">40</integer>
 
-    <!-- Doze: number of pulses when doing multiple pulses in quick succession -->
-    <integer name="doze_multipulse_count">3</integer>
+    <!-- Doze: period of time between pulses (start of pulse) when following the notification light
+         Format: <under_ms>:<period_ms>,...,<default_ms> -->
+    <string name="doze_pulse_period_function">60000:10000,300000:30000,1800000:60000,0</string>
 
-    <!-- Doze: interval between pulses when following the notification light -->
-    <integer name="doze_notification_pulse_interval">30000</integer>
+    <!-- Doze: pulse parameter - how long does it take to fade in? -->
+    <integer name="doze_pulse_duration_in">1000</integer>
+
+    <!-- Doze: pulse parameter - once faded in, how long does it stay visible? -->
+    <integer name="doze_pulse_duration_visible">3000</integer>
+
+    <!-- Doze: pulse parameter - how long does it take to fade out? -->
+    <integer name="doze_pulse_duration_out">1000</integer>
+
+    <!-- Doze: pulse parameter - how long to wait before pulsing (if not starting immediately) -->
+    <integer name="doze_pulse_delay">1000</integer>
 
     <!-- Doze: alpha to apply to small icons when dozing -->
     <integer name="doze_small_icon_alpha">222</integer><!-- 87% of 0xff -->
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index d17e263..1183582 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -42,6 +42,7 @@
 
 import com.android.systemui.R;
 import com.android.systemui.SystemUIApplication;
+import com.android.systemui.statusbar.phone.DozeParameters;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -54,11 +55,11 @@
     private static final String ACTION_BASE = "com.android.systemui.doze";
     private static final String PULSE_ACTION = ACTION_BASE + ".pulse";
     private static final String NOTIFICATION_PULSE_ACTION = ACTION_BASE + ".notification_pulse";
-    private static final String EXTRA_PULSES = "pulses";
 
     private final String mTag = String.format(TAG + ".%08x", hashCode());
     private final Context mContext = this;
     private final Handler mHandler = new Handler();
+    private final DozeParameters mDozeParameters = new DozeParameters(mContext);
 
     private Host mHost;
     private SensorManager mSensors;
@@ -74,9 +75,8 @@
     private int mDisplayStateWhenOn;
     private boolean mNotificationLightOn;
     private PendingIntent mNotificationPulseIntent;
-    private int mMultipulseCount;
-    private int mNotificationPulseInterval;
     private boolean mPowerSaveActive;
+    private long mNotificationPulseTime;
 
     public DozeService() {
         if (DEBUG) Log.d(mTag, "new DozeService()");
@@ -94,9 +94,9 @@
         pw.print("  mMaxBrightness: "); pw.println(mMaxBrightness);
         pw.print("  mDisplayStateSupported: "); pw.println(mDisplayStateSupported);
         pw.print("  mNotificationLightOn: "); pw.println(mNotificationLightOn);
-        pw.print("  mMultipulseCount: "); pw.println(mMultipulseCount);
-        pw.print("  mNotificationPulseInterval: "); pw.println(mNotificationPulseInterval);
         pw.print("  mPowerSaveActive: "); pw.println(mPowerSaveActive);
+        pw.print("  mNotificationPulseTime: "); pw.println(mNotificationPulseTime);
+        mDozeParameters.dump(pw);
     }
 
     @Override
@@ -127,11 +127,7 @@
                 BRIGHTNESS_OFF, BRIGHTNESS_ON);
         mNotificationPulseIntent = PendingIntent.getBroadcast(mContext, 0,
                 new Intent(NOTIFICATION_PULSE_ACTION).setPackage(getPackageName()),
-                PendingIntent.FLAG_CANCEL_CURRENT);
-        mMultipulseCount = SystemProperties.getInt("doze.multipulses",
-                res.getInteger(R.integer.doze_multipulse_count));
-        mNotificationPulseInterval = SystemProperties.getInt("doze.notification.pulse",
-                res.getInteger(R.integer.doze_notification_pulse_interval));
+                PendingIntent.FLAG_UPDATE_CURRENT);
         mDisplayStateWhenOn = mDisplayStateSupported ? Display.STATE_DOZE : Display.STATE_ON;
         setDozeScreenState(mDisplayStateWhenOn);
     }
@@ -159,6 +155,7 @@
 
     public void stayAwake(long millis) {
         if (mDreaming && millis > 0) {
+            if (DEBUG) Log.d(mTag, "stayAwake millis=" + millis);
             mWakeLock.acquire(millis);
             setDozeScreenState(mDisplayStateWhenOn);
             setDozeScreenBrightness(mMaxBrightness);
@@ -218,21 +215,9 @@
         }
     }
 
-    private void requestMultipulse() {
-        requestPulse(mMultipulseCount);
-    }
-
-    private void requestPulse() {
-        requestPulse(1);
-    }
-
-    private void requestPulse(int pulses) {
-        requestPulse(pulses, true /*delayed*/);
-    }
-
-    private void requestPulse(int pulses, boolean delayed) {
+    private void requestPulse(boolean delayed) {
         if (mHost != null) {
-            mHost.requestPulse(pulses, delayed, this);
+            mHost.requestPulse(delayed, this);
         }
     }
 
@@ -281,9 +266,14 @@
     private void rescheduleNotificationPulse() {
         mAlarmManager.cancel(mNotificationPulseIntent);
         if (mNotificationLightOn) {
-            final long time = System.currentTimeMillis() + mNotificationPulseInterval;
-            if (DEBUG) Log.d(TAG, "Scheduling pulse for " + new Date(time));
-            mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, mNotificationPulseIntent);
+            final long now = System.currentTimeMillis();
+            final long age = now - mNotificationPulseTime;
+            final long period = mDozeParameters.getPulsePeriod(age);
+            final long time = now + period;
+            if (period > 0) {
+                if (DEBUG) Log.d(TAG, "Scheduling pulse in " + period + " for " + new Date(time));
+                mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, mNotificationPulseIntent);
+            }
         }
     }
 
@@ -314,11 +304,11 @@
         public void onReceive(Context context, Intent intent) {
             if (PULSE_ACTION.equals(intent.getAction())) {
                 if (DEBUG) Log.d(mTag, "Received pulse intent");
-                requestPulse(intent.getIntExtra(EXTRA_PULSES, mMultipulseCount));
+                requestPulse(false /*delayed*/);
             }
             if (NOTIFICATION_PULSE_ACTION.equals(intent.getAction())) {
                 if (DEBUG) Log.d(mTag, "Received notification pulse intent");
-                requestPulse();
+                requestPulse(true /*delayed*/);
                 rescheduleNotificationPulse();
             }
         }
@@ -334,7 +324,8 @@
         @Override
         public void onBuzzBeepBlinked() {
             if (DEBUG) Log.d(mTag, "onBuzzBeepBlinked");
-            requestMultipulse();
+            mNotificationPulseTime = System.currentTimeMillis();
+            requestPulse(true /*delayed*/);
         }
 
         @Override
@@ -342,6 +333,10 @@
             if (DEBUG) Log.d(mTag, "onNotificationLight on=" + on);
             if (mNotificationLightOn == on) return;
             mNotificationLightOn = on;
+            if (mNotificationLightOn) {
+                mNotificationPulseTime = System.currentTimeMillis();
+                requestPulse(true /*delayed*/);
+            }
             rescheduleNotificationPulse();
         }
 
@@ -358,7 +353,7 @@
         void addCallback(Callback callback);
         void removeCallback(Callback callback);
         void requestDoze(DozeService dozeService);
-        void requestPulse(int pulses, boolean delayed, DozeService dozeService);
+        void requestPulse(boolean delayed, DozeService dozeService);
         void dozingStopped(DozeService dozeService);
         boolean isPowerSaveActive();
 
@@ -409,7 +404,7 @@
                             .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION).build());
                 }
             }
-            requestPulse(1, false /*delayed*/);
+            requestPulse(false /*delayed*/);
             setListening(true);  // reregister, this sensor only fires once
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index f7e0c83..ce3739c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -92,6 +92,7 @@
 import com.android.systemui.SystemUI;
 import com.android.systemui.statusbar.NotificationData.Entry;
 import com.android.systemui.statusbar.phone.KeyguardTouchDelegate;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
 import com.android.systemui.statusbar.policy.PreviewInflater;
@@ -288,6 +289,10 @@
 
                         // close the shade if it was open
                         if (handled) {
+                            if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                                Log.i(TAG, "Collapsing panel from mOnClickHandler after keyguard"
+                                        + "dismiss");
+                            }
                             animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
                             visibilityChanged(false);
                         }
@@ -334,6 +339,9 @@
                 Settings.Secure.putInt(mContext.getContentResolver(),
                         Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
                 if (BANNER_ACTION_SETUP.equals(action)) {
+                    if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                        Log.i(TAG, "Animating collapse because of BANNER_ACTION_SETUP");
+                    }
                     animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
                     mContext.startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_REDACTION)
                             .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
@@ -759,6 +767,10 @@
                         }
                     }
                 });
+                if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                    Log.i(TAG, "Collapsing panel from startNotificationGutsIntent after keyguard"
+                            + "dismiss");
+                }
                 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
                 return true;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
new file mode 100644
index 0000000..e14ef12
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.content.Context;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.MathUtils;
+
+import com.android.systemui.R;
+
+import java.io.PrintWriter;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DozeParameters {
+    private static final String TAG = "DozeParameters";
+
+    private static final int MAX_DURATION = 10 * 1000;
+
+    private final Context mContext;
+
+    private StepFunction mPulsePeriodFunction;
+
+    public DozeParameters(Context context) {
+        mContext = context;
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println("  DozeParameters:");
+        pw.print("    getPulseDuration(): "); pw.println(getPulseDuration());
+        pw.print("    getPulseInDuration(): "); pw.println(getPulseInDuration());
+        pw.print("    getPulseInVisibleDuration(): "); pw.println(getPulseVisibleDuration());
+        pw.print("    getPulseOutDuration(): "); pw.println(getPulseOutDuration());
+        pw.print("    getPulseStartDelay(): "); pw.println(getPulseStartDelay());
+        pw.print("    getPulsePeriodFunction(): "); pw.println(getPulsePeriodFunction());
+    }
+
+    public int getPulseDuration() {
+        return getPulseInDuration() + getPulseVisibleDuration() + getPulseOutDuration();
+    }
+
+    public int getPulseInDuration() {
+        return getInt("doze.pulse.duration.in", R.integer.doze_pulse_duration_in);
+    }
+
+    public int getPulseVisibleDuration() {
+        return getInt("doze.pulse.duration.visible", R.integer.doze_pulse_duration_visible);
+    }
+
+    public int getPulseOutDuration() {
+        return getInt("doze.pulse.duration.out", R.integer.doze_pulse_duration_out);
+    }
+
+    public int getPulseStartDelay() {
+        return getInt("doze.pulse.delay", R.integer.doze_pulse_delay);
+    }
+
+    public long getPulsePeriod(long age) {
+        final String spec = getPulsePeriodFunction();
+        if (mPulsePeriodFunction == null || !mPulsePeriodFunction.mSpec.equals(spec)) {
+            mPulsePeriodFunction = StepFunction.parse(spec);
+        }
+        return mPulsePeriodFunction != null ? mPulsePeriodFunction.evaluate(age) : 0;
+    }
+
+    private String getPulsePeriodFunction() {
+        return getString("doze.pulse.period.function", R.string.doze_pulse_period_function);
+    }
+
+    private int getInt(String propName, int resId) {
+        int value = SystemProperties.getInt(propName, mContext.getResources().getInteger(resId));
+        return MathUtils.constrain(value, 0, MAX_DURATION);
+    }
+
+    private String getString(String propName, int resId) {
+        return SystemProperties.get(propName, mContext.getString(resId));
+    }
+
+    private static class StepFunction {
+        private static final Pattern PATTERN = Pattern.compile("(\\d+?)(:(\\d+?))?", 0);
+
+        private String mSpec;
+        private long[] mSteps;
+        private long[] mValues;
+        private long mDefault;
+
+        public static StepFunction parse(String spec) {
+            if (TextUtils.isEmpty(spec)) return null;
+            try {
+                final StepFunction rt = new StepFunction();
+                rt.mSpec = spec;
+                final String[] tokens = spec.split(",");
+                rt.mSteps = new long[tokens.length - 1];
+                rt.mValues = new long[tokens.length - 1];
+                for (int i = 0; i < tokens.length - 1; i++) {
+                    final Matcher m = PATTERN.matcher(tokens[i]);
+                    if (!m.matches()) throw new IllegalArgumentException("Bad token: " + tokens[i]);
+                    rt.mSteps[i] = Long.parseLong(m.group(1));
+                    rt.mValues[i] = Long.parseLong(m.group(3));
+                }
+                rt.mDefault = Long.parseLong(tokens[tokens.length - 1]);
+                return rt;
+            } catch (RuntimeException e) {
+                Log.w(TAG, "Error parsing spec: " + spec, e);
+                return null;
+            }
+        }
+
+        public long evaluate(long x) {
+            for (int i = 0; i < mSteps.length; i++) {
+                if (x < mSteps[i]) return mValues[i];
+            }
+            return mDefault;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index e84ca52..23f027b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -128,6 +128,9 @@
         public boolean performAccessibilityAction(View host, int action, Bundle args) {
             if (action == ACTION_CLICK) {
                 if (host == mLockIcon) {
+                    if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                        Log.i(TAG, "Collapsing panel from lock icon accessibility click");
+                    }
                     mPhoneStatusBar.animateCollapsePanels(
                             CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
                     return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index f74d2f4..ccafbd1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -140,6 +140,9 @@
         mPanelHolder.setSelectedPanel(mTouchingPanel);
         for (PanelView pv : mPanels) {
             if (pv != panel) {
+                if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                    Log.i(TAG, "Collapsing because opening another panel");
+                }
                 pv.collapse(false /* delayed */);
             }
         }
@@ -191,9 +194,15 @@
         boolean waiting = false;
         for (PanelView pv : mPanels) {
             if (animate && !pv.isFullyCollapsed()) {
+                if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                    Log.i(TAG, "Animating collapse, delayed");
+                }
                 pv.collapse(true /* delayed */);
                 waiting = true;
             } else {
+                if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                    Log.i(TAG, "Collapsing without animation");
+                }
                 pv.resetViews();
                 pv.setExpandedFraction(0); // just in case
                 pv.setVisibility(View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 006e480..c3b263d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -134,6 +134,9 @@
     }
 
     private void runPeekAnimation() {
+        if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+            Log.i(TAG, "Starting peek animation");
+        }
         mPeekHeight = getPeekHeight();
         if (DEBUG) logf("peek to height=%.1f", mPeekHeight);
         if (mHeightAnimator != null) {
@@ -154,9 +157,15 @@
             public void onAnimationEnd(Animator animation) {
                 mPeekAnimator = null;
                 if (mCollapseAfterPeek && !mCancelled) {
+                    if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                        Log.i(TAG, "Peek animation finished, posting collapse");
+                    }
                     postOnAnimation(new Runnable() {
                         @Override
                         public void run() {
+                            if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                                Log.i(TAG, "Peek animation finished, collapsing");
+                            }
                             collapse(false /* delayed */);
                         }
                     });
@@ -330,6 +339,9 @@
                     }
                     boolean expand = flingExpands(vel, vectorVel);
                     onTrackingStopped(expand);
+                    if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                        Log.i(TAG, "Flinging: expand=" + expand);
+                    }
                     fling(vel, expand);
                     mUpdateFlingOnLayout = expand && mPanelClosedOnDown && !mHasLayoutedSinceDown;
                     if (mUpdateFlingOnLayout) {
@@ -510,6 +522,9 @@
             notifyExpandingFinished();
             return;
         }
+        if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+            Log.i(TAG, "Executing fling: expand=" + expand + " vel=" + vel);
+        }
         mOverExpandedBeforeFling = getOverExpansionAmount() > 0f;
         ValueAnimator animator = createHeightAnimator(target);
         if (expand) {
@@ -691,8 +706,14 @@
             mClosing = true;
             notifyExpandingStarted();
             if (delayed) {
+                if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                    Log.i(TAG, "Posting collapse runnable, will be run in 120ms");
+                }
                 postDelayed(mFlingCollapseRunnable, 120);
             } else {
+                if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                    Log.i(TAG, "Animating collapsing now");
+                }
                 fling(0, false /* expand */);
             }
         }
@@ -701,6 +722,9 @@
     private final Runnable mFlingCollapseRunnable = new Runnable() {
         @Override
         public void run() {
+            if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                Log.i(TAG, "Executing collapse runnable, animating collapsing now");
+            }
             fling(0, false /* expand */);
         }
     };
@@ -729,6 +753,11 @@
     }
 
     public void instantExpand() {
+        if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+            Log.i(TAG, "Before instant expanding"
+                    + " mTracking=" + mTracking
+                    + " mExpanding=" + mExpanding);
+        }
         mInstantExpanding = true;
         mUpdateFlingOnLayout = false;
         abortAnimations();
@@ -749,6 +778,11 @@
                     public void onGlobalLayout() {
                         if (mStatusBar.getStatusBarWindow().getHeight()
                                 != mStatusBar.getStatusBarHeight()) {
+                            if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                                Log.i(TAG, "Now instant expanding after layout"
+                                        + " mTracking=" + mTracking
+                                        + " mExpanding=" + mExpanding);
+                            }
                             getViewTreeObserver().removeOnGlobalLayoutListener(this);
                             setExpandedFraction(1f);
                             mInstantExpanding = false;
@@ -895,6 +929,9 @@
     private final Runnable mPostCollapseRunnable = new Runnable() {
         @Override
         public void run() {
+            if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                Log.i(TAG, "Collapsing after middle clicked");
+            }
             collapse(false /* delayed */);
         }
     };
@@ -907,6 +944,9 @@
                 mStatusBar.goToKeyguard();
                 return true;
             case StatusBarState.SHADE:
+                if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                    Log.i(TAG, "Middle clicked in shade state, posting collapsing runnable");
+                }
 
                 // This gets called in the middle of the touch handling, where the state is still
                 // that we are tracking the panel. Collapse the panel after this is done.
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 5d4c831..fd60ac4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -177,6 +177,7 @@
     public static final boolean DEBUG_GESTURES = false;
     public static final boolean DEBUG_MEDIA = false;
     public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
+    public static final boolean DEBUG_EMPTY_KEYGUARD = true;
 
     public static final boolean DEBUG_WINDOW_STATE = false;
 
@@ -2238,6 +2239,11 @@
             mStatusBarWindowManager.setStatusBarFocusable(false);
 
             mStatusBarWindow.cancelExpandHelper();
+            if (DEBUG_EMPTY_KEYGUARD) {
+                Log.i(TAG, "Collapsing panel from animateCollapsePanels:"
+                        + " force=" + force
+                        + " mState=" + mState);
+            }
             mStatusBarView.collapseAllPanels(true);
         }
     }
@@ -2325,6 +2331,9 @@
     }
 
     public void animateCollapseQuickSettings() {
+        if (DEBUG_EMPTY_KEYGUARD) {
+            Log.i(TAG, "Collapsing panel from animateCollapseQuickSettings");
+        }
         mStatusBarView.collapseAllPanels(true);
     }
 
@@ -2337,6 +2346,9 @@
         }
 
         // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
+        if (DEBUG_EMPTY_KEYGUARD) {
+            Log.i(TAG, "Collapsing panel from makeExpandedInvisible");
+        }
         mStatusBarView.collapseAllPanels(/*animate=*/ false);
 
         // reset things to their proper state
@@ -2430,6 +2442,9 @@
             mStatusBarWindowState = state;
             if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
             if (!showing) {
+                if (DEBUG_EMPTY_KEYGUARD) {
+                    Log.i(TAG, "Collapsing panel from setWindowState");
+                }
                 mStatusBarView.collapseAllPanels(false);
             }
         }
@@ -2987,6 +3002,10 @@
                     }
                 });
                 if (dismissShade) {
+                    if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                        Log.i(TAG, "Collapsing panel startActivityDismissKeyguard after keyguard"
+                                + "dismiss");
+                    }
                     animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
                 }
                 return true;
@@ -3654,6 +3673,9 @@
     public boolean onSpacePressed() {
         if (mScreenOn != null && mScreenOn
                 && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
+            if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+                Log.i(TAG, "Collapsing panel from onSpacePressed");
+            }
             animateCollapsePanels(0 /* flags */, true /* force */);
             return true;
         }
@@ -3949,7 +3971,8 @@
     }
 
     public void wakeUpIfDozing(long time) {
-        if (mDozeServiceHost != null && mDozeServiceHost.isDozing()) {
+        if (mDozeServiceHost != null && mDozeServiceHost.isDozing()
+                && mScrimController.isPulsing()) {
             PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
             pm.wakeUp(time);
         }
@@ -4045,10 +4068,10 @@
         }
 
         @Override
-        public void requestPulse(int pulses, boolean delayed, DozeService dozeService) {
+        public void requestPulse(boolean delayed, DozeService dozeService) {
             if (dozeService == null) return;
             dozeService.stayAwake(PROCESSING_TIME);
-            mHandler.obtainMessage(H.REQUEST_PULSE, pulses, delayed ? 1 : 0, dozeService)
+            mHandler.obtainMessage(H.REQUEST_PULSE, delayed ? 1 : 0, 0, dozeService)
                     .sendToTarget();
         }
 
@@ -4073,9 +4096,9 @@
             mCurrentDozeService.startDozing();
         }
 
-        private void handleRequestPulse(int pulses, boolean delayed, DozeService dozeService) {
+        private void handleRequestPulse(boolean delayed, DozeService dozeService) {
             if (!dozeService.equals(mCurrentDozeService)) return;
-            final long stayAwake = mScrimController.pulse(pulses, delayed);
+            final long stayAwake = mScrimController.pulse(delayed);
             mCurrentDozeService.stayAwake(stayAwake);
         }
 
@@ -4099,7 +4122,7 @@
                 if (msg.what == REQUEST_DOZE) {
                     handleRequestDoze((DozeService) msg.obj);
                 } else if (msg.what == REQUEST_PULSE) {
-                    handleRequestPulse(msg.arg1, msg.arg2 != 0, (DozeService) msg.obj);
+                    handleRequestPulse(msg.arg1 != 0, (DozeService) msg.obj);
                 } else if (msg.what == DOZING_STOPPED) {
                     handleDozingStopped((DozeService) msg.obj);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index be48df7..57e5755 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
+import android.content.Context;
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
 import android.util.Log;
@@ -36,7 +37,7 @@
  */
 public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
     private static final String TAG = "ScrimController";
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     public static final long ANIMATION_DURATION = 220;
 
@@ -46,17 +47,10 @@
     private static final float SCRIM_IN_FRONT_ALPHA = 0.75f;
     private static final int TAG_KEY_ANIM = R.id.scrim;
 
-    private static final long PULSE_IN_ANIMATION_DURATION = 1000;
-    private static final long PULSE_VISIBLE_DURATION = 3000;
-    private static final long PULSE_OUT_ANIMATION_DURATION = 1000;
-    private static final long PULSE_INVISIBLE_DURATION = 1000;
-    private static final long PULSE_DURATION = PULSE_IN_ANIMATION_DURATION
-            + PULSE_VISIBLE_DURATION + PULSE_OUT_ANIMATION_DURATION + PULSE_INVISIBLE_DURATION;
-    private static final long PRE_PULSE_DELAY = 1000;
-
     private final View mScrimBehind;
     private final View mScrimInFront;
     private final UnlockMethodCache mUnlockMethodCache;
+    private final DozeParameters mDozeParameters;
 
     private boolean mKeyguardShowing;
     private float mFraction;
@@ -72,16 +66,18 @@
     private Runnable mOnAnimationFinished;
     private boolean mAnimationStarted;
     private boolean mDozing;
-    private int mPulsesRemaining;
+    private long mPulseEndTime;
     private final Interpolator mInterpolator = new DecelerateInterpolator();
     private final Interpolator mLinearOutSlowInInterpolator;
 
     public ScrimController(View scrimBehind, View scrimInFront) {
         mScrimBehind = scrimBehind;
         mScrimInFront = scrimInFront;
-        mUnlockMethodCache = UnlockMethodCache.getInstance(scrimBehind.getContext());
-        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(scrimBehind.getContext(),
+        final Context context = scrimBehind.getContext();
+        mUnlockMethodCache = UnlockMethodCache.getInstance(context);
+        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                 android.R.interpolator.linear_out_slow_in);
+        mDozeParameters = new DozeParameters(context);
     }
 
     public void setKeyguardShowing(boolean showing) {
@@ -137,19 +133,28 @@
         scheduleUpdate();
     }
 
-    /** When dozing, fade screen contents in and out a few times using the front scrim. */
-    public long pulse(int pulses, boolean delayed) {
+    /** When dozing, fade screen contents in and out using the front scrim. */
+    public long pulse(boolean delayed) {
         if (!mDozing) return 0;
-        mPulsesRemaining = Math.max(pulses, mPulsesRemaining);
-        final long delay = delayed ? PRE_PULSE_DELAY : 0;
+        final long now = System.currentTimeMillis();
+        if (DEBUG) Log.d(TAG, "pulse delayed=" + delayed + " mPulseEndTime=" + mPulseEndTime
+                + " now=" + now);
+        if (mPulseEndTime != 0 && mPulseEndTime > now) return mPulseEndTime - now;
+        final long delay = delayed ? mDozeParameters.getPulseStartDelay() : 0;
         mScrimInFront.postDelayed(mPulseIn, delay);
-        return delay + mPulsesRemaining * PULSE_DURATION;
+        mPulseEndTime = now + delay + mDozeParameters.getPulseDuration();
+        return mPulseEndTime - now;
+    }
+
+    public boolean isPulsing() {
+        return mDozing && mPulseEndTime != 0;
     }
 
     private void cancelPulsing() {
-        mPulsesRemaining = 0;
+        if (DEBUG) Log.d(TAG, "Cancel pulsing");
         mScrimInFront.removeCallbacks(mPulseIn);
         mScrimInFront.removeCallbacks(mPulseOut);
+        mPulseEndTime = 0;
     }
 
     private void scheduleUpdate() {
@@ -302,11 +307,9 @@
     private final Runnable mPulseIn = new Runnable() {
         @Override
         public void run() {
-            if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing
-                    + " mPulsesRemaining=" + mPulsesRemaining);
-            if (!mDozing || mPulsesRemaining == 0) return;
-            mPulsesRemaining--;
-            mDurationOverride = PULSE_IN_ANIMATION_DURATION;
+            if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing);
+            if (!mDozing) return;
+            mDurationOverride = mDozeParameters.getPulseInDuration();
             mAnimationDelay = 0;
             mAnimateChange = true;
             mOnAnimationFinished = mPulseInFinished;
@@ -319,7 +322,7 @@
         public void run() {
             if (DEBUG) Log.d(TAG, "Pulse in finished, mDozing=" + mDozing);
             if (!mDozing) return;
-            mScrimInFront.postDelayed(mPulseOut, PULSE_VISIBLE_DURATION);
+            mScrimInFront.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
         }
     };
 
@@ -328,7 +331,7 @@
         public void run() {
             if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
             if (!mDozing) return;
-            mDurationOverride = PULSE_OUT_ANIMATION_DURATION;
+            mDurationOverride = mDozeParameters.getPulseOutDuration();
             mAnimationDelay = 0;
             mAnimateChange = true;
             mOnAnimationFinished = mPulseOutFinished;
@@ -339,10 +342,8 @@
     private final Runnable mPulseOutFinished = new Runnable() {
         @Override
         public void run() {
-            if (DEBUG) Log.d(TAG, "Pulse out finished, mPulsesRemaining=" + mPulsesRemaining);
-            if (mPulsesRemaining > 0) {
-                mScrimInFront.postDelayed(mPulseIn, PULSE_INVISIBLE_DURATION);
-            }
+            if (DEBUG) Log.d(TAG, "Pulse out finished");
+            mPulseEndTime = 0;
         }
     };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index a5217ab..42cfd39 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -100,6 +100,11 @@
                 if (!down) {
                     return mService.onSpacePressed();
                 }
+            case KeyEvent.KEYCODE_VOLUME_DOWN:
+            case KeyEvent.KEYCODE_VOLUME_UP:
+                if (down) {
+                    mService.wakeUpIfDozing(event.getEventTime());
+                }
         }
         if (mService.interceptMediaKey(event)) {
             return true;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index cce30c7..f802e1e 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -124,6 +124,7 @@
     private static final int CUSTOM_TITLE_COMPATIBLE_FEATURES = DEFAULT_FEATURES |
             (1 << FEATURE_CUSTOM_TITLE) |
             (1 << FEATURE_CONTENT_TRANSITIONS) |
+            (1 << FEATURE_ACTIVITY_TRANSITIONS) |
             (1 << FEATURE_ACTION_MODE_OVERLAY);
 
     private static final Transition USE_DEFAULT_TRANSITION = new TransitionSet();
@@ -3207,6 +3208,9 @@
         if (a.getBoolean(R.styleable.Window_windowContentTransitions, false)) {
             requestFeature(FEATURE_CONTENT_TRANSITIONS);
         }
+        if (a.getBoolean(R.styleable.Window_windowActivityTransitions, false)) {
+            requestFeature(FEATURE_ACTIVITY_TRANSITIONS);
+        }
 
         final WindowManager windowService = (WindowManager) getContext().getSystemService(
                 Context.WINDOW_SERVICE);
@@ -3516,7 +3520,7 @@
 
             // Only inflate or create a new TransitionManager if the caller hasn't
             // already set a custom one.
-            if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
+            if (hasFeature(FEATURE_ACTIVITY_TRANSITIONS)) {
                 if (mTransitionManager == null) {
                     final int transitionRes = getWindowStyle().getResourceId(
                             R.styleable.Window_windowContentTransitionManager,
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 16bb00b..5874f63 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -439,6 +439,7 @@
 
     WindowState mTopFullscreenOpaqueWindowState;
     HashSet<IApplicationToken> mAppsToBeHidden = new HashSet<IApplicationToken>();
+    HashSet<IApplicationToken> mAppsThatDismissKeyguard = new HashSet<IApplicationToken>();
     boolean mTopIsFullscreen;
     boolean mForceStatusBar;
     boolean mForceStatusBarFromKeyguard;
@@ -1758,6 +1759,11 @@
         }
     }
 
+    @Override
+    public WindowState getWinShowWhenLockedLw() {
+        return mWinShowWhenLocked;
+    }
+
     /** {@inheritDoc} */
     @Override
     public View addStartingWindow(IBinder appToken, String packageName, int theme,
@@ -1826,8 +1832,6 @@
             params.packageName = packageName;
             params.windowAnimations = win.getWindowStyle().getResourceId(
                     com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
-            params.privateFlags |=
-                    WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED;
             params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
 
             if (!compatInfo.supportsScreen()) {
@@ -3753,6 +3757,7 @@
     public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) {
         mTopFullscreenOpaqueWindowState = null;
         mAppsToBeHidden.clear();
+        mAppsThatDismissKeyguard.clear();
         mForceStatusBar = false;
         mForceStatusBarFromKeyguard = false;
         mForcingShowNavBar = false;
@@ -3793,7 +3798,7 @@
                 mShowingLockscreen = true;
             }
             boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
-                    && attrs.type <= LAST_APPLICATION_WINDOW;
+                    && attrs.type < FIRST_SYSTEM_WINDOW;
             if (attrs.type == TYPE_DREAM) {
                 // If the lockscreen was showing when the dream started then wait
                 // for the dream to draw before hiding the lockscreen.
@@ -3808,38 +3813,44 @@
             final boolean dismissKeyguard = (fl & FLAG_DISMISS_KEYGUARD) != 0;
             final boolean secureKeyguard = isKeyguardSecure();
             if (appWindow) {
-                if (showWhenLocked || (dismissKeyguard && !secureKeyguard)) {
+                final IApplicationToken appToken = win.getAppToken();
+                if (showWhenLocked) {
                     // Remove any previous windows with the same appToken.
-                    mAppsToBeHidden.remove(win.getAppToken());
-                    if (mAppsToBeHidden.isEmpty() && showWhenLocked &&
-                            isKeyguardSecureIncludingHidden()) {
+                    mAppsToBeHidden.remove(appToken);
+                    mAppsThatDismissKeyguard.remove(appToken);
+                    if (mAppsToBeHidden.isEmpty() && isKeyguardSecureIncludingHidden()) {
                         mWinShowWhenLocked = win;
                         mHideLockScreen = true;
                         mForceStatusBarFromKeyguard = false;
                     }
+                } else if (dismissKeyguard) {
+                    if (secureKeyguard) {
+                        mAppsToBeHidden.add(appToken);
+                    } else {
+                        mAppsToBeHidden.remove(appToken);
+                    }
+                    mAppsThatDismissKeyguard.add(appToken);
                 } else {
-                    mAppsToBeHidden.add(win.getAppToken());
+                    mAppsToBeHidden.add(appToken);
                 }
                 if (attrs.x == 0 && attrs.y == 0
                         && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
                         && attrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
                     if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
                     mTopFullscreenOpaqueWindowState = win;
-                    if (mAppsToBeHidden.isEmpty()) {
-                        if (showWhenLocked) {
-                            if (DEBUG_LAYOUT) Slog.v(TAG,
-                                    "Setting mHideLockScreen to true by win " + win);
-                            mHideLockScreen = true;
-                            mForceStatusBarFromKeyguard = false;
-                        }
-                        if (dismissKeyguard && mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
-                            if (DEBUG_LAYOUT) Slog.v(TAG,
-                                    "Setting mDismissKeyguard true by win " + win);
-                            mDismissKeyguard = mWinDismissingKeyguard == win ?
-                                    DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
-                            mWinDismissingKeyguard = win;
-                            mForceStatusBarFromKeyguard = mShowingLockscreen && secureKeyguard;
-                        }
+                    if (!mAppsThatDismissKeyguard.isEmpty() &&
+                            mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
+                        if (DEBUG_LAYOUT) Slog.v(TAG,
+                                "Setting mDismissKeyguard true by win " + win);
+                        mDismissKeyguard = mWinDismissingKeyguard == win ?
+                                DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
+                        mWinDismissingKeyguard = win;
+                        mForceStatusBarFromKeyguard = mShowingLockscreen && secureKeyguard;
+                    } else if (mAppsToBeHidden.isEmpty() && showWhenLocked) {
+                        if (DEBUG_LAYOUT) Slog.v(TAG,
+                                "Setting mHideLockScreen to true by win " + win);
+                        mHideLockScreen = true;
+                        mForceStatusBarFromKeyguard = false;
                     }
                     if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
                         mAllowLockscreenWhenOn = true;
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index e9419ad..7716385 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -127,6 +127,7 @@
     long mLastAlarmDeliveryTime;
     long mStartCurrentDelayTime;
     long mNextNonWakeupDeliveryTime;
+    int mNumTimeChanged;
 
     private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser =
             new SparseArray<>();
@@ -821,6 +822,7 @@
                     pw.print(" = "); pw.println(sdf.format(new Date(nextNonWakeupRTC)));
             pw.print("Next wakeup: "); TimeUtils.formatDuration(mNextWakeup, nowELAPSED, pw);
                     pw.print(" = "); pw.println(sdf.format(new Date(nextWakeupRTC)));
+            pw.print("Num time change events: "); pw.println(mNumTimeChanged);
 
             if (mAlarmBatches.size() > 0) {
                 pw.println();
@@ -1535,7 +1537,7 @@
         for (int i=0; i<triggerList.size(); i++) {
             Alarm alarm = triggerList.get(i);
             try {
-                if (localLOGV) Slog.v(TAG, "sending alarm " + alarm);
+                Slog.v(TAG, "sending alarm " + alarm);
                 alarm.operation.send(getContext(), 0,
                         mBackgroundIntent.putExtra(
                                 Intent.EXTRA_ALARM_COUNT, alarm.count),
@@ -1619,6 +1621,9 @@
                     removeImpl(mTimeTickSender);
                     rebatchAllAlarms();
                     mClockReceiver.scheduleTimeTickEvent();
+                    synchronized (mLock) {
+                        mNumTimeChanged++;
+                    }
                     Intent intent = new Intent(Intent.ACTION_TIME_CHANGED);
                     intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
                             | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 4f179ce..2885b83 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -180,6 +180,7 @@
 import android.os.SystemProperties;
 import android.os.UpdateLock;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.text.format.DateUtils;
 import android.text.format.Time;
@@ -3369,6 +3370,16 @@
         }
     }
 
+    void enforceShellRestriction(String restriction, int userHandle) {
+        if (Binder.getCallingUid() == Process.SHELL_UID) {
+            if (userHandle < 0
+                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
+                throw new SecurityException("Shell does not have permission to access user "
+                        + userHandle);
+            }
+        }
+    }
+
     @Override
     public int getFrontActivityScreenCompatMode() {
         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
@@ -14602,6 +14613,14 @@
             throw new IllegalArgumentException(
                     "Call does not support special user #" + targetUserId);
         }
+        // Check shell permission
+        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
+            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
+                    targetUserId)) {
+                throw new SecurityException("Shell does not have permission to access user "
+                        + targetUserId + "\n " + Debug.getCallers(3));
+            }
+        }
         return targetUserId;
     }
 
@@ -14626,13 +14645,10 @@
             }
         } else if ("system".equals(componentProcessName)) {
             result = true;
-        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
-                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
-            // Phone app is allowed to export singleuser providers.
-            result = true;
-        } else {
-            // App with pre-defined UID, check if it's a persistent app
-            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
+        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
+            // Phone app and persistent apps are allowed to export singleuser providers.
+            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
+                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
         }
         if (DEBUG_MU) {
             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
@@ -14660,6 +14676,7 @@
             Intent service, String resolvedType,
             IServiceConnection connection, int flags, int userId) {
         enforceNotIsolatedCaller("bindService");
+
         // Refuse possible leaked file descriptors
         if (service != null && service.hasFileDescriptors() == true) {
             throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -15094,12 +15111,18 @@
     }
 
     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
-            int[] users) {
+            int callingUid, int[] users) {
         List<ResolveInfo> receivers = null;
         try {
             HashSet<ComponentName> singleUserReceivers = null;
             boolean scannedFirstReceivers = false;
             for (int user : users) {
+                // Skip users that have Shell restrictions
+                if (callingUid == Process.SHELL_UID
+                        && getUserManagerLocked().hasUserRestriction(
+                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
+                    continue;
+                }
                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
                 if (user != 0 && newReceivers != null) {
@@ -15188,7 +15211,6 @@
         // Make sure that the user who is receiving this broadcast is started.
         // If not, we will just skip it.
 
-
         if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
             if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
                     & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
@@ -15453,11 +15475,30 @@
         // Need to resolve the intent to interested receivers...
         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
                  == 0) {
-            receivers = collectReceiverComponents(intent, resolvedType, users);
+            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
         }
         if (intent.getComponent() == null) {
-            registeredReceivers = mReceiverResolver.queryIntent(intent,
-                    resolvedType, false, userId);
+            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
+                // Query one target user at a time, excluding shell-restricted users
+                UserManagerService ums = getUserManagerLocked();
+                for (int i = 0; i < users.length; i++) {
+                    if (ums.hasUserRestriction(
+                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
+                        continue;
+                    }
+                    List<BroadcastFilter> registeredReceiversForUser =
+                            mReceiverResolver.queryIntent(intent,
+                                    resolvedType, false, users[i]);
+                    if (registeredReceivers == null) {
+                        registeredReceivers = registeredReceiversForUser;
+                    } else if (registeredReceiversForUser != null) {
+                        registeredReceivers.addAll(registeredReceiversForUser);
+                    }
+                }
+            } else {
+                registeredReceivers = mReceiverResolver.queryIntent(intent,
+                        resolvedType, false, userId);
+            }
         }
 
         final boolean replacePending =
@@ -15619,7 +15660,7 @@
         enforceNotIsolatedCaller("broadcastIntent");
         synchronized(this) {
             intent = verifyBroadcastLocked(intent);
-            
+
             final ProcessRecord callerApp = getRecordForAppLocked(caller);
             final int callingPid = Binder.getCallingPid();
             final int callingUid = Binder.getCallingUid();
@@ -18027,6 +18068,7 @@
 
     @Override
     public boolean switchUser(final int userId) {
+        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
         String userName;
         synchronized (this) {
             UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
@@ -18468,6 +18510,7 @@
         if (userId <= 0) {
             throw new IllegalArgumentException("Can't stop primary user " + userId);
         }
+        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
         synchronized (this) {
             return stopUserLocked(userId, callback);
         }
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 1287dce..80d0510 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -21,6 +21,7 @@
 import java.nio.ByteBuffer;
 
 import android.app.ActivityManager;
+import android.os.Build;
 import android.os.SystemClock;
 import com.android.internal.util.MemInfoReader;
 import com.android.server.wm.WindowManagerService;
@@ -230,21 +231,31 @@
             Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
         }
 
+        final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
+
         for (int i=0; i<mOomAdj.length; i++) {
             int low = mOomMinFreeLow[i];
             int high = mOomMinFreeHigh[i];
             mOomMinFree[i] = (int)(low + ((high-low)*scale));
+            if (is64bit) {
+                // On 64 bit devices, we consume more baseline RAM, because 64 bit is cool!
+                // To avoid being all pagey and stuff, scale up the memory levels to
+                // give us some breathing room.
+                mOomMinFree[i] = (3*mOomMinFree[i])/2;
+            }
         }
 
         if (minfree_abs >= 0) {
             for (int i=0; i<mOomAdj.length; i++) {
-                mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]);
+                mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
+                        / mOomMinFree[mOomAdj.length - 1]);
             }
         }
 
         if (minfree_adj != 0) {
             for (int i=0; i<mOomAdj.length; i++) {
-                mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]);
+                mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i]
+                        / mOomMinFree[mOomAdj.length - 1]);
                 if (mOomMinFree[i] < 0) {
                     mOomMinFree[i] = 0;
                 }
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index 3cc406b..b21af48 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -347,6 +347,10 @@
     private static void removeObsoleteFiles(ArraySet<Integer> persistentTaskIds, File[] files) {
         if (DEBUG) Slog.d(TAG, "removeObsoleteFile: persistentTaskIds=" + persistentTaskIds +
                 " files=" + files);
+        if (files == null) {
+            Slog.e(TAG, "File error accessing recents directory (too many files open?).");
+            return;
+        }
         for (int fileNdx = 0; fileNdx < files.length; ++fileNdx) {
             File file = files[fileNdx];
             String filename = file.getName();
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index f6399a3..a6a9a89 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -69,7 +69,7 @@
 
         try {
             if (projection != null) {
-                projection.addCallback(new MediaProjectionCallback(appToken));
+                projection.registerCallback(new MediaProjectionCallback(appToken));
             }
             appToken.linkToDeath(device, 0);
         } catch (RemoteException ex) {
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 6ce235b..5823f47 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -255,37 +255,5 @@
     //     values which denotes the device type in HDMI Spec 1.4.
     static final String PROPERTY_DEVICE_TYPE = "ro.hdmi.device_type";
 
-    // --------------------------------------------------
-    // MHL sub command message types.
-    static final int MHL_MSG_MSGE  = 0x02;
-    static final int MHL_MSG_RCP   = 0x10;
-    static final int MHL_MSG_RCPK  = 0x11;
-    static final int MHL_MSG_RCPE  = 0x12;
-    static final int MHL_MSG_RAP   = 0x20;
-    static final int MHL_MSG_RAPK  = 0x21;
-
-    // MHL RAP messages.
-    static final int MHL_RAP_ACTION_POLL = 0x00;
-    static final int MHL_RAP_ACTION_CONTENT_ON = 0x10;
-    static final int MHL_RAP_ACTION_CONTENT_OFF = 0x11;
-
-    // MHL RAPK messages.
-    static final int MHL_RAPK_NO_ERROR = 0x00;
-    static final int MHL_RAPK_UNRECOGNIZED_ACTION = 0x01;
-    static final int MHL_RAPK_UNSUPPORTED_ACTION = 0x02;
-    static final int MHL_RAPK_RESPONDER_BUSY = 0x03;
-
-    static final int MHL_INVALID_ADOPTER_ID = -1;
-    static final int MHL_INVALID_DEVICE_ID = -1;
-
-    static final int MHL_CBUS_MODE_OCBUS = 1;
-    static final int MHL_CBUS_MODE_ECBUS_S = 2;
-    static final int MHL_CBUS_MODE_ECBUS_D = 3;
-
-    // MHL RCPE messages
-    static final int MHL_RCPE_NO_ERROR = 0x00;
-    static final int MHL_RCPE_INEFFECTIVE_KEYCODE = 0x01;
-    static final int MHL_RCPE_RESPONDER_BUSY = 0x02;
-
     private Constants() { /* cannot be instantiated */ }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index c5a6dbd..0e8788a 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -32,6 +32,7 @@
 import libcore.util.EmptyArray;
 
 import java.util.ArrayList;
+import java.util.LinkedList;
 import java.util.List;
 
 /**
@@ -367,7 +368,8 @@
 
         // Extract polling candidates. No need to poll against local devices.
         List<Integer> pollingCandidates = pickPollCandidates(pickStrategy);
-        runDevicePolling(sourceAddress, pollingCandidates, retryCount, callback);
+        ArrayList<Integer> allocated = new ArrayList<>();
+        runDevicePolling(sourceAddress, pollingCandidates, retryCount, callback, allocated);
     }
 
     /**
@@ -395,7 +397,7 @@
         }
 
         int iterationStrategy = pickStrategy & Constants.POLL_ITERATION_STRATEGY_MASK;
-        ArrayList<Integer> pollingCandidates = new ArrayList<>();
+        LinkedList<Integer> pollingCandidates = new LinkedList<>();
         switch (iterationStrategy) {
             case Constants.POLL_ITERATION_IN_ORDER:
                 for (int i = Constants.ADDR_TV; i <= Constants.ADDR_SPECIFIC_USE; ++i) {
@@ -430,26 +432,32 @@
     @ServiceThreadOnly
     private void runDevicePolling(final int sourceAddress,
             final List<Integer> candidates, final int retryCount,
-            final DevicePollingCallback callback) {
+            final DevicePollingCallback callback, final List<Integer> allocated) {
         assertRunOnServiceThread();
+        if (candidates.isEmpty()) {
+            if (callback != null) {
+                HdmiLogger.debug("[P]:AllocatedAddress=%s", allocated.toString());
+                callback.onPollingFinished(allocated);
+            }
+            return;
+        }
+
+        final Integer candidate = candidates.remove(0);
+        // Proceed polling action for the next address once polling action for the
+        // previous address is done.
         runOnIoThread(new Runnable() {
             @Override
             public void run() {
-                final ArrayList<Integer> allocated = new ArrayList<>();
-                for (Integer address : candidates) {
-                    if (sendPollMessage(sourceAddress, address, retryCount)) {
-                        allocated.add(address);
+                if (sendPollMessage(sourceAddress, candidate, retryCount)) {
+                    allocated.add(candidate);
+                }
+                runOnServiceThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        runDevicePolling(sourceAddress, candidates, retryCount, callback,
+                                allocated);
                     }
-                }
-                HdmiLogger.debug("[P]:Allocated Address=" + allocated);
-                if (callback != null) {
-                    runOnServiceThread(new Runnable() {
-                        @Override
-                        public void run() {
-                            callback.onPollingFinished(allocated);
-                        }
-                    });
-                }
+                });
             }
         });
     }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index c00c5d0..41ac589 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -263,7 +263,9 @@
             case Constants.MESSAGE_GIVE_DEVICE_POWER_STATUS:
                 return handleGiveDevicePowerStatus(message);
             case Constants.MESSAGE_MENU_REQUEST:
-                return handleGiveDeviceMenuStatus(message);
+                return handleMenuRequest(message);
+            case Constants.MESSAGE_MENU_STATUS:
+                return handleMenuStatus(message);
             case Constants.MESSAGE_VENDOR_COMMAND:
                 return handleVendorCommand(message);
             case Constants.MESSAGE_VENDOR_COMMAND_WITH_ID:
@@ -503,16 +505,24 @@
         return true;
     }
 
-    protected boolean handleGiveDeviceMenuStatus(HdmiCecMessage message) {
+    protected boolean handleMenuRequest(HdmiCecMessage message) {
         // Always report menu active to receive Remote Control.
         mService.sendCecCommand(HdmiCecMessageBuilder.buildReportMenuStatus(
                 mAddress, message.getSource(), Constants.MENU_STATE_ACTIVATED));
         return true;
     }
 
+    protected boolean handleMenuStatus(HdmiCecMessage message) {
+        return false;
+    }
+
     protected boolean handleVendorCommand(HdmiCecMessage message) {
-        mService.invokeVendorCommandListeners(mDeviceType, message.getSource(),
-                message.getParams(), false);
+        if (!mService.invokeVendorCommandListeners(mDeviceType, message.getSource(),
+                message.getParams(), false)) {
+            // Vendor command listener may not have been registered yet. Respond with
+            // <Feature Abort> [NOT_IN_CORRECT_MODE] so that the sender can try again later.
+            mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE);
+        }
         return true;
     }
 
@@ -520,7 +530,10 @@
         byte[] params = message.getParams();
         int vendorId = HdmiUtils.threeBytesToInt(params);
         if (vendorId == mService.getVendorId()) {
-            mService.invokeVendorCommandListeners(mDeviceType, message.getSource(), params, true);
+            if (!mService.invokeVendorCommandListeners(mDeviceType, message.getSource(), params,
+                    true)) {
+                mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE);
+            }
         } else if (message.getDestination() != Constants.ADDR_BROADCAST &&
                 message.getSource() != Constants.ADDR_UNREGISTERED) {
             Slog.v(TAG, "Wrong direct vendor command. Replying with <Feature Abort>");
@@ -531,6 +544,10 @@
         return true;
     }
 
+    protected void sendStandby(int deviceId) {
+        // Do nothing.
+    }
+
     protected boolean handleSetOsdName(HdmiCecMessage message) {
         // The default behavior of <Set Osd Name> is doing nothing.
         return true;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 58ccbdb..9033c38 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -1646,6 +1646,22 @@
     }
 
     @Override
+    protected boolean handleMenuStatus(HdmiCecMessage message) {
+        // Do nothing and just return true not to prevent from responding <Feature Abort>.
+        return true;
+    }
+
+    @Override
+    protected void sendStandby(int deviceId) {
+        HdmiDeviceInfo targetDevice = mDeviceInfos.get(deviceId);
+        if (targetDevice == null) {
+            return;
+        }
+        int targetAddress = targetDevice.getLogicalAddress();
+        mService.sendCecCommand(HdmiCecMessageBuilder.buildStandby(mAddress, targetAddress));
+    }
+
+    @Override
     protected void dump(final IndentingPrintWriter pw) {
         super.dump(pw);
         pw.println("mArcEstablished: " + mArcEstablished);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
index 0b3d9fb..d703989 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
@@ -25,6 +25,11 @@
 public final class HdmiCecMessageValidator {
     private static final String TAG = "HdmiCecMessageValidator";
 
+    static final int OK = 0;
+    static final int ERROR_SOURCE = 1;
+    static final int ERROR_DESTINATION = 2;
+    static final int ERROR_PARAMETER = 3;
+
     private final HdmiControlService mService;
 
     interface ParameterValidator {
@@ -140,7 +145,9 @@
         addValidationInfo(Constants.MESSAGE_SET_OSD_STRING, maxLengthValidator, DEST_DIRECT);
         addValidationInfo(Constants.MESSAGE_SET_OSD_NAME, maxLengthValidator, DEST_DIRECT);
 
-        // TODO: Handle messages for the Device Menu Control.
+        // Messages for the Device Menu Control.
+        addValidationInfo(Constants.MESSAGE_MENU_REQUEST, oneByteValidator, DEST_DIRECT);
+        addValidationInfo(Constants.MESSAGE_MENU_STATUS, oneByteValidator, DEST_DIRECT);
 
         // Messages for the Remote Control Passthrough.
         // TODO: Parse the first parameter and determine if it can have the next parameter.
@@ -178,39 +185,39 @@
         mValidationInfo.append(opcode, new ValidationInfo(validator, addrType));
     }
 
-    boolean isValid(HdmiCecMessage message) {
+    int isValid(HdmiCecMessage message) {
         int opcode = message.getOpcode();
         ValidationInfo info = mValidationInfo.get(opcode);
         if (info == null) {
             HdmiLogger.warning("No validation information for the message: " + message);
-            return true;
+            return OK;
         }
 
         // Check the source field.
         if (message.getSource() == Constants.ADDR_UNREGISTERED &&
                 (info.addressType & SRC_UNREGISTERED) == 0) {
             HdmiLogger.warning("Unexpected source: " + message);
-            return false;
+            return ERROR_SOURCE;
         }
         // Check the destination field.
         if (message.getDestination() == Constants.ADDR_BROADCAST) {
             if ((info.addressType & DEST_BROADCAST) == 0) {
                 HdmiLogger.warning("Unexpected broadcast message: " + message);
-                return false;
+                return ERROR_DESTINATION;
             }
         } else {  // Direct addressing.
             if ((info.addressType & DEST_DIRECT) == 0) {
                 HdmiLogger.warning("Unexpected direct message: " + message);
-                return false;
+                return ERROR_DESTINATION;
             }
         }
 
         // Check the parameter type.
         if (!info.parameterValidator.isValid(message.getParams())) {
             HdmiLogger.warning("Unexpected parameters: " + message);
-            return false;
+            return ERROR_PARAMETER;
         }
-        return true;
+        return OK;
     }
 
     private static class FixedLengthValidator implements ParameterValidator {
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 5cd7c01..96823e1 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -43,7 +43,7 @@
 import android.hardware.hdmi.IHdmiDeviceEventListener;
 import android.hardware.hdmi.IHdmiHotplugEventListener;
 import android.hardware.hdmi.IHdmiInputChangeListener;
-import android.hardware.hdmi.IHdmiMhlScratchpadCommandListener;
+import android.hardware.hdmi.IHdmiMhlVendorCommandListener;
 import android.hardware.hdmi.IHdmiRecordListener;
 import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener;
 import android.hardware.hdmi.IHdmiVendorCommandListener;
@@ -247,10 +247,10 @@
     @GuardedBy("mLock")
     private boolean mMhlInputChangeEnabled;
 
-    // List of records for MHL Scratchpad command listener to handle the caller killed in action.
+    // List of records for MHL Vendor command listener to handle the caller killed in action.
     @GuardedBy("mLock")
-    private final ArrayList<HdmiMhlScratchpadCommandListenerRecord>
-            mScratchpadCommandListenerRecords = new ArrayList<>();
+    private final ArrayList<HdmiMhlVendorCommandListenerRecord>
+            mMhlVendorCommandListenerRecords = new ArrayList<>();
 
     @GuardedBy("mLock")
     private List<HdmiDeviceInfo> mMhlDevices;
@@ -651,7 +651,7 @@
     @ServiceThreadOnly
     void sendCecCommand(HdmiCecMessage command, @Nullable SendMessageCallback callback) {
         assertRunOnServiceThread();
-        if (mMessageValidator.isValid(command)) {
+        if (mMessageValidator.isValid(command) == HdmiCecMessageValidator.OK) {
             mCecController.sendCommand(command, callback);
         } else {
             HdmiLogger.error("Invalid message type:" + command);
@@ -682,8 +682,13 @@
     @ServiceThreadOnly
     boolean handleCecCommand(HdmiCecMessage message) {
         assertRunOnServiceThread();
-        if (!mMessageValidator.isValid(message)) {
-            return false;
+        int errorCode = mMessageValidator.isValid(message);
+        if (errorCode != HdmiCecMessageValidator.OK) {
+            // We'll not response on the messages with the invalid source or destination.
+            if (errorCode == HdmiCecMessageValidator.ERROR_PARAMETER) {
+                maySendFeatureAbortCommand(message, Constants.ABORT_INVALID_OPERAND);
+            }
+            return true;
         }
         return dispatchMessageToLocalDevice(message);
     }
@@ -814,45 +819,21 @@
     }
 
     @ServiceThreadOnly
-    void sendMhlSubcommand(int portId, HdmiMhlSubcommand command) {
-        assertRunOnServiceThread();
-        sendMhlSubcommand(portId, command, null);
-    }
-
-    @ServiceThreadOnly
-    void sendMhlSubcommand(int portId, HdmiMhlSubcommand command, SendMessageCallback callback) {
-        assertRunOnServiceThread();
-        mMhlController.sendSubcommand(portId, command, callback);
-    }
-
-    @ServiceThreadOnly
-    boolean handleMhlSubcommand(int portId, HdmiMhlSubcommand message) {
-        assertRunOnServiceThread();
-
-        HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId);
-        if (device != null) {
-            return device.handleSubcommand(message);
-        }
-        Slog.w(TAG, "No mhl device exists[portId:" + portId + ", message:" + message);
-        return false;
-    }
-
-    @ServiceThreadOnly
     void handleMhlHotplugEvent(int portId, boolean connected) {
         assertRunOnServiceThread();
         if (connected) {
-            HdmiMhlLocalDevice newDevice = new HdmiMhlLocalDevice(this, portId);
-            HdmiMhlLocalDevice oldDevice = mMhlController.addLocalDevice(newDevice);
+            HdmiMhlLocalDeviceStub newDevice = new HdmiMhlLocalDeviceStub(this, portId);
+            HdmiMhlLocalDeviceStub oldDevice = mMhlController.addLocalDevice(newDevice);
             if (oldDevice != null) {
                 oldDevice.onDeviceRemoved();
                 Slog.i(TAG, "Old device of port " + portId + " is removed");
             }
         } else {
-            HdmiMhlLocalDevice device = mMhlController.removeLocalDevice(portId);
+            HdmiMhlLocalDeviceStub device = mMhlController.removeLocalDevice(portId);
             if (device != null) {
                 device.onDeviceRemoved();
-                // There is no explicit event for device removal unlike capability register event
-                // used for device addition . Hence we remove the device on hotplug event.
+                // There is no explicit event for device removal.
+                // Hence we remove the device on hotplug event.
                 HdmiDeviceInfo deviceInfo = device.getInfo();
                 if (deviceInfo != null) {
                     invokeDeviceEventListeners(deviceInfo, DEVICE_EVENT_REMOVE_DEVICE);
@@ -866,40 +847,40 @@
     }
 
     @ServiceThreadOnly
-    void handleMhlCbusModeChanged(int portId, int cbusmode) {
+    void handleMhlBusModeChanged(int portId, int busmode) {
         assertRunOnServiceThread();
-        HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId);
+        HdmiMhlLocalDeviceStub device = mMhlController.getLocalDevice(portId);
         if (device != null) {
-            device.setCbusMode(cbusmode);
+            device.setBusMode(busmode);
         } else {
-            Slog.w(TAG, "No mhl device exists for cbus mode change[portId:" + portId +
-                    ", cbusmode:" + cbusmode + "]");
+            Slog.w(TAG, "No mhl device exists for bus mode change[portId:" + portId +
+                    ", busmode:" + busmode + "]");
         }
     }
 
     @ServiceThreadOnly
-    void handleMhlVbusOvercurrent(int portId, boolean on) {
+    void handleMhlBusOvercurrent(int portId, boolean on) {
         assertRunOnServiceThread();
-        HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId);
+        HdmiMhlLocalDeviceStub device = mMhlController.getLocalDevice(portId);
         if (device != null) {
-            device.onVbusOvercurrentDetected(on);
+            device.onBusOvercurrentDetected(on);
         } else {
-            Slog.w(TAG, "No mhl device exists for vbus overcurrent event[portId:" + portId + "]");
+            Slog.w(TAG, "No mhl device exists for bus overcurrent event[portId:" + portId + "]");
         }
     }
 
     @ServiceThreadOnly
-    void handleMhlCapabilityRegisterChanged(int portId, int adopterId, int deviceId) {
+    void handleMhlDeviceStatusChanged(int portId, int adopterId, int deviceId) {
         assertRunOnServiceThread();
-        HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId);
+        HdmiMhlLocalDeviceStub device = mMhlController.getLocalDevice(portId);
 
-        // Hotplug event should already have been called before capability register change event.
+        // Hotplug event should already have been called before device status change event.
         if (device != null) {
-            device.setCapabilityRegister(adopterId, deviceId);
+            device.setDeviceStatusChange(adopterId, deviceId);
             invokeDeviceEventListeners(device.getInfo(), DEVICE_EVENT_ADD_DEVICE);
             updateSafeMhlInput();
         } else {
-            Slog.w(TAG, "No mhl device exists for capability register change event[portId:"
+            Slog.w(TAG, "No mhl device exists for device status event[portId:"
                     + portId + ", adopterId:" + adopterId + ", deviceId:" + deviceId + "]");
         }
     }
@@ -908,9 +889,9 @@
     private void updateSafeMhlInput() {
         assertRunOnServiceThread();
         List<HdmiDeviceInfo> inputs = Collections.emptyList();
-        SparseArray<HdmiMhlLocalDevice> devices = mMhlController.getAllLocalDevices();
+        SparseArray<HdmiMhlLocalDeviceStub> devices = mMhlController.getAllLocalDevices();
         for (int i = 0; i < devices.size(); ++i) {
-            HdmiMhlLocalDevice device = devices.valueAt(i);
+            HdmiMhlLocalDeviceStub device = devices.valueAt(i);
             HdmiDeviceInfo info = device.getInfo();
             if (info != null) {
                 if (inputs.isEmpty()) {
@@ -928,16 +909,16 @@
         return mMhlDevices;
     }
 
-    private class HdmiMhlScratchpadCommandListenerRecord implements IBinder.DeathRecipient {
-        private final IHdmiMhlScratchpadCommandListener mListener;
+    private class HdmiMhlVendorCommandListenerRecord implements IBinder.DeathRecipient {
+        private final IHdmiMhlVendorCommandListener mListener;
 
-        public HdmiMhlScratchpadCommandListenerRecord(IHdmiMhlScratchpadCommandListener listener) {
+        public HdmiMhlVendorCommandListenerRecord(IHdmiMhlVendorCommandListener listener) {
             mListener = listener;
         }
 
         @Override
         public void binderDied() {
-            mScratchpadCommandListenerRecords.remove(this);
+            mMhlVendorCommandListenerRecords.remove(this);
         }
     }
 
@@ -1072,7 +1053,7 @@
                         invokeCallback(callback, HdmiControlManager.RESULT_SOURCE_NOT_AVAILABLE);
                         return;
                     }
-                    HdmiMhlLocalDevice device = mMhlController.getLocalDeviceById(deviceId);
+                    HdmiMhlLocalDeviceStub device = mMhlController.getLocalDeviceById(deviceId);
                     if (device != null) {
                         if (device.getPortId() == tv.getActivePortId()) {
                             invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS);
@@ -1117,7 +1098,7 @@
             runOnServiceThread(new Runnable() {
                 @Override
                 public void run() {
-                    HdmiMhlLocalDevice device = mMhlController.getLocalDevice(mActivePortId);
+                    HdmiMhlLocalDeviceStub device = mMhlController.getLocalDevice(mActivePortId);
                     if (device != null) {
                         device.sendKeyEvent(keyCode, isPressed);
                         return;
@@ -1340,6 +1321,22 @@
         }
 
         @Override
+        public void sendStandby(final int deviceType, final int deviceId) {
+            enforceAccessPermission();
+            runOnServiceThread(new Runnable() {
+                @Override
+                public void run() {
+                    HdmiCecLocalDevice device = mCecController.getLocalDevice(deviceType);
+                    if (device == null) {
+                        Slog.w(TAG, "Local device not available");
+                        return;
+                    }
+                    device.sendStandby(deviceId);
+                }
+            });
+        }
+
+        @Override
         public void setHdmiRecordListener(IHdmiRecordListener listener) {
             HdmiControlService.this.setHdmiRecordListener(listener);
         }
@@ -1403,7 +1400,7 @@
         }
 
         @Override
-        public void sendScratchpadCommand(final int portId, final int offset, final int length,
+        public void sendMhlVendorCommand(final int portId, final int offset, final int length,
                 final byte[] data) {
             enforceAccessPermission();
             runOnServiceThread(new Runnable() {
@@ -1413,21 +1410,21 @@
                         Slog.w(TAG, "Hdmi control is disabled.");
                         return ;
                     }
-                    HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId);
+                    HdmiMhlLocalDeviceStub device = mMhlController.getLocalDevice(portId);
                     if (device == null) {
                         Slog.w(TAG, "Invalid port id:" + portId);
                         return;
                     }
-                    mMhlController.sendScratchpadCommand(portId, offset, length, data);
+                    mMhlController.sendVendorCommand(portId, offset, length, data);
                 }
             });
         }
 
         @Override
-        public void addHdmiMhlScratchpadCommandListener(
-                IHdmiMhlScratchpadCommandListener listener) {
+        public void addHdmiMhlVendorCommandListener(
+                IHdmiMhlVendorCommandListener listener) {
             enforceAccessPermission();
-            HdmiControlService.this.addHdmiMhlScratchpadCommandListener(listener);
+            HdmiControlService.this.addHdmiMhlVendorCommandListener(listener);
         }
 
         @Override
@@ -1864,9 +1861,12 @@
         }
     }
 
-    void invokeVendorCommandListeners(int deviceType, int srcAddress, byte[] params,
+    boolean invokeVendorCommandListeners(int deviceType, int srcAddress, byte[] params,
             boolean hasVendorId) {
         synchronized (mLock) {
+            if (mVendorCommandListenerRecords.isEmpty()) {
+                return false;
+            }
             for (VendorCommandListenerRecord record : mVendorCommandListenerRecords) {
                 if (record.mDeviceType != deviceType) {
                     continue;
@@ -1877,12 +1877,13 @@
                     Slog.e(TAG, "Failed to notify vendor command reception", e);
                 }
             }
+            return true;
         }
     }
 
-    private void addHdmiMhlScratchpadCommandListener(IHdmiMhlScratchpadCommandListener listener) {
-        HdmiMhlScratchpadCommandListenerRecord record =
-                new HdmiMhlScratchpadCommandListenerRecord(listener);
+    private void addHdmiMhlVendorCommandListener(IHdmiMhlVendorCommandListener listener) {
+        HdmiMhlVendorCommandListenerRecord record =
+                new HdmiMhlVendorCommandListenerRecord(listener);
         try {
             listener.asBinder().linkToDeath(record, 0);
         } catch (RemoteException e) {
@@ -1891,18 +1892,17 @@
         }
 
         synchronized (mLock) {
-            mScratchpadCommandListenerRecords.add(record);
+            mMhlVendorCommandListenerRecords.add(record);
         }
     }
 
-    void invokeScratchpadCommandListeners(int portId, int offest, int length, byte[] data) {
+    void invokeMhlVendorCommandListeners(int portId, int offest, int length, byte[] data) {
         synchronized (mLock) {
-            for (HdmiMhlScratchpadCommandListenerRecord record :
-                    mScratchpadCommandListenerRecords) {
+            for (HdmiMhlVendorCommandListenerRecord record : mMhlVendorCommandListenerRecords) {
                 try {
                     record.mListener.onReceived(portId, offest, length, data);
                 } catch (RemoteException e) {
-                    Slog.e(TAG, "Failed to notify scratchpad command", e);
+                    Slog.e(TAG, "Failed to notify MHL vendor command", e);
                 }
             }
         }
@@ -2001,7 +2001,7 @@
         // the last port to go back to when turnoff command is received. Note that the last port
         // may not be the MHL-enabled one. In this case the device info to be passed to
         // input change listener should be the one describing the corresponding HDMI port.
-        HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId);
+        HdmiMhlLocalDeviceStub device = mMhlController.getLocalDevice(portId);
         HdmiDeviceInfo info = (device != null && device.getInfo() != null)
                 ? device.getInfo()
                 : mPortDeviceMap.get(portId);
diff --git a/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java b/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java
index c27cf18..708aee6 100644
--- a/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java
+++ b/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java
@@ -29,7 +29,7 @@
  */
 final class HdmiMhlControllerStub {
 
-    private static final SparseArray<HdmiMhlLocalDevice> mLocalDevices = new SparseArray<>();
+    private static final SparseArray<HdmiMhlLocalDeviceStub> mLocalDevices = new SparseArray<>();
     private static final HdmiPortInfo[] EMPTY_PORT_INFO = new HdmiPortInfo[0];
     private static final int INVALID_MHL_VERSION = 0;
     private static final int NO_SUPPORTED_FEATURES = 0;
@@ -53,60 +53,49 @@
     }
 
     /**
-     * Return {@link HdmiMhlLocalDevice} matched with the given port id.
+     * Return {@link HdmiMhlLocalDeviceStub} matched with the given port id.
      *
      * @return null if has no matched port id
      */
-    HdmiMhlLocalDevice getLocalDevice(int portId) {
+    HdmiMhlLocalDeviceStub getLocalDevice(int portId) {
         return null;
     }
 
     /**
-     * Return {@link HdmiMhlLocalDevice} matched with the given device id.
+     * Return {@link HdmiMhlLocalDeviceStub} matched with the given device id.
      *
      * @return null if has no matched id
      */
-    HdmiMhlLocalDevice getLocalDeviceById(int deviceId) {
+    HdmiMhlLocalDeviceStub getLocalDeviceById(int deviceId) {
         return null;
     }
 
-    SparseArray<HdmiMhlLocalDevice> getAllLocalDevices() {
+    SparseArray<HdmiMhlLocalDeviceStub> getAllLocalDevices() {
         return mLocalDevices;
     }
 
     /**
-     * Remove a {@link HdmiMhlLocalDevice} matched with the given port id.
+     * Remove a {@link HdmiMhlLocalDeviceStub} matched with the given port id.
      *
-     * @return removed {@link HdmiMhlLocalDevice}. Return null if no matched port id.
+     * @return removed {@link HdmiMhlLocalDeviceStub}. Return null if no matched port id.
      */
-    HdmiMhlLocalDevice removeLocalDevice(int portId) {
+    HdmiMhlLocalDeviceStub removeLocalDevice(int portId) {
         return null;
     }
 
     /**
-     * Add a new {@link HdmiMhlLocalDevice}.
+     * Add a new {@link HdmiMhlLocalDeviceStub}.
      *
-     * @return old {@link HdmiMhlLocalDevice} having same port id
+     * @return old {@link HdmiMhlLocalDeviceStub} having same port id
      */
-    HdmiMhlLocalDevice addLocalDevice(HdmiMhlLocalDevice device) {
+    HdmiMhlLocalDeviceStub addLocalDevice(HdmiMhlLocalDeviceStub device) {
         return null;
     }
 
     void clearAllLocalDevices() {
     }
 
-    /**
-     * Send MHL MSC-Subcommand to the device connected to the given port.
-     */
-    void sendSubcommand(int portId, HdmiMhlSubcommand command) {
-    }
-
-    void sendSubcommand(final int portId, final HdmiMhlSubcommand command,
-            SendMessageCallback callback) {
-    }
-
-
-    void sendScratchpadCommand(int portId, int offset, int length, byte[] data) {
+    void sendVendorCommand(int portId, int offset, int length, byte[] data) {
     }
 
     void setOption(int flag, int value) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiMhlLocalDeviceStub.java b/services/core/java/com/android/server/hdmi/HdmiMhlLocalDeviceStub.java
new file mode 100644
index 0000000..53a7c5c
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/HdmiMhlLocalDeviceStub.java
@@ -0,0 +1,46 @@
+package com.android.server.hdmi;
+
+import android.hardware.hdmi.HdmiDeviceInfo;
+import android.hardware.hdmi.IHdmiControlCallback;
+
+/**
+ * Stub class that models a logical mhl device hosted in this system.
+ */
+final class HdmiMhlLocalDeviceStub {
+
+    private static final HdmiDeviceInfo INFO = new HdmiDeviceInfo(
+            Constants.INVALID_PHYSICAL_ADDRESS, Constants.INVALID_PORT_ID, -1, -1);
+    private final HdmiControlService mService;
+    private final int mPortId;
+
+    protected HdmiMhlLocalDeviceStub(HdmiControlService service, int portId) {
+        mService = service;
+        mPortId = portId;
+    }
+
+    void onDeviceRemoved() {
+    }
+
+    HdmiDeviceInfo getInfo() {
+        return INFO;
+    }
+
+    void setBusMode(int cbusmode) {
+    }
+
+    void onBusOvercurrentDetected(boolean on) {
+    }
+
+    void setDeviceStatusChange(int adopterId, int deviceId) {
+    }
+
+    int getPortId() {
+        return mPortId;
+    }
+
+    void turnOn(IHdmiControlCallback callback) {
+    }
+
+    void sendKeyEvent(int keycode, boolean isPressed) {
+    }
+}
diff --git a/services/core/java/com/android/server/hdmi/MhlConstants.java b/services/core/java/com/android/server/hdmi/MhlConstants.java
new file mode 100644
index 0000000..fe479f3
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/MhlConstants.java
@@ -0,0 +1,40 @@
+package com.android.server.hdmi;
+
+/**
+ * Defines constants related to MHL protocol internal implementation.
+ */
+final class MhlConstants {
+    // --------------------------------------------------
+    // MHL sub command message types.
+    static final int MSG_MSGE  = 0x02;
+    static final int MSG_RCP   = 0x10;
+    static final int MSG_RCPK  = 0x11;
+    static final int MSG_RCPE  = 0x12;
+    static final int MSG_RAP   = 0x20;
+    static final int MSG_RAPK  = 0x21;
+
+    // MHL RAP messages.
+    static final int RAP_ACTION_POLL = 0x00;
+    static final int RAP_ACTION_CONTENT_ON = 0x10;
+    static final int RAP_ACTION_CONTENT_OFF = 0x11;
+
+    // MHL RAPK messages.
+    static final int RAPK_NO_ERROR = 0x00;
+    static final int RAPK_UNRECOGNIZED_ACTION = 0x01;
+    static final int RAPK_UNSUPPORTED_ACTION = 0x02;
+    static final int RAPK_RESPONDER_BUSY = 0x03;
+
+    static final int INVALID_ADOPTER_ID = -1;
+    static final int INVALID_DEVICE_ID = -1;
+
+    static final int CBUS_MODE_OCBUS = 1;
+    static final int CBUS_MODE_ECBUS_S = 2;
+    static final int CBUS_MODE_ECBUS_D = 3;
+
+    // MHL RCPE messages
+    static final int RCPE_NO_ERROR = 0x00;
+    static final int RCPE_INEFFECTIVE_KEYCODE = 0x01;
+    static final int RCPE_RESPONDER_BUSY = 0x02;
+
+    private MhlConstants() { /* cannot be instantiated */ }
+}
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index 344c57b..d0447bc 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -153,7 +153,8 @@
             }
 
             mRunningJob = job;
-            mParams = new JobParameters(job.getJobId(), job.getExtras(), this);
+            mParams = new JobParameters(this, job.getJobId(), job.getExtras(),
+                    !job.isConstraintsSatisfied());
             mExecutionStartTimeElapsed = SystemClock.elapsedRealtime();
 
             mVerb = VERB_BINDING;
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index f562721..e3c55b6 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -195,16 +195,23 @@
     }
 
     /**
-     * @return Whether or not this job is ready to run, based on its requirements.
+     * @return Whether or not this job is ready to run, based on its requirements. This is true if
+     * the constraints are satisfied <strong>or</strong> the deadline on the job has expired.
      */
     public synchronized boolean isReady() {
+        return isConstraintsSatisfied()
+                || (hasDeadlineConstraint() && deadlineConstraintSatisfied.get());
+    }
+
+    /**
+     * @return Whether the constraints set on this job are satisfied.
+     */
+    public synchronized boolean isConstraintsSatisfied() {
         return (!hasChargingConstraint() || chargingConstraintSatisfied.get())
                 && (!hasTimingDelayConstraint() || timeDelayConstraintSatisfied.get())
                 && (!hasConnectivityConstraint() || connectivityConstraintSatisfied.get())
                 && (!hasUnmeteredConstraint() || unmeteredConstraintSatisfied.get())
-                && (!hasIdleConstraint() || idleConstraintSatisfied.get())
-                // Also ready if the deadline has expired - special case.
-                || (hasDeadlineConstraint() && deadlineConstraintSatisfied.get());
+                && (!hasIdleConstraint() || idleConstraintSatisfied.get());
     }
 
     public boolean matches(int uid, int jobId) {
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 8ec9b254..8a1f3ad 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -389,7 +389,7 @@
                     throw new IllegalStateException(
                             "Cannot start already started MediaProjection");
                 }
-                addCallback(callback);
+                registerCallback(callback);
                 try {
                     mToken = callback.asBinder();
                     mDeathEater = new IBinder.DeathRecipient() {
@@ -424,7 +424,7 @@
         }
 
         @Override
-        public void addCallback(IMediaProjectionCallback callback) {
+        public void registerCallback(IMediaProjectionCallback callback) {
             if (callback == null) {
                 throw new IllegalArgumentException("callback must not be null");
             }
@@ -432,7 +432,7 @@
         }
 
         @Override
-        public void removeCallback(IMediaProjectionCallback callback) {
+        public void unregisterCallback(IMediaProjectionCallback callback) {
             if (callback == null) {
                 throw new IllegalArgumentException("callback must not be null");
             }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 9e5fa41..cf19416 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -433,14 +433,12 @@
 
         // listen for configured wifi networks to be removed
         final IntentFilter wifiConfigFilter = new IntentFilter(CONFIGURED_NETWORKS_CHANGED_ACTION);
-        mContext.registerReceiver(
-                mWifiConfigReceiver, wifiConfigFilter, CONNECTIVITY_INTERNAL, mHandler);
+        mContext.registerReceiver(mWifiConfigReceiver, wifiConfigFilter, null, mHandler);
 
         // listen for wifi state changes to catch metered hint
         final IntentFilter wifiStateFilter = new IntentFilter(
                 WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        mContext.registerReceiver(
-                mWifiStateReceiver, wifiStateFilter, CONNECTIVITY_INTERNAL, mHandler);
+        mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler);
 
     }
 
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index f995dee..b5aa4d8 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -318,7 +318,7 @@
 
         // watch for tethering changes
         final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
-        mContext.registerReceiver(mTetherReceiver, tetherFilter, CONNECTIVITY_INTERNAL, mHandler);
+        mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler);
 
         // listen for periodic polling events
         final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index c09eff8..3235574 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1236,17 +1236,16 @@
                         final int N = keys.length;
                         for (int i = 0; i < N; i++) {
                             NotificationRecord r = mNotificationsByKey.get(keys[i]);
+                            if (r == null) continue;
                             final int userId = r.sbn.getUserId();
                             if (userId != info.userid && userId != UserHandle.USER_ALL &&
                                     !mUserProfiles.isCurrentProfile(userId)) {
                                 throw new SecurityException("Disallowed call from listener: "
                                         + info.service);
                             }
-                            if (r != null) {
-                                cancelNotificationFromListenerLocked(info, callingUid, callingPid,
-                                        r.sbn.getPackageName(), r.sbn.getTag(), r.sbn.getId(),
-                                        userId);
-                            }
+                            cancelNotificationFromListenerLocked(info, callingUid, callingPid,
+                                    r.sbn.getPackageName(), r.sbn.getTag(), r.sbn.getId(),
+                                    userId);
                         }
                     } else {
                         cancelAllLocked(callingUid, callingPid, info.userid,
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 496c136..ed678d2 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -446,7 +446,7 @@
     private int createSessionInternal(SessionParams params, String installerPackageName, int userId)
             throws IOException {
         final int callingUid = Binder.getCallingUid();
-        mPm.enforceCrossUserPermission(callingUid, userId, true, "createSession");
+        mPm.enforceCrossUserPermission(callingUid, userId, true, false, "createSession");
 
         if (mPm.isUserRestricted(UserHandle.getUserId(callingUid),
                 UserManager.DISALLOW_INSTALL_APPS)) {
@@ -654,7 +654,7 @@
 
     @Override
     public List<SessionInfo> getAllSessions(int userId) {
-        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "getAllSessions");
+        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "getAllSessions");
 
         final List<SessionInfo> result = new ArrayList<>();
         synchronized (mSessions) {
@@ -670,7 +670,7 @@
 
     @Override
     public List<SessionInfo> getMySessions(String installerPackageName, int userId) {
-        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "getMySessions");
+        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "getMySessions");
         mAppOps.checkPackage(Binder.getCallingUid(), installerPackageName);
 
         final List<SessionInfo> result = new ArrayList<>();
@@ -688,7 +688,7 @@
 
     @Override
     public void uninstall(String packageName, int flags, IntentSender statusReceiver, int userId) {
-        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "uninstall");
+        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "uninstall");
 
         final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext,
                 statusReceiver, packageName);
@@ -717,7 +717,7 @@
 
     @Override
     public void registerCallback(IPackageInstallerCallback callback, int userId) {
-        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "registerCallback");
+        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "registerCallback");
         mCallbacks.register(callback, userId);
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a5e84f6..f09d789 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -138,6 +138,7 @@
 import android.os.Environment;
 import android.os.Environment.UserEnvironment;
 import android.os.storage.StorageManager;
+import android.os.Debug;
 import android.os.FileUtils;
 import android.os.Handler;
 import android.os.IBinder;
@@ -1792,19 +1793,17 @@
     void cleanupInstallFailedPackage(PackageSetting ps) {
         Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name);
         removeDataDirsLI(ps.name);
-
-        // TODO: try cleaning up codePath directory contents first, since it
-        // might be a cluster
-
         if (ps.codePath != null) {
-            if (!ps.codePath.delete()) {
-                Slog.w(TAG, "Unable to remove old code file: " + ps.codePath);
+            if (ps.codePath.isDirectory()) {
+                FileUtils.deleteContents(ps.codePath);
             }
+            ps.codePath.delete();
         }
-        if (ps.resourcePath != null) {
-            if (!ps.resourcePath.delete() && !ps.resourcePath.equals(ps.codePath)) {
-                Slog.w(TAG, "Unable to remove old code file: " + ps.resourcePath);
+        if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
+            if (ps.resourcePath.isDirectory()) {
+                FileUtils.deleteContents(ps.resourcePath);
             }
+            ps.resourcePath.delete();
         }
         mSettings.removePackageLPw(ps.name);
     }
@@ -1845,7 +1844,7 @@
     @Override
     public boolean isPackageAvailable(String packageName, int userId) {
         if (!sUserManager.exists(userId)) return false;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "is package available");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(packageName);
             if (p != null) {
@@ -1864,7 +1863,7 @@
     @Override
     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package info");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
         // reader
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(packageName);
@@ -1909,7 +1908,7 @@
     @Override
     public int getPackageUid(String packageName, int userId) {
         if (!sUserManager.exists(userId)) return -1;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package uid");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
         // reader
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(packageName);
@@ -2059,7 +2058,7 @@
     @Override
     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get application info");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
         // writer
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(packageName);
@@ -2150,7 +2149,7 @@
     @Override
     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get activity info");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
         synchronized (mPackages) {
             PackageParser.Activity a = mActivities.mActivities.get(component);
 
@@ -2189,7 +2188,7 @@
     @Override
     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get receiver info");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
         synchronized (mPackages) {
             PackageParser.Activity a = mReceivers.mActivities.get(component);
             if (DEBUG_PACKAGE_INFO) Log.v(
@@ -2207,7 +2206,7 @@
     @Override
     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get service info");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
         synchronized (mPackages) {
             PackageParser.Service s = mServices.mServices.get(component);
             if (DEBUG_PACKAGE_INFO) Log.v(
@@ -2225,7 +2224,7 @@
     @Override
     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get provider info");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
         synchronized (mPackages) {
             PackageParser.Provider p = mProviders.mProviders.get(component);
             if (DEBUG_PACKAGE_INFO) Log.v(
@@ -2329,13 +2328,17 @@
     /**
      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
+     * @param checkShell TODO(yamasani):
      * @param message the message to log on security exception
      */
     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
-            String message) {
+            boolean checkShell, String message) {
         if (userId < 0) {
             throw new IllegalArgumentException("Invalid userId " + userId);
         }
+        if (checkShell) {
+            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
+        }
         if (userId == UserHandle.getUserId(callingUid)) return;
         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
             if (requireFullPermission) {
@@ -2353,6 +2356,19 @@
         }
     }
 
+    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
+        if (callingUid == Process.SHELL_UID) {
+            if (userHandle >= 0
+                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
+                throw new SecurityException("Shell does not have permission to access user "
+                        + userHandle);
+            } else if (userHandle < 0) {
+                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
+                        + Debug.getCallers(3));
+            }
+        }
+    }
+
     private BasePermission findPermissionTreeLP(String permName) {
         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
             if (permName.startsWith(bp.name) &&
@@ -2876,7 +2892,7 @@
     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
             int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "resolve intent");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
         return chooseBestActivity(intent, resolvedType, flags, query, userId);
     }
@@ -3199,7 +3215,7 @@
     public List<ResolveInfo> queryIntentActivities(Intent intent,
             String resolvedType, int flags, int userId) {
         if (!sUserManager.exists(userId)) return Collections.emptyList();
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "query intent activities");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
         ComponentName comp = intent.getComponent();
         if (comp == null) {
             if (intent.getSelector() != null) {
@@ -3346,7 +3362,7 @@
             String resolvedType, int flags, int userId) {
         if (!sUserManager.exists(userId)) return Collections.emptyList();
         enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
-                "query intent activity options");
+                false, "query intent activity options");
         final String resultsAction = intent.getAction();
 
         List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
@@ -3642,7 +3658,7 @@
     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
 
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "get installed packages");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
 
         // writer
         synchronized (mPackages) {
@@ -4940,6 +4956,21 @@
 
     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
+        boolean success = false;
+        try {
+            final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
+                    currentTime, user);
+            success = true;
+            return res;
+        } finally {
+            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
+                removeDataDirsLI(pkg.packageName);
+            }
+        }
+    }
+
+    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
+            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
         final File scanFile = new File(pkg.codePath);
         if (pkg.applicationInfo.getCodePath() == null ||
                 pkg.applicationInfo.getResourcePath() == null) {
@@ -5246,7 +5277,8 @@
         File dataPath;
         if (mPlatformPackage == pkg) {
             // The system package is special.
-            dataPath = new File (Environment.getDataDirectory(), "system");
+            dataPath = new File(Environment.getDataDirectory(), "system");
+
             pkg.applicationInfo.dataDir = dataPath.getPath();
 
         } else {
@@ -5254,7 +5286,6 @@
             dataPath = getDataPathForPackage(pkg.packageName, 0);
 
             boolean uidError = false;
-
             if (dataPath.exists()) {
                 int currentUid = 0;
                 try {
@@ -5581,13 +5612,9 @@
                     pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0);
         }
 
-        if ((scanFlags&SCAN_NO_DEX) == 0) {
-            if (performDexOptLI(pkg, null /* instruction sets */, forceDex, (scanFlags&SCAN_DEFER_DEX) != 0, false)
-                    == DEX_OPT_FAILED) {
-                if ((scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
-                    removeDataDirsLI(pkg.packageName);
-                }
-
+        if ((scanFlags & SCAN_NO_DEX) == 0) {
+            if (performDexOptLI(pkg, null /* instruction sets */, forceDex,
+                    (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
                 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
             }
         }
@@ -5658,16 +5685,11 @@
         // if these fail, we should abort the install since installing the library will
         // result in some apps being broken.
         if (clientLibPkgs != null) {
-            if ((scanFlags&SCAN_NO_DEX) == 0) {
-                for (int i=0; i<clientLibPkgs.size(); i++) {
+            if ((scanFlags & SCAN_NO_DEX) == 0) {
+                for (int i = 0; i < clientLibPkgs.size(); i++) {
                     PackageParser.Package clientPkg = clientLibPkgs.get(i);
-                    if (performDexOptLI(clientPkg, null /* instruction sets */,
-                            forceDex, (scanFlags&SCAN_DEFER_DEX) != 0, false)
-                            == DEX_OPT_FAILED) {
-                        if ((scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
-                            removeDataDirsLI(pkg.packageName);
-                        }
-
+                    if (performDexOptLI(clientPkg, null /* instruction sets */, forceDex,
+                            (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
                         throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
                                 "scanPackageLI failed to dexopt clientLibPkgs");
                     }
@@ -7660,7 +7682,7 @@
 
         final File originFile = new File(originPath);
         final int uid = Binder.getCallingUid();
-        if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
+        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
             try {
                 if (observer != null) {
                     observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
@@ -7748,11 +7770,8 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
         PackageSetting pkgSetting;
         final int uid = Binder.getCallingUid();
-        if (UserHandle.getUserId(uid) != userId) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
-                    "setApplicationHiddenSetting for user " + userId);
-        }
+        enforceCrossUserPermission(uid, userId, true, true,
+                "setApplicationHiddenSetting for user " + userId);
 
         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
@@ -7811,7 +7830,7 @@
     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
         enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
-                "getApplicationHidden for user " + userId);
+                false, "getApplicationHidden for user " + userId);
         PackageSetting pkgSetting;
         long callingId = Binder.clearCallingIdentity();
         try {
@@ -7837,7 +7856,8 @@
                 null);
         PackageSetting pkgSetting;
         final int uid = Binder.getCallingUid();
-        enforceCrossUserPermission(uid, userId, true, "installExistingPackage for user " + userId);
+        enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
+                + userId);
         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
         }
@@ -10961,7 +10981,7 @@
             final IPackageDataObserver observer, final int userId) {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "clear application data");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
         // Queue up an async operation since the package deletion may take a little while.
         mHandler.post(new Runnable() {
             public void run() {
@@ -10995,45 +11015,40 @@
             Slog.w(TAG, "Attempt to delete null packageName.");
             return false;
         }
+
+        // Try finding details about the requested package
         PackageParser.Package pkg;
-        boolean dataOnly = false;
-        final int appId;
         synchronized (mPackages) {
             pkg = mPackages.get(packageName);
             if (pkg == null) {
-                dataOnly = true;
-                PackageSetting ps = mSettings.mPackages.get(packageName);
-                if ((ps == null) || (ps.pkg == null)) {
-                    Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
-                    return false;
+                final PackageSetting ps = mSettings.mPackages.get(packageName);
+                if (ps != null) {
+                    pkg = ps.pkg;
                 }
-                pkg = ps.pkg;
-            }
-            if (!dataOnly) {
-                // need to check this only for fully installed applications
-                if (pkg == null) {
-                    Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
-                    return false;
-                }
-                final ApplicationInfo applicationInfo = pkg.applicationInfo;
-                if (applicationInfo == null) {
-                    Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
-                    return false;
-                }
-            }
-            if (pkg != null && pkg.applicationInfo != null) {
-                appId = pkg.applicationInfo.uid;
-            } else {
-                appId = -1;
             }
         }
+
+        if (pkg == null) {
+            Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
+        }
+
+        // Always delete data directories for package, even if we found no other
+        // record of app. This helps users recover from UID mismatches without
+        // resorting to a full data wipe.
         int retCode = mInstaller.clearUserData(packageName, userId);
         if (retCode < 0) {
-            Slog.w(TAG, "Couldn't remove cache files for package: "
-                    + packageName);
+            Slog.w(TAG, "Couldn't remove cache files for package: " + packageName);
             return false;
         }
-        removeKeystoreDataIfNeeded(userId, appId);
+
+        if (pkg == null) {
+            return false;
+        }
+
+        if (pkg != null && pkg.applicationInfo != null) {
+            final int appId = pkg.applicationInfo.uid;
+            removeKeystoreDataIfNeeded(userId, appId);
+        }
 
         // Create a native library symlink only if we have native libraries
         // and if the native libraries are 32 bit libraries. We do not provide
@@ -11261,7 +11276,7 @@
             String opname) {
         // writer
         int callingUid = Binder.getCallingUid();
-        enforceCrossUserPermission(callingUid, userId, true, "add preferred activity");
+        enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
         if (filter.countActions() == 0) {
             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
             return;
@@ -11306,7 +11321,7 @@
         }
 
         final int callingUid = Binder.getCallingUid();
-        enforceCrossUserPermission(callingUid, userId, true, "replace preferred activity");
+        enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
         synchronized (mPackages) {
             if (mContext.checkCallingOrSelfPermission(
                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
@@ -11447,6 +11462,7 @@
 
     @Override
     public void resetPreferredActivities(int userId) {
+        /* TODO: Actually use userId. Why is it being passed in? */
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
         // writer
@@ -11561,6 +11577,7 @@
                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
         int callingUid = Binder.getCallingUid();
         enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
+        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
         if (intentFilter.countActions() == 0) {
             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
             return;
@@ -11580,6 +11597,7 @@
                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
         int callingUid = Binder.getCallingUid();
         enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
+        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
         int callingUserId = UserHandle.getUserId(callingUid);
         synchronized (mPackages) {
             CrossProfileIntentResolver resolver =
@@ -11674,7 +11692,7 @@
         final int uid = Binder.getCallingUid();
         final int permission = mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
-        enforceCrossUserPermission(uid, userId, false, "set enabled");
+        enforceCrossUserPermission(uid, userId, false, true, "set enabled");
         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
         boolean sendNow = false;
         boolean isApp = (className == null);
@@ -11808,7 +11826,7 @@
         final int permission = mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
-        enforceCrossUserPermission(uid, userId, true, "stop package");
+        enforceCrossUserPermission(uid, userId, true, true, "stop package");
         // writer
         synchronized (mPackages) {
             if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
@@ -11830,7 +11848,7 @@
     public int getApplicationEnabledSetting(String packageName, int userId) {
         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
         int uid = Binder.getCallingUid();
-        enforceCrossUserPermission(uid, userId, false, "get enabled");
+        enforceCrossUserPermission(uid, userId, false, false, "get enabled");
         // reader
         synchronized (mPackages) {
             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
@@ -11841,7 +11859,7 @@
     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
         int uid = Binder.getCallingUid();
-        enforceCrossUserPermission(uid, userId, false, "get component enabled");
+        enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
         // reader
         synchronized (mPackages) {
             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index a74e3f1..0dadee7 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -36,6 +36,7 @@
 import android.os.PatternMatcher;
 import android.os.Process;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.util.LogPrinter;
 
 import com.android.internal.util.FastXmlSerializer;
@@ -463,6 +464,7 @@
             int vc, int pkgFlags, UserHandle installUser, boolean add,
             boolean allowInstall) {
         PackageSetting p = mPackages.get(name);
+        UserManagerService userManager = UserManagerService.getInstance();
         if (p != null) {
             p.primaryCpuAbiString = primaryCpuAbiString;
             p.secondaryCpuAbiString = secondaryCpuAbiString;
@@ -540,6 +542,7 @@
                         Slog.i(PackageManagerService.TAG, "Stopping package " + name, e);
                     }
                     List<UserInfo> users = getAllUsers();
+                    final int installUserId = installUser != null ? installUser.getIdentifier() : 0;
                     if (users != null && allowInstall) {
                         for (UserInfo user : users) {
                             // By default we consider this app to be installed
@@ -549,8 +552,9 @@
                             // asked to install for all users, or this is the
                             // user we are installing for.
                             final boolean installed = installUser == null
-                                    || installUser.getIdentifier() == UserHandle.USER_ALL
-                                    || installUser.getIdentifier() == user.id;
+                                    || (installUserId == UserHandle.USER_ALL
+                                        && !isAdbInstallDisallowed(userManager, user.id))
+                                    || installUserId == user.id;
                             p.setUserState(user.id, COMPONENT_ENABLED_STATE_DEFAULT,
                                     installed,
                                     true, // stopped,
@@ -616,7 +620,8 @@
                 List<UserInfo> users = getAllUsers();
                 if (users != null) {
                     for (UserInfo user : users) {
-                        if (installUser.getIdentifier() == UserHandle.USER_ALL
+                        if ((installUser.getIdentifier() == UserHandle.USER_ALL
+                                    && !isAdbInstallDisallowed(userManager, user.id))
                                 || installUser.getIdentifier() == user.id) {
                             boolean installed = p.getInstalled(user.id);
                             if (!installed) {
@@ -631,6 +636,11 @@
         return p;
     }
 
+    boolean isAdbInstallDisallowed(UserManagerService userManager, int userId) {
+        return userManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
+                userId);
+    }
+
     void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) {
         p.pkg = pkg;
         // pkg.mSetEnabled = p.getEnabled(userId);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index d032d29..26e0db3 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -33,6 +33,7 @@
 import android.graphics.BitmapFactory;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Debug;
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.Handler;
@@ -480,6 +481,14 @@
     }
 
     @Override
+    public boolean hasUserRestriction(String restrictionKey, int userId) {
+        synchronized (mPackagesLock) {
+            Bundle restrictions = mUserRestrictions.get(userId);
+            return restrictions != null ? restrictions.getBoolean(restrictionKey) : false;
+        }
+    }
+
+    @Override
     public Bundle getUserRestrictions(int userId) {
         // checkManageUsersPermission("getUserRestrictions");
 
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 7808800..0a4b3bc 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -814,7 +814,7 @@
                         + " [" + wakeLock.mTag + "], flags=0x" + Integer.toHexString(flags));
             }
 
-            if ((flags & PowerManager.WAIT_FOR_DISTANT_PROXIMITY) != 0) {
+            if ((flags & PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY) != 0) {
                 mRequestWaitForNegativeProximity = true;
             }
 
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index e1ade63..a8245e7 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -843,7 +843,7 @@
             }
             File file = new File(dir, WALLPAPER);
             ParcelFileDescriptor fd = ParcelFileDescriptor.open(file,
-                    MODE_CREATE|MODE_READ_WRITE);
+                    MODE_CREATE|MODE_READ_WRITE|MODE_TRUNCATE);
             if (!SELinux.restorecon(file)) {
                 return null;
             }
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 81cd602..da5cfda 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -252,6 +252,10 @@
         final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleNow() &&
                 (imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0;
 
+        final WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw();
+        final AppWindowToken appShowWhenLocked = winShowWhenLocked == null ?
+                null : winShowWhenLocked.mAppToken;
+
         for (int i = windows.size() - 1; i >= 0; i--) {
             WindowState win = windows.get(i);
             WindowStateAnimator winAnimator = win.mWinAnimator;
@@ -316,8 +320,8 @@
                             + " hidden=" + win.mRootToken.hidden
                             + " anim=" + win.mWinAnimator.mAnimation);
                 } else if (mPolicy.canBeForceHidden(win, win.mAttrs)) {
-                    final boolean hideWhenLocked = (flags & FLAG_SHOW_WHEN_LOCKED) == 0 &&
-                            !(win.mIsImWindow && showImeOverKeyguard);
+                    final boolean hideWhenLocked = !((win.mIsImWindow && showImeOverKeyguard) ||
+                            (appShowWhenLocked != null && appShowWhenLocked == win.mAppToken));
                     final boolean changed;
                     if (((mForceHiding == KEYGUARD_ANIMATING_IN)
                                 && (!winAnimator.isAnimating() || hideWhenLocked))
@@ -454,7 +458,10 @@
                     }
                     final int color = winAnimator.mAnimation.getBackgroundColor();
                     if (color != 0) {
-                        win.getStack().setAnimationBackground(winAnimator, color);
+                        final TaskStack stack = win.getStack();
+                        if (stack != null) {
+                            stack.setAnimationBackground(winAnimator, color);
+                        }
                     }
                 }
                 mAnimating = true;
@@ -473,7 +480,10 @@
 
                 final int color = appAnimator.animation.getBackgroundColor();
                 if (color != 0) {
-                    win.getStack().setAnimationBackground(winAnimator, color);
+                    final TaskStack stack = win.getStack();
+                    if (stack != null) {
+                        stack.setAnimationBackground(winAnimator, color);
+                    }
                 }
             }
         } // end forall windows
@@ -568,6 +578,15 @@
                         mBulkUpdateParams |= SET_UPDATE_ROTATION;
                         screenRotationAnimation.kill();
                         displayAnimator.mScreenRotationAnimation = null;
+
+                        //TODO (multidisplay): Accessibility supported only for the default display.
+                        if (mService.mAccessibilityController != null
+                                && displayId == Display.DEFAULT_DISPLAY) {
+                            // We just finished rotation animation which means we did not
+                            // anounce the rotation and waited for it to end, announce now.
+                            mService.mAccessibilityController.onRotationChangedLocked(
+                                    mService.getDefaultDisplayContentLocked(), mService.mRotation);
+                        }
                     }
                 }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 54af851..9033f30 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6442,9 +6442,12 @@
         }
 
         //TODO (multidisplay): Magnification is supported only for the default display.
-        if (mAccessibilityController != null
+        // Announce rotation only if we will not animate as we already have the
+        // windows in final state. Otherwise, we make this call at the rotation end.
+        if (screenRotationAnimation == null && mAccessibilityController != null
                 && displayContent.getDisplayId() == Display.DEFAULT_DISPLAY) {
-            mAccessibilityController.onRotationChangedLocked(getDefaultDisplayContentLocked(), rotation);
+            mAccessibilityController.onRotationChangedLocked(getDefaultDisplayContentLocked(),
+                    rotation);
         }
 
         return true;
@@ -8553,7 +8556,8 @@
                 layerChanged = true;
                 anyLayerChanged = true;
             }
-            if (layerChanged && w.getStack().isDimming(winAnimator)) {
+            final TaskStack stack = w.getStack();
+            if (layerChanged && stack != null && stack.isDimming(winAnimator)) {
                 // Force an animation pass just to update the mDimLayer layer.
                 scheduleAnimationLocked();
             }
@@ -9377,6 +9381,9 @@
                 && !w.mExiting) {
             final WindowStateAnimator winAnimator = w.mWinAnimator;
             final TaskStack stack = w.getStack();
+            if (stack == null) {
+                return;
+            }
             stack.setDimmingTag();
             if (!stack.isDimming(winAnimator)) {
                 if (localLOGV) Slog.v(TAG, "Win " + w + " start dimming.");
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index dd611ce..da97876 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1368,7 +1368,10 @@
                 mAnimator.setPendingLayoutChanges(w.getDisplayId(),
                         WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
                 if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {
-                    w.getStack().startDimmingIfNeeded(this);
+                    final TaskStack stack = w.getStack();
+                    if (stack != null) {
+                        stack.startDimmingIfNeeded(this);
+                    }
                 }
             } catch (RuntimeException e) {
                 // If something goes wrong with the surface (such
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 225465b..efaf253 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -45,13 +45,13 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
+import android.database.ContentObserver;
+import android.hardware.usb.UsbManager;
 import android.media.AudioManager;
 import android.media.IAudioService;
 import android.net.ConnectivityManager;
-import android.net.Uri;
-import android.database.ContentObserver;
-import android.hardware.usb.UsbManager;
 import android.net.ProxyInfo;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
@@ -70,6 +70,7 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.security.Credentials;
+import android.security.IKeyChainService;
 import android.security.KeyChain;
 import android.security.KeyChain.KeyChainConnection;
 import android.util.Log;
@@ -111,6 +112,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
@@ -2830,6 +2832,35 @@
         }
     }
 
+    @Override
+    public boolean installKeyPair(ComponentName who, byte[] privKey, byte[] cert, String alias) {
+        if (who == null) {
+            throw new NullPointerException("ComponentName is null");
+        }
+        synchronized (this) {
+            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+        }
+        final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
+        final long id = Binder.clearCallingIdentity();
+        try {
+          final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle);
+          try {
+              IKeyChainService keyChain = keyChainConnection.getService();
+              return keyChain.installKeyPair(privKey, cert, alias);
+          } catch (RemoteException e) {
+              Log.e(LOG_TAG, "Installing certificate", e);
+          } finally {
+              keyChainConnection.close();
+          }
+        } catch (InterruptedException e) {
+            Log.w(LOG_TAG, "Interrupted while installing certificate", e);
+            Thread.currentThread().interrupt();
+        } finally {
+            Binder.restoreCallingIdentity(id);
+        }
+        return false;
+    }
+
     void wipeDataLocked(int flags) {
         // If the SD card is encrypted and non-removable, we have to force a wipe.
         boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();
@@ -4623,7 +4654,8 @@
 
     @Override
     public void setUserRestriction(ComponentName who, String key, boolean enabled) {
-        final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
+        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
+        final int userHandle = user.getIdentifier();
         synchronized (this) {
             if (who == null) {
                 throw new NullPointerException("ComponentName is null");
@@ -4634,7 +4666,7 @@
             if (!isDeviceOwner && DEVICE_OWNER_USER_RESTRICTIONS.contains(key)) {
                 throw new SecurityException("Profile owners cannot set user restriction " + key);
             }
-            boolean alreadyRestricted = mUserManager.hasUserRestriction(key, userHandle);
+            boolean alreadyRestricted = mUserManager.hasUserRestriction(key, user);
 
             IAudioService iAudioService = null;
             if (UserManager.DISALLOW_UNMUTE_MICROPHONE.equals(key)
@@ -4660,7 +4692,7 @@
                     if (UserManager.DISALLOW_CONFIG_WIFI.equals(key)) {
                         Settings.Secure.putIntForUser(mContext.getContentResolver(),
                                 Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0,
-                                userHandle.getIdentifier());
+                                userHandle);
                     } else if (UserManager.DISALLOW_USB_FILE_TRANSFER.equals(key)) {
                         UsbManager manager =
                                 (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
@@ -4668,27 +4700,30 @@
                     } else if (UserManager.DISALLOW_SHARE_LOCATION.equals(key)) {
                         Settings.Secure.putIntForUser(mContext.getContentResolver(),
                                 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF,
-                                userHandle.getIdentifier());
+                                userHandle);
                         Settings.Secure.putStringForUser(mContext.getContentResolver(),
                                 Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "",
-                                userHandle.getIdentifier());
+                                userHandle);
                     } else if (UserManager.DISALLOW_DEBUGGING_FEATURES.equals(key)) {
-                        Settings.Global.putStringForUser(mContext.getContentResolver(),
-                                Settings.Global.ADB_ENABLED, "0", userHandle.getIdentifier());
+                        // Only disable adb if changing for primary user, since it is global
+                        if (userHandle == UserHandle.USER_OWNER) {
+                            Settings.Global.putStringForUser(mContext.getContentResolver(),
+                                    Settings.Global.ADB_ENABLED, "0", userHandle);
+                        }
                     } else if (UserManager.ENSURE_VERIFY_APPS.equals(key)) {
                         Settings.Global.putStringForUser(mContext.getContentResolver(),
                                 Settings.Global.PACKAGE_VERIFIER_ENABLE, "1",
-                                userHandle.getIdentifier());
+                                userHandle);
                         Settings.Global.putStringForUser(mContext.getContentResolver(),
                                 Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, "1",
-                                userHandle.getIdentifier());
+                                userHandle);
                     } else if (UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES.equals(key)) {
                         Settings.Secure.putIntForUser(mContext.getContentResolver(),
                                 Settings.Secure.INSTALL_NON_MARKET_APPS, 0,
-                                userHandle.getIdentifier());
+                                userHandle);
                     }
                 }
-                mUserManager.setUserRestriction(key, enabled, userHandle);
+                mUserManager.setUserRestriction(key, enabled, user);
             } finally {
                 restoreCallingIdentity(id);
             }
diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
index 62a7ec0..972c929 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
@@ -61,7 +61,7 @@
     /**
      * Initialize any directories required and index what stats are available.
      */
-    void init() {
+    public void init(long currentTimeMillis) {
         synchronized (mLock) {
             for (File f : mIntervalDirs) {
                 f.mkdirs();
@@ -72,27 +72,53 @@
             }
 
             checkVersionLocked();
+            indexFilesLocked();
 
-            final FilenameFilter backupFileFilter = new FilenameFilter() {
-                @Override
-                public boolean accept(File dir, String name) {
-                    return !name.endsWith(".bak");
+            // Delete files that are in the future.
+            for (TimeSparseArray<AtomicFile> files : mSortedStatFiles) {
+                final int startIndex = files.closestIndexOnOrAfter(currentTimeMillis);
+                if (startIndex < 0) {
+                    continue;
                 }
-            };
 
-            // Index the available usage stat files on disk.
-            for (int i = 0; i < mSortedStatFiles.length; i++) {
+                final int fileCount = files.size();
+                for (int i = startIndex; i < fileCount; i++) {
+                    files.valueAt(i).delete();
+                }
+
+                // Remove in a separate loop because any accesses (valueAt)
+                // will cause a gc in the SparseArray and mess up the order.
+                for (int i = startIndex; i < fileCount; i++) {
+                    files.removeAt(i);
+                }
+            }
+        }
+    }
+
+    private void indexFilesLocked() {
+        final FilenameFilter backupFileFilter = new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return !name.endsWith(".bak");
+            }
+        };
+
+        // Index the available usage stat files on disk.
+        for (int i = 0; i < mSortedStatFiles.length; i++) {
+            if (mSortedStatFiles[i] == null) {
                 mSortedStatFiles[i] = new TimeSparseArray<>();
-                File[] files = mIntervalDirs[i].listFiles(backupFileFilter);
-                if (files != null) {
-                    if (DEBUG) {
-                        Slog.d(TAG, "Found " + files.length + " stat files for interval " + i);
-                    }
+            } else {
+                mSortedStatFiles[i].clear();
+            }
+            File[] files = mIntervalDirs[i].listFiles(backupFileFilter);
+            if (files != null) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Found " + files.length + " stat files for interval " + i);
+                }
 
-                    for (File f : files) {
-                        final AtomicFile af = new AtomicFile(f);
-                        mSortedStatFiles[i].put(UsageStatsXml.parseBeginTime(af), af);
-                    }
+                for (File f : files) {
+                    final AtomicFile af = new AtomicFile(f);
+                    mSortedStatFiles[i].put(UsageStatsXml.parseBeginTime(af), af);
                 }
             }
         }
@@ -135,6 +161,38 @@
         }
     }
 
+    public void onTimeChanged(long timeDiffMillis) {
+        synchronized (mLock) {
+            for (TimeSparseArray<AtomicFile> files : mSortedStatFiles) {
+                final int fileCount = files.size();
+                for (int i = 0; i < fileCount; i++) {
+                    final AtomicFile file = files.valueAt(i);
+                    final long newTime = files.keyAt(i) + timeDiffMillis;
+                    if (newTime < 0) {
+                        Slog.i(TAG, "Deleting file " + file.getBaseFile().getAbsolutePath()
+                                + " for it is in the future now.");
+                        file.delete();
+                    } else {
+                        try {
+                            file.openRead().close();
+                        } catch (IOException e) {
+                            // Ignore, this is just to make sure there are no backups.
+                        }
+                        final File newFile = new File(file.getBaseFile().getParentFile(),
+                                Long.toString(newTime));
+                        Slog.i(TAG, "Moving file " + file.getBaseFile().getAbsolutePath() + " to "
+                                + newFile.getAbsolutePath());
+                        file.getBaseFile().renameTo(newFile);
+                    }
+                }
+                files.clear();
+            }
+
+            // Now re-index the new files.
+            indexFilesLocked();
+        }
+    }
+
     /**
      * Get the latest stats that exist for this interval type.
      */
@@ -296,25 +354,24 @@
     /**
      * Remove any usage stat files that are too old.
      */
-    public void prune() {
+    public void prune(final long currentTimeMillis) {
         synchronized (mLock) {
-            long timeNow = System.currentTimeMillis();
-            mCal.setTimeInMillis(timeNow);
+            mCal.setTimeInMillis(currentTimeMillis);
             mCal.addYears(-3);
             pruneFilesOlderThan(mIntervalDirs[UsageStatsManager.INTERVAL_YEARLY],
                     mCal.getTimeInMillis());
 
-            mCal.setTimeInMillis(timeNow);
+            mCal.setTimeInMillis(currentTimeMillis);
             mCal.addMonths(-6);
             pruneFilesOlderThan(mIntervalDirs[UsageStatsManager.INTERVAL_MONTHLY],
                     mCal.getTimeInMillis());
 
-            mCal.setTimeInMillis(timeNow);
+            mCal.setTimeInMillis(currentTimeMillis);
             mCal.addWeeks(-4);
             pruneFilesOlderThan(mIntervalDirs[UsageStatsManager.INTERVAL_WEEKLY],
                     mCal.getTimeInMillis());
 
-            mCal.setTimeInMillis(timeNow);
+            mCal.setTimeInMillis(currentTimeMillis);
             mCal.addDays(-7);
             pruneFilesOlderThan(mIntervalDirs[UsageStatsManager.INTERVAL_DAILY],
                     mCal.getTimeInMillis());
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 2dcdcc4..2ed9745 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -33,6 +33,7 @@
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.os.Binder;
+import android.os.Debug;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.Looper;
@@ -64,6 +65,7 @@
     private static final long TEN_SECONDS = 10 * 1000;
     private static final long TWENTY_MINUTES = 20 * 60 * 1000;
     private static final long FLUSH_INTERVAL = DEBUG ? TEN_SECONDS : TWENTY_MINUTES;
+    private static final long TIME_CHANGE_THRESHOLD_MILLIS = 2 * 1000; // Two seconds.
 
     // Handler message types.
     static final int MSG_REPORT_EVENT = 0;
@@ -170,18 +172,47 @@
         }
     }
 
-    private UserUsageStatsService getUserDataAndInitializeIfNeededLocked(int userId) {
+    private UserUsageStatsService getUserDataAndInitializeIfNeededLocked(int userId,
+            long currentTimeMillis) {
         UserUsageStatsService service = mUserState.get(userId);
         if (service == null) {
             service = new UserUsageStatsService(userId,
                     new File(mUsageStatsDir, Integer.toString(userId)), this);
-            service.init();
+            service.init(currentTimeMillis);
             mUserState.put(userId, service);
         }
         return service;
     }
 
     /**
+     * This should be the only way to get the time from the system.
+     */
+    private long checkAndGetTimeLocked() {
+        final long actualSystemTime = System.currentTimeMillis();
+        final long actualRealtime = SystemClock.elapsedRealtime();
+        final long expectedSystemTime = (actualRealtime - mRealTimeSnapshot) + mSystemTimeSnapshot;
+        if (Math.abs(actualSystemTime - expectedSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS) {
+            // The time has changed.
+            final int userCount = mUserState.size();
+            for (int i = 0; i < userCount; i++) {
+                final UserUsageStatsService service = mUserState.valueAt(i);
+                service.onTimeChanged(expectedSystemTime, actualSystemTime);
+            }
+            mRealTimeSnapshot = actualRealtime;
+            mSystemTimeSnapshot = actualSystemTime;
+        }
+        return actualSystemTime;
+    }
+
+    /**
+     * Assuming the event's timestamp is measured in milliseconds since boot,
+     * convert it to a system wall time.
+     */
+    private void convertToSystemTimeLocked(UsageEvents.Event event) {
+        event.mTimeStamp = Math.max(0, event.mTimeStamp - mRealTimeSnapshot) + mSystemTimeSnapshot;
+    }
+
+    /**
      * Called by the Binder stub
      */
     void shutdown() {
@@ -196,7 +227,11 @@
      */
     void reportEvent(UsageEvents.Event event, int userId) {
         synchronized (mLock) {
-            final UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId);
+            final long timeNow = checkAndGetTimeLocked();
+            convertToSystemTimeLocked(event);
+
+            final UserUsageStatsService service =
+                    getUserDataAndInitializeIfNeededLocked(userId, timeNow);
             service.reportEvent(event);
         }
     }
@@ -225,12 +260,14 @@
      * Called by the Binder stub.
      */
     List<UsageStats> queryUsageStats(int userId, int bucketType, long beginTime, long endTime) {
-        if (!validRange(beginTime, endTime)) {
-            return null;
-        }
-
         synchronized (mLock) {
-            UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId);
+            final long timeNow = checkAndGetTimeLocked();
+            if (!validRange(timeNow, beginTime, endTime)) {
+                return null;
+            }
+
+            final UserUsageStatsService service =
+                    getUserDataAndInitializeIfNeededLocked(userId, timeNow);
             return service.queryUsageStats(bucketType, beginTime, endTime);
         }
     }
@@ -240,12 +277,14 @@
      */
     List<ConfigurationStats> queryConfigurationStats(int userId, int bucketType, long beginTime,
             long endTime) {
-        if (!validRange(beginTime, endTime)) {
-            return null;
-        }
-
         synchronized (mLock) {
-            UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId);
+            final long timeNow = checkAndGetTimeLocked();
+            if (!validRange(timeNow, beginTime, endTime)) {
+                return null;
+            }
+
+            final UserUsageStatsService service =
+                    getUserDataAndInitializeIfNeededLocked(userId, timeNow);
             return service.queryConfigurationStats(bucketType, beginTime, endTime);
         }
     }
@@ -254,19 +293,20 @@
      * Called by the Binder stub.
      */
     UsageEvents queryEvents(int userId, long beginTime, long endTime) {
-        if (!validRange(beginTime, endTime)) {
-            return null;
-        }
-
         synchronized (mLock) {
-            UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId);
+            final long timeNow = checkAndGetTimeLocked();
+            if (!validRange(timeNow, beginTime, endTime)) {
+                return null;
+            }
+
+            final UserUsageStatsService service =
+                    getUserDataAndInitializeIfNeededLocked(userId, timeNow);
             return service.queryEvents(beginTime, endTime);
         }
     }
 
-    private static boolean validRange(long beginTime, long endTime) {
-        final long timeNow = System.currentTimeMillis();
-        return beginTime <= timeNow && beginTime < endTime;
+    private static boolean validRange(long currentTime, long beginTime, long endTime) {
+        return beginTime <= currentTime && beginTime < endTime;
     }
 
     private void flushToDiskLocked() {
@@ -386,14 +426,6 @@
      */
     private class LocalService extends UsageStatsManagerInternal {
 
-        /**
-         * The system may have its time change, so at least make sure the events
-         * are monotonic in order.
-         */
-        private long computeMonotonicSystemTime(long realTime) {
-            return (realTime - mRealTimeSnapshot) + mSystemTimeSnapshot;
-        }
-
         @Override
         public void reportEvent(ComponentName component, int userId, int eventType) {
             if (component == null) {
@@ -404,7 +436,10 @@
             UsageEvents.Event event = new UsageEvents.Event();
             event.mPackage = component.getPackageName();
             event.mClass = component.getClassName();
-            event.mTimeStamp = computeMonotonicSystemTime(SystemClock.elapsedRealtime());
+
+            // This will later be converted to system time.
+            event.mTimeStamp = SystemClock.elapsedRealtime();
+
             event.mEventType = eventType;
             mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
         }
@@ -418,7 +453,10 @@
 
             UsageEvents.Event event = new UsageEvents.Event();
             event.mPackage = "android";
-            event.mTimeStamp = computeMonotonicSystemTime(SystemClock.elapsedRealtime());
+
+            // This will later be converted to system time.
+            event.mTimeStamp = SystemClock.elapsedRealtime();
+
             event.mEventType = UsageEvents.Event.CONFIGURATION_CHANGE;
             event.mConfiguration = new Configuration(config);
             mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 2769666..4916ec2 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -22,6 +22,7 @@
 import android.app.usage.UsageStats;
 import android.app.usage.UsageStatsManager;
 import android.content.res.Configuration;
+import android.os.SystemClock;
 import android.util.ArraySet;
 import android.util.Slog;
 
@@ -62,10 +63,9 @@
         mLogPrefix = "User[" + Integer.toString(userId) + "] ";
     }
 
-    void init() {
-        mDatabase.init();
+    void init(final long currentTimeMillis) {
+        mDatabase.init(currentTimeMillis);
 
-        final long timeNow = System.currentTimeMillis();
         int nullCount = 0;
         for (int i = 0; i < mCurrentStats.length; i++) {
             mCurrentStats[i] = mDatabase.getLatestUsageStats(i);
@@ -73,11 +73,6 @@
                 // Find out how many intervals we don't have data for.
                 // Ideally it should be all or none.
                 nullCount++;
-            } else if (mCurrentStats[i].beginTime > timeNow) {
-                Slog.e(TAG, mLogPrefix + "Interval " + i + " has stat in the future " +
-                        mCurrentStats[i].beginTime);
-                mCurrentStats[i] = null;
-                nullCount++;
             }
         }
 
@@ -92,7 +87,7 @@
 
             // By calling loadActiveStats, we will
             // generate new stats for each bucket.
-            loadActiveStats();
+            loadActiveStats(currentTimeMillis, false);
         } else {
             // Set up the expiry date to be one day from the latest daily stat.
             // This may actually be today and we will rollover on the first event
@@ -123,6 +118,12 @@
         }
     }
 
+    void onTimeChanged(long oldTime, long newTime) {
+        persistActiveStats();
+        mDatabase.onTimeChanged(newTime - oldTime);
+        loadActiveStats(newTime, true);
+    }
+
     void reportEvent(UsageEvents.Event event) {
         if (DEBUG) {
             Slog.d(TAG, mLogPrefix + "Got usage event for " + event.mPackage
@@ -132,7 +133,7 @@
 
         if (event.mTimeStamp >= mDailyExpiryDate.getTimeInMillis()) {
             // Need to rollover
-            rolloverStats();
+            rolloverStats(event.mTimeStamp);
         }
 
         final IntervalStats currentDailyStats = mCurrentStats[UsageStatsManager.INTERVAL_DAILY];
@@ -330,8 +331,8 @@
         }
     }
 
-    private void rolloverStats() {
-        final long startTime = System.currentTimeMillis();
+    private void rolloverStats(final long currentTimeMillis) {
+        final long startTime = SystemClock.elapsedRealtime();
         Slog.i(TAG, mLogPrefix + "Rolling over usage stats");
 
         // Finish any ongoing events with an END_OF_DAY event. Make a note of which components
@@ -348,7 +349,7 @@
                     continuePreviousDay.add(pkgStats.mPackageName);
                     stat.update(pkgStats.mPackageName, mDailyExpiryDate.getTimeInMillis() - 1,
                             UsageEvents.Event.END_OF_DAY);
-                    mStatsChanged = true;
+                    notifyStatsChanged();
                 }
             }
 
@@ -356,8 +357,8 @@
         }
 
         persistActiveStats();
-        mDatabase.prune();
-        loadActiveStats();
+        mDatabase.prune(currentTimeMillis);
+        loadActiveStats(currentTimeMillis, false);
 
         final int continueCount = continuePreviousDay.size();
         for (int i = 0; i < continueCount; i++) {
@@ -366,12 +367,12 @@
             for (IntervalStats stat : mCurrentStats) {
                 stat.update(name, beginTime, UsageEvents.Event.CONTINUE_PREVIOUS_DAY);
                 stat.updateConfigurationStats(previousConfig, beginTime);
-                mStatsChanged = true;
+                notifyStatsChanged();
             }
         }
         persistActiveStats();
 
-        final long totalTime = System.currentTimeMillis() - startTime;
+        final long totalTime = SystemClock.elapsedRealtime() - startTime;
         Slog.i(TAG, mLogPrefix + "Rolling over usage stats complete. Took " + totalTime
                 + " milliseconds");
     }
@@ -383,15 +384,16 @@
         }
     }
 
-    private void loadActiveStats() {
-        final long timeNow = System.currentTimeMillis();
-
+    /**
+     * @param force To force all in-memory stats to be reloaded.
+     */
+    private void loadActiveStats(final long currentTimeMillis, boolean force) {
         final UnixCalendar tempCal = mDailyExpiryDate;
         for (int intervalType = 0; intervalType < mCurrentStats.length; intervalType++) {
-            tempCal.setTimeInMillis(timeNow);
+            tempCal.setTimeInMillis(currentTimeMillis);
             UnixCalendar.truncateTo(tempCal, intervalType);
 
-            if (mCurrentStats[intervalType] != null &&
+            if (!force && mCurrentStats[intervalType] != null &&
                     mCurrentStats[intervalType].beginTime == tempCal.getTimeInMillis()) {
                 // These are the same, no need to load them (in memory stats are always newer
                 // than persisted stats).
@@ -399,11 +401,7 @@
             }
 
             final long lastBeginTime = mDatabase.getLatestUsageStatsBeginTime(intervalType);
-            if (lastBeginTime > timeNow) {
-                Slog.e(TAG, mLogPrefix + "Latest usage stats for interval " +
-                        intervalType + " begins in the future");
-                mCurrentStats[intervalType] = null;
-            } else if (lastBeginTime >= tempCal.getTimeInMillis()) {
+            if (lastBeginTime >= tempCal.getTimeInMillis()) {
                 if (DEBUG) {
                     Slog.d(TAG, mLogPrefix + "Loading existing stats @ " +
                             sDateFormat.format(lastBeginTime) + "(" + lastBeginTime +
@@ -423,11 +421,11 @@
                 }
                 mCurrentStats[intervalType] = new IntervalStats();
                 mCurrentStats[intervalType].beginTime = tempCal.getTimeInMillis();
-                mCurrentStats[intervalType].endTime = timeNow;
+                mCurrentStats[intervalType].endTime = currentTimeMillis;
             }
         }
         mStatsChanged = false;
-        mDailyExpiryDate.setTimeInMillis(timeNow);
+        mDailyExpiryDate.setTimeInMillis(currentTimeMillis);
         mDailyExpiryDate.addDays(1);
         mDailyExpiryDate.truncateToDay();
         Slog.i(TAG, mLogPrefix + "Rollover scheduled @ " +
diff --git a/telecomm/java/android/telecomm/Call.java b/telecomm/java/android/telecomm/Call.java
index c3aa2a0..7ada9b1 100644
--- a/telecomm/java/android/telecomm/Call.java
+++ b/telecomm/java/android/telecomm/Call.java
@@ -108,7 +108,7 @@
 
         /**
          * @return The presentation requirements for the handle. See
-         * {@link PropertyPresentation} for valid values.
+         * {@link TelecommManager} for valid values.
          */
         public int getHandlePresentation() {
             return mHandlePresentation;
@@ -123,7 +123,7 @@
 
         /**
          * @return The presentation requirements for the caller display name. See
-         * {@link PropertyPresentation} for valid values.
+         * {@link TelecommManager} for valid values.
          */
         public int getCallerDisplayNamePresentation() {
             return mCallerDisplayNamePresentation;
@@ -482,13 +482,6 @@
     }
 
     /**
-     * Notifies this {@code Call} that the phone account user interface element was touched.
-     */
-    public void phoneAccountClicked() {
-        mInCallAdapter.phoneAccountClicked(mTelecommCallId);
-    }
-
-    /**
      * Notifies this {@code Call} that an account has been selected and to proceed with placing
      * an outgoing call.
      */
diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java
index 03db1c3..2f25dcf 100644
--- a/telecomm/java/android/telecomm/Connection.java
+++ b/telecomm/java/android/telecomm/Connection.java
@@ -68,13 +68,13 @@
     /** @hide */
     public abstract static class Listener {
         public void onStateChanged(Connection c, int state) {}
-        public void onHandleChanged(Connection c, Uri newHandle, int presentation) {}
+        public void onAddressChanged(Connection c, Uri newAddress, int presentation) {}
         public void onCallerDisplayNameChanged(
                 Connection c, String callerDisplayName, int presentation) {}
         public void onVideoStateChanged(Connection c, int videoState) {}
         public void onDisconnected(Connection c, int cause, String message) {}
         public void onPostDialWait(Connection c, String remaining) {}
-        public void onRequestingRingback(Connection c, boolean ringback) {}
+        public void onRingbackRequested(Connection c, boolean ringback) {}
         public void onDestroyed(Connection c) {}
         public void onCallCapabilitiesChanged(Connection c, int callCapabilities) {}
         public void onVideoProviderChanged(
@@ -464,11 +464,11 @@
 
     private int mState = STATE_NEW;
     private AudioState mAudioState;
-    private Uri mHandle;
-    private int mHandlePresentation;
+    private Uri mAddress;
+    private int mAddressPresentation;
     private String mCallerDisplayName;
     private int mCallerDisplayNamePresentation;
-    private boolean mRequestingRingback = false;
+    private boolean mRingbackRequested = false;
     private int mCallCapabilities;
     private VideoProvider mVideoProvider;
     private boolean mAudioModeIsVoip;
@@ -485,17 +485,18 @@
     public Connection() {}
 
     /**
-     * @return The handle (e.g., phone number) to which this Connection is currently communicating.
+     * @return The address (e.g., phone number) to which this Connection is currently communicating.
      */
-    public final Uri getHandle() {
-        return mHandle;
+    public final Uri getAddress() {
+        return mAddress;
     }
 
     /**
-     * @return The {@link PropertyPresentation} which controls how the handle is shown.
+     * @return The presentation requirements for the address.
+     *         See {@link TelecommManager} for valid values.
      */
-    public final int getHandlePresentation() {
-        return mHandlePresentation;
+    public final int getAddressPresentation() {
+        return mAddressPresentation;
     }
 
     /**
@@ -506,8 +507,8 @@
     }
 
     /**
-     * @return The {@link PropertyPresentation} which controls how the caller display name is
-     *         shown.
+     * @return The presentation requirements for the handle.
+     *         See {@link TelecommManager} for valid values.
      */
     public final int getCallerDisplayNamePresentation() {
         return mCallerDisplayNamePresentation;
@@ -555,8 +556,8 @@
      * Returns whether this connection is requesting that the system play a ringback tone
      * on its behalf.
      */
-    public final boolean isRequestingRingback() {
-        return mRequestingRingback;
+    public final boolean isRingbackRequested() {
+        return mRingbackRequested;
     }
 
     /**
@@ -624,7 +625,7 @@
     final void setAudioState(AudioState state) {
         Log.d(this, "setAudioState %s", state);
         mAudioState = state;
-        onSetAudioState(state);
+        onAudioStateChanged(state);
     }
 
     /**
@@ -661,18 +662,18 @@
     }
 
     /**
-     * Sets the value of the {@link #getHandle()} property.
+     * Sets the value of the {@link #getAddress()} property.
      *
-     * @param handle The new handle.
-     * @param presentation The {@link PropertyPresentation} which controls how the handle is
-     *         shown.
+     * @param address The new address.
+     * @param presentation The presentation requirements for the address.
+     *        See {@link TelecommManager} for valid values.
      */
-    public final void setHandle(Uri handle, int presentation) {
-        Log.d(this, "setHandle %s", handle);
-        mHandle = handle;
-        mHandlePresentation = presentation;
+    public final void setAddress(Uri address, int presentation) {
+        Log.d(this, "setAddress %s", address);
+        mAddress = address;
+        mAddressPresentation = presentation;
         for (Listener l : mListeners) {
-            l.onHandleChanged(this, handle, presentation);
+            l.onAddressChanged(this, address, presentation);
         }
     }
 
@@ -680,8 +681,8 @@
      * Sets the caller display name (CNAP).
      *
      * @param callerDisplayName The new display name.
-     * @param presentation The {@link PropertyPresentation} which controls how the name is
-     *         shown.
+     * @param presentation The presentation requirements for the handle.
+     *        See {@link TelecommManager} for valid values.
      */
     public final void setCallerDisplayName(String callerDisplayName, int presentation) {
         Log.d(this, "setCallerDisplayName %s", callerDisplayName);
@@ -715,7 +716,7 @@
      * communicate).
      */
     public final void setActive() {
-        setRequestingRingback(false);
+        setRingbackRequested(false);
         setState(STATE_ACTIVE);
     }
 
@@ -803,11 +804,11 @@
      *
      * @param ringback Whether the ringback tone is to be played.
      */
-    public final void setRequestingRingback(boolean ringback) {
-        if (mRequestingRingback != ringback) {
-            mRequestingRingback = ringback;
+    public final void setRingbackRequested(boolean ringback) {
+        if (mRingbackRequested != ringback) {
+            mRingbackRequested = ringback;
             for (Listener l : mListeners) {
-                l.onRequestingRingback(this, ringback);
+                l.onRingbackRequested(this, ringback);
             }
         }
     }
@@ -945,7 +946,7 @@
      *
      * @param state The new call audio state.
      */
-    public void onSetAudioState(AudioState state) {}
+    public void onAudioStateChanged(AudioState state) {}
 
     /**
      * Notifies this Connection of an internal state change. This method is called after the
@@ -953,7 +954,7 @@
      *
      * @param state The new state, one of the {@code STATE_*} constants.
      */
-    public void onSetState(int state) {}
+    public void onStateChanged(int state) {}
 
     /**
      * Notifies this Connection of a request to play a DTMF tone.
@@ -1021,11 +1022,6 @@
     public void onPostDialContinue(boolean proceed) {}
 
     /**
-     * Called when the phone account UI was clicked.
-     */
-    public void onPhoneAccountClicked() {}
-
-    /**
      * Merge this connection and the specified connection into a conference call.  Once the
      * connections are merged, the calls should be added to the an existing or new
      * {@code Conference} instance. For new {@code Conference} instances, use
@@ -1068,7 +1064,7 @@
         if (mState != state) {
             Log.d(this, "setState: %s", stateToString(state));
             mState = state;
-            onSetState(state);
+            onStateChanged(state);
             for (Listener l : mListeners) {
                 l.onStateChanged(this, state);
             }
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index 39365b6..05ddc27 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -69,7 +69,6 @@
     private static final int MSG_CONFERENCE = 12;
     private static final int MSG_SPLIT_FROM_CONFERENCE = 13;
     private static final int MSG_ON_POST_DIAL_CONTINUE = 14;
-    private static final int MSG_ON_PHONE_ACCOUNT_CLICKED = 15;
     private static final int MSG_REMOVE_CONNECTION_SERVICE_ADAPTER = 16;
     private static final int MSG_ANSWER_VIDEO = 17;
     private static final int MSG_MERGE_CONFERENCE = 18;
@@ -200,11 +199,6 @@
             args.argi1 = proceed ? 1 : 0;
             mHandler.obtainMessage(MSG_ON_POST_DIAL_CONTINUE, args).sendToTarget();
         }
-
-        @Override
-        public void onPhoneAccountClicked(String callId) {
-            mHandler.obtainMessage(MSG_ON_PHONE_ACCOUNT_CLICKED, callId).sendToTarget();
-        }
     };
 
     private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@@ -327,9 +321,6 @@
                     }
                     break;
                 }
-                case MSG_ON_PHONE_ACCOUNT_CLICKED:
-                    onPhoneAccountHandleClicked((String) msg.obj);
-                    break;
                 default:
                     break;
             }
@@ -423,9 +414,9 @@
         }
 
         @Override
-        public void onHandleChanged(Connection c, Uri handle, int presentation) {
+        public void onAddressChanged(Connection c, Uri address, int presentation) {
             String id = mIdByConnection.get(c);
-            mAdapter.setHandle(id, handle, presentation);
+            mAdapter.setAddress(id, address, presentation);
         }
 
         @Override
@@ -448,10 +439,10 @@
         }
 
         @Override
-        public void onRequestingRingback(Connection c, boolean ringback) {
+        public void onRingbackRequested(Connection c, boolean ringback) {
             String id = mIdByConnection.get(c);
             Log.d(this, "Adapter onRingback %b", ringback);
-            mAdapter.setRequestingRingback(id, ringback);
+            mAdapter.setRingbackRequested(id, ringback);
         }
 
         @Override
@@ -471,7 +462,7 @@
         @Override
         public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {
             String id = mIdByConnection.get(c);
-            mAdapter.setAudioModeIsVoip(id, isVoip);
+            mAdapter.setIsVoipAudioMode(id, isVoip);
         }
 
         @Override
@@ -507,6 +498,13 @@
         return mBinder;
     }
 
+    /** {@inheritDoc} */
+    @Override
+    public boolean onUnbind(Intent intent) {
+        endAllConnections();
+        return super.onUnbind(intent);
+    }
+
     /**
      * This can be used by telecomm to either create a new outgoing call or attach to an existing
      * incoming call. In either case, telecomm will cycle through a set of services and call
@@ -532,8 +530,8 @@
             addConnection(callId, connection);
         }
 
-        Uri handle = connection.getHandle();
-        String number = handle == null ? "null" : handle.getSchemeSpecificPart();
+        Uri address = connection.getAddress();
+        String number = address == null ? "null" : address.getSchemeSpecificPart();
         Log.v(this, "createConnection, number: %s, state: %s, capabilities: %s",
                 Connection.toLogSafePhoneNumber(number),
                 Connection.stateToString(connection.getState()),
@@ -547,14 +545,14 @@
                         request.getAccountHandle(),
                         connection.getState(),
                         connection.getCallCapabilities(),
-                        connection.getHandle(),
-                        connection.getHandlePresentation(),
+                        connection.getAddress(),
+                        connection.getAddressPresentation(),
                         connection.getCallerDisplayName(),
                         connection.getCallerDisplayNamePresentation(),
                         connection.getVideoProvider() == null ?
                                 null : connection.getVideoProvider().getInterface(),
                         connection.getVideoState(),
-                        connection.isRequestingRingback(),
+                        connection.isRingbackRequested(),
                         connection.getAudioModeIsVoip(),
                         connection.getStatusHints(),
                         connection.getDisconnectCause(),
@@ -678,11 +676,6 @@
         findConnectionForAction(callId, "stopDtmfTone").onPostDialContinue(proceed);
     }
 
-    private void onPhoneAccountHandleClicked(String callId) {
-        Log.d(this, "onPhoneAccountClicked %s", callId);
-        findConnectionForAction(callId, "onPhoneAccountClicked").onPhoneAccountClicked();
-    }
-
     private void onAdapterAttached() {
         if (mAreAccountsInitialized) {
             // No need to query again if we already did it.
@@ -965,4 +958,17 @@
         }
         return sNullConference;
     }
+
+    private void endAllConnections() {
+        // Unbound from telecomm.  We should end all connections and conferences.
+        for (Connection connection : mIdByConnection.keySet()) {
+            // only operate on top-level calls. Conference calls will be removed on their own.
+            if (connection.getConference() == null) {
+                connection.onDisconnect();
+            }
+        }
+        for (Conference conference : mIdByConference.keySet()) {
+            conference.onDisconnect();
+        }
+    }
 }
diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
index e3dc713..19f42d6 100644
--- a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
@@ -168,10 +168,10 @@
      * @param callId The unique ID of the call whose ringback is being changed.
      * @param ringback Whether Telecomm should start playing a ringback tone.
      */
-    void setRequestingRingback(String callId, boolean ringback) {
+    void setRingbackRequested(String callId, boolean ringback) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setRequestingRingback(callId, ringback);
+                adapter.setRingbackRequested(callId, ringback);
             } catch (RemoteException e) {
             }
         }
@@ -280,10 +280,10 @@
      * @param callId The unique ID of the call to set with the given call video provider.
      * @param isVoip True if the audio mode is VOIP.
      */
-    void setAudioModeIsVoip(String callId, boolean isVoip) {
+    void setIsVoipAudioMode(String callId, boolean isVoip) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setAudioModeIsVoip(callId, isVoip);
+                adapter.setIsVoipAudioMode(callId, isVoip);
             } catch (RemoteException e) {
             }
         }
@@ -298,10 +298,10 @@
         }
     }
 
-    void setHandle(String callId, Uri handle, int presentation) {
+    void setAddress(String callId, Uri address, int presentation) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setHandle(callId, handle, presentation);
+                adapter.setAddress(callId, address, presentation);
             } catch (RemoteException e) {
             }
         }
diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java
index 21e99db..2aac7fc 100644
--- a/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java
@@ -44,7 +44,7 @@
     private static final int MSG_SET_DIALING = 4;
     private static final int MSG_SET_DISCONNECTED = 5;
     private static final int MSG_SET_ON_HOLD = 6;
-    private static final int MSG_SET_REQUESTING_RINGBACK = 7;
+    private static final int MSG_SET_RINGBACK_REQUESTED = 7;
     private static final int MSG_SET_CALL_CAPABILITIES = 8;
     private static final int MSG_SET_IS_CONFERENCED = 9;
     private static final int MSG_ADD_CONFERENCE_CALL = 10;
@@ -53,9 +53,9 @@
     private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 13;
     private static final int MSG_SET_VIDEO_STATE = 14;
     private static final int MSG_SET_VIDEO_CALL_PROVIDER = 15;
-    private static final int MSG_SET_AUDIO_MODE_IS_VOIP = 16;
+    private static final int MSG_SET_IS_VOIP_AUDIO_MODE = 16;
     private static final int MSG_SET_STATUS_HINTS = 17;
-    private static final int MSG_SET_HANDLE = 18;
+    private static final int MSG_SET_ADDRESS = 18;
     private static final int MSG_SET_CALLER_DISPLAY_NAME = 19;
     private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 20;
 
@@ -107,8 +107,8 @@
                 case MSG_SET_ON_HOLD:
                     mDelegate.setOnHold((String) msg.obj);
                     break;
-                case MSG_SET_REQUESTING_RINGBACK:
-                    mDelegate.setRequestingRingback((String) msg.obj, msg.arg1 == 1);
+                case MSG_SET_RINGBACK_REQUESTED:
+                    mDelegate.setRingbackRequested((String) msg.obj, msg.arg1 == 1);
                     break;
                 case MSG_SET_CALL_CAPABILITIES:
                     mDelegate.setCallCapabilities((String) msg.obj, msg.arg1);
@@ -160,8 +160,8 @@
                     }
                     break;
                 }
-                case MSG_SET_AUDIO_MODE_IS_VOIP:
-                    mDelegate.setAudioModeIsVoip((String) msg.obj, msg.arg1 == 1);
+                case MSG_SET_IS_VOIP_AUDIO_MODE:
+                    mDelegate.setIsVoipAudioMode((String) msg.obj, msg.arg1 == 1);
                     break;
                 case MSG_SET_STATUS_HINTS: {
                     SomeArgs args = (SomeArgs) msg.obj;
@@ -172,10 +172,10 @@
                     }
                     break;
                 }
-                case MSG_SET_HANDLE: {
+                case MSG_SET_ADDRESS: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.setHandle((String) args.arg1, (Uri) args.arg2, args.argi1);
+                        mDelegate.setAddress((String) args.arg1, (Uri) args.arg2, args.argi1);
                     } finally {
                         args.recycle();
                     }
@@ -249,8 +249,8 @@
         }
 
         @Override
-        public void setRequestingRingback(String connectionId, boolean ringback) {
-            mHandler.obtainMessage(MSG_SET_REQUESTING_RINGBACK, ringback ? 1 : 0, 0, connectionId)
+        public void setRingbackRequested(String connectionId, boolean ringback) {
+            mHandler.obtainMessage(MSG_SET_RINGBACK_REQUESTED, ringback ? 1 : 0, 0, connectionId)
                     .sendToTarget();
         }
 
@@ -308,8 +308,8 @@
         }
 
         @Override
-        public final void setAudioModeIsVoip(String connectionId, boolean isVoip) {
-            mHandler.obtainMessage(MSG_SET_AUDIO_MODE_IS_VOIP, isVoip ? 1 : 0, 0,
+        public final void setIsVoipAudioMode(String connectionId, boolean isVoip) {
+            mHandler.obtainMessage(MSG_SET_IS_VOIP_AUDIO_MODE, isVoip ? 1 : 0, 0,
                     connectionId).sendToTarget();
         }
 
@@ -322,12 +322,12 @@
         }
 
         @Override
-        public final void setHandle(String connectionId, Uri handle, int presentation) {
+        public final void setAddress(String connectionId, Uri address, int presentation) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
-            args.arg2 = handle;
+            args.arg2 = address;
             args.argi1 = presentation;
-            mHandler.obtainMessage(MSG_SET_HANDLE, args).sendToTarget();
+            mHandler.obtainMessage(MSG_SET_ADDRESS, args).sendToTarget();
         }
 
         @Override
diff --git a/telecomm/java/android/telecomm/GatewayInfo.java b/telecomm/java/android/telecomm/GatewayInfo.java
index b95e6b6..a720284 100644
--- a/telecomm/java/android/telecomm/GatewayInfo.java
+++ b/telecomm/java/android/telecomm/GatewayInfo.java
@@ -16,6 +16,7 @@
 
 package android.telecomm;
 
+import android.annotation.SystemApi;
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -33,14 +34,15 @@
 public class GatewayInfo implements Parcelable {
 
     private final String mGatewayProviderPackageName;
-    private final Uri mGatewayHandle;
-    private final Uri mOriginalHandle;
+    private final Uri mGatewayAddress;
+    private final Uri mOriginalAddress;
 
     /** @hide */
-    public GatewayInfo(String packageName, Uri gatewayUri, Uri originalHandle) {
+    @SystemApi
+    public GatewayInfo(String packageName, Uri gatewayUri, Uri originalAddress) {
         mGatewayProviderPackageName = packageName;
-        mGatewayHandle = gatewayUri;
-        mOriginalHandle = originalHandle;
+        mGatewayAddress = gatewayUri;
+        mOriginalAddress = originalAddress;
     }
 
     /**
@@ -51,21 +53,21 @@
     }
 
     /**
-     * Gateway provider handle to use when actually placing the call.
+     * Gateway provider address to use when actually placing the call.
      */
-    public Uri getGatewayHandle() {
-        return mGatewayHandle;
+    public Uri getGatewayAddress() {
+        return mGatewayAddress;
     }
 
     /**
-     * The actual call handle that the user is trying to connect to via the gateway.
+     * The actual call address that the user is trying to connect to via the gateway.
      */
-    public Uri getOriginalHandle() {
-        return mOriginalHandle;
+    public Uri getOriginalAddress() {
+        return mOriginalAddress;
     }
 
     public boolean isEmpty() {
-        return TextUtils.isEmpty(mGatewayProviderPackageName) || mGatewayHandle == null;
+        return TextUtils.isEmpty(mGatewayProviderPackageName) || mGatewayAddress == null;
     }
 
     /** Implement the Parcelable interface */
@@ -76,8 +78,8 @@
         public GatewayInfo createFromParcel(Parcel source) {
             String gatewayPackageName = source.readString();
             Uri gatewayUri = Uri.CREATOR.createFromParcel(source);
-            Uri originalHandle = Uri.CREATOR.createFromParcel(source);
-            return new GatewayInfo(gatewayPackageName, gatewayUri, originalHandle);
+            Uri originalAddress = Uri.CREATOR.createFromParcel(source);
+            return new GatewayInfo(gatewayPackageName, gatewayUri, originalAddress);
         }
 
         @Override
@@ -100,7 +102,7 @@
     @Override
     public void writeToParcel(Parcel destination, int flags) {
         destination.writeString(mGatewayProviderPackageName);
-        mGatewayHandle.writeToParcel(destination, 0);
-        mOriginalHandle.writeToParcel(destination, 0);
+        mGatewayAddress.writeToParcel(destination, 0);
+        mOriginalAddress.writeToParcel(destination, 0);
     }
 }
diff --git a/telecomm/java/android/telecomm/InCallAdapter.java b/telecomm/java/android/telecomm/InCallAdapter.java
index 96ea5a6..899f35e 100644
--- a/telecomm/java/android/telecomm/InCallAdapter.java
+++ b/telecomm/java/android/telecomm/InCallAdapter.java
@@ -189,18 +189,6 @@
     }
 
     /**
-     * Instructs Telecomm that the phone account UI was clicked.
-     *
-     * @param callId The identifier of the call.
-     */
-    public void phoneAccountClicked(String callId) {
-        try {
-            mAdapter.phoneAccountClicked(callId);
-        } catch (RemoteException e) {
-        }
-    }
-
-    /**
      * Instructs Telecomm to add a PhoneAccountHandle to the specified call
      *
      * @param callId The identifier of the call
diff --git a/telecomm/java/android/telecomm/ParcelableCall.java b/telecomm/java/android/telecomm/ParcelableCall.java
index a2aa192..f7fc125 100644
--- a/telecomm/java/android/telecomm/ParcelableCall.java
+++ b/telecomm/java/android/telecomm/ParcelableCall.java
@@ -153,7 +153,9 @@
         return mHandle;
     }
 
-    /** The {@link PropertyPresentation} which controls how the handle is shown. */
+    /**
+     * The presentation requirements for the handle. See {@link TelecommManager} for valid values.
+     */
     public int getHandlePresentation() {
         return mHandlePresentation;
     }
@@ -163,7 +165,10 @@
         return mCallerDisplayName;
     }
 
-    /** The {@link PropertyPresentation} which controls how the caller display name is shown. */
+    /**
+     * The presentation requirements for the caller display name.
+     * See {@link TelecommManager} for valid values.
+     */
     public int getCallerDisplayNamePresentation() {
         return mCallerDisplayNamePresentation;
     }
diff --git a/telecomm/java/android/telecomm/ParcelableConnection.java b/telecomm/java/android/telecomm/ParcelableConnection.java
index 2e21d37..cadcd85 100644
--- a/telecomm/java/android/telecomm/ParcelableConnection.java
+++ b/telecomm/java/android/telecomm/ParcelableConnection.java
@@ -35,14 +35,14 @@
     private final PhoneAccountHandle mPhoneAccount;
     private final int mState;
     private final int mCapabilities;
-    private final Uri mHandle;
-    private final int mHandlePresentation;
+    private final Uri mAddress;
+    private final int mAddressPresentation;
     private final String mCallerDisplayName;
     private final int mCallerDisplayNamePresentation;
     private final IVideoProvider mVideoProvider;
     private final int mVideoState;
-    private final boolean mRequestingRingback;
-    private final boolean mAudioModeIsVoip;
+    private final boolean mRingbackRequested;
+    private final boolean mIsVoipAudioMode;
     private final StatusHints mStatusHints;
     private final int mDisconnectCause;
     private final String mDisconnectMessage;
@@ -53,14 +53,14 @@
             PhoneAccountHandle phoneAccount,
             int state,
             int capabilities,
-            Uri handle,
-            int handlePresentation,
+            Uri address,
+            int addressPresentation,
             String callerDisplayName,
             int callerDisplayNamePresentation,
             IVideoProvider videoProvider,
             int videoState,
-            boolean requestingRingback,
-            boolean audioModeIsVoip,
+            boolean ringbackRequested,
+            boolean isVoipAudioMode,
             StatusHints statusHints,
             int disconnectCause,
             String disconnectMessage,
@@ -68,14 +68,14 @@
         mPhoneAccount = phoneAccount;
         mState = state;
         mCapabilities = capabilities;
-        mHandle = handle;
-        mHandlePresentation = handlePresentation;
+        mAddress = address;
+        mAddressPresentation = addressPresentation;
         mCallerDisplayName = callerDisplayName;
         mCallerDisplayNamePresentation = callerDisplayNamePresentation;
         mVideoProvider = videoProvider;
         mVideoState = videoState;
-        mRequestingRingback = requestingRingback;
-        mAudioModeIsVoip = audioModeIsVoip;
+        mRingbackRequested = ringbackRequested;
+        mIsVoipAudioMode = isVoipAudioMode;
         mStatusHints = statusHints;
         mDisconnectCause = disconnectCause;
         mDisconnectMessage = disconnectMessage;
@@ -96,11 +96,11 @@
     }
 
     public Uri getHandle() {
-        return mHandle;
+        return mAddress;
     }
 
     public int getHandlePresentation() {
-        return mHandlePresentation;
+        return mAddressPresentation;
     }
 
     public String getCallerDisplayName() {
@@ -119,12 +119,12 @@
         return mVideoState;
     }
 
-    public boolean isRequestingRingback() {
-        return mRequestingRingback;
+    public boolean isRingbackRequested() {
+        return mRingbackRequested;
     }
 
-    public boolean getAudioModeIsVoip() {
-        return mAudioModeIsVoip;
+    public boolean getIsVoipAudioMode() {
+        return mIsVoipAudioMode;
     }
 
     public final StatusHints getStatusHints() {
@@ -164,14 +164,14 @@
             PhoneAccountHandle phoneAccount = source.readParcelable(classLoader);
             int state = source.readInt();
             int capabilities = source.readInt();
-            Uri handle = source.readParcelable(classLoader);
-            int handlePresentation = source.readInt();
+            Uri address = source.readParcelable(classLoader);
+            int addressPresentation = source.readInt();
             String callerDisplayName = source.readString();
             int callerDisplayNamePresentation = source.readInt();
             IVideoProvider videoCallProvider =
                     IVideoProvider.Stub.asInterface(source.readStrongBinder());
             int videoState = source.readInt();
-            boolean requestingRingback = source.readByte() == 1;
+            boolean ringbackRequested = source.readByte() == 1;
             boolean audioModeIsVoip = source.readByte() == 1;
             StatusHints statusHints = source.readParcelable(classLoader);
             int disconnectCauseCode = source.readInt();
@@ -183,13 +183,13 @@
                     phoneAccount,
                     state,
                     capabilities,
-                    handle,
-                    handlePresentation,
+                    address,
+                    addressPresentation,
                     callerDisplayName,
                     callerDisplayNamePresentation,
                     videoCallProvider,
                     videoState,
-                    requestingRingback,
+                    ringbackRequested,
                     audioModeIsVoip,
                     statusHints,
                     disconnectCauseCode,
@@ -215,15 +215,15 @@
         destination.writeParcelable(mPhoneAccount, 0);
         destination.writeInt(mState);
         destination.writeInt(mCapabilities);
-        destination.writeParcelable(mHandle, 0);
-        destination.writeInt(mHandlePresentation);
+        destination.writeParcelable(mAddress, 0);
+        destination.writeInt(mAddressPresentation);
         destination.writeString(mCallerDisplayName);
         destination.writeInt(mCallerDisplayNamePresentation);
         destination.writeStrongBinder(
                 mVideoProvider != null ? mVideoProvider.asBinder() : null);
         destination.writeInt(mVideoState);
-        destination.writeByte((byte) (mRequestingRingback ? 1 : 0));
-        destination.writeByte((byte) (mAudioModeIsVoip ? 1 : 0));
+        destination.writeByte((byte) (mRingbackRequested ? 1 : 0));
+        destination.writeByte((byte) (mIsVoipAudioMode ? 1 : 0));
         destination.writeParcelable(mStatusHints, 0);
         destination.writeInt(mDisconnectCause);
         destination.writeString(mDisconnectMessage);
diff --git a/telecomm/java/android/telecomm/PhoneAccount.java b/telecomm/java/android/telecomm/PhoneAccount.java
index f709a86..b37c144 100644
--- a/telecomm/java/android/telecomm/PhoneAccount.java
+++ b/telecomm/java/android/telecomm/PhoneAccount.java
@@ -83,6 +83,25 @@
     public static final int CAPABILITY_VIDEO_CALLING = 0x8;
 
     /**
+     * Flag indicating that this {@code PhoneAccount} is capable of placing emergency calls.
+     * By default all PSTN {@code PhoneAccount}s are capable of placing emergency calls.
+     * <p>
+     * See {@link #getCapabilities}
+     */
+    public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 0x10;
+
+    /**
+     * Flag indicating that this {@code PhoneAccount} is always enabled and cannot be disabled by
+     * the user.
+     * This capability is reserved for important {@code PhoneAccount}s such as the emergency calling
+     * only {@code PhoneAccount}.
+     * <p>
+     * See {@link #getCapabilities}
+     * @hide
+     */
+    public static final int CAPABILITY_ALWAYS_ENABLED = 0x20;
+
+    /**
      * URI scheme for telephone number URIs.
      */
     public static final String SCHEME_TEL = "tel";
@@ -105,6 +124,7 @@
     private final CharSequence mLabel;
     private final CharSequence mShortDescription;
     private final List<String> mSupportedUriSchemes;
+    private final boolean mIsEnabled;
 
     public static class Builder {
         private PhoneAccountHandle mAccountHandle;
@@ -115,12 +135,31 @@
         private CharSequence mLabel;
         private CharSequence mShortDescription;
         private List<String> mSupportedUriSchemes = new ArrayList<String>();
+        private boolean mIsEnabled = false;
 
         public Builder(PhoneAccountHandle accountHandle, CharSequence label) {
             this.mAccountHandle = accountHandle;
             this.mLabel = label;
         }
 
+        /**
+         * Creates an instance of the {@link PhoneAccount.Builder} from an existing
+         * {@link PhoneAccount}.
+         *
+         * @param phoneAccount The {@link PhoneAccount} used to initialize the builder.
+         */
+        public Builder(PhoneAccount phoneAccount) {
+            mAccountHandle = phoneAccount.getAccountHandle();
+            mAddress = phoneAccount.getAddress();
+            mSubscriptionAddress = phoneAccount.getSubscriptionAddress();
+            mCapabilities = phoneAccount.getCapabilities();
+            mIconResId = phoneAccount.getIconResId();
+            mLabel = phoneAccount.getLabel();
+            mShortDescription = phoneAccount.getShortDescription();
+            mSupportedUriSchemes.addAll(phoneAccount.getSupportedUriSchemes());
+            mIsEnabled = phoneAccount.isEnabled();
+        }
+
         public Builder setAddress(Uri value) {
             this.mAddress = value;
             return this;
@@ -177,6 +216,24 @@
             return this;
         }
 
+        /**
+         * Specifies whether the {@link PhoneAccount} is enabled or not.  {@link PhoneAccount}s are
+         * by default not enabled.
+         *
+         * @param value {@code True} if the {@link PhoneAccount} is enabled.
+         * @return The Builder.
+         * @hide
+         */
+        public Builder setEnabled(boolean value) {
+            this.mIsEnabled = value;
+            return this;
+        }
+
+        /**
+         * Creates an instance of a {@link PhoneAccount} based on the current builder settings.
+         *
+         * @return The {@link PhoneAccount}.
+         */
         public PhoneAccount build() {
             // If no supported URI schemes were defined, assume "tel" is supported.
             if (mSupportedUriSchemes.isEmpty()) {
@@ -191,7 +248,8 @@
                     mIconResId,
                     mLabel,
                     mShortDescription,
-                    mSupportedUriSchemes);
+                    mSupportedUriSchemes,
+                    mIsEnabled);
         }
     }
 
@@ -203,7 +261,8 @@
             int iconResId,
             CharSequence label,
             CharSequence shortDescription,
-            List<String> supportedUriSchemes) {
+            List<String> supportedUriSchemes,
+            boolean enabled) {
         mAccountHandle = account;
         mAddress = address;
         mSubscriptionAddress = subscriptionAddress;
@@ -212,6 +271,7 @@
         mLabel = label;
         mShortDescription = shortDescription;
         mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes);
+        mIsEnabled = enabled;
     }
 
     public static Builder builder(
@@ -221,6 +281,14 @@
     }
 
     /**
+     * Returns a builder initialized with the current {@link PhoneAccount} instance.
+     *
+     * @return The builder.
+     * @hide
+     */
+    public Builder toBuilder() { return new Builder(this); }
+
+    /**
      * The unique identifier of this {@code PhoneAccount}.
      *
      * @return A {@code PhoneAccountHandle}.
@@ -265,6 +333,17 @@
     }
 
     /**
+     * Determines if this {@code PhoneAccount} has a capabilities specified by the passed in
+     * bit mask.
+     *
+     * @param capability The capabilities to check.
+     * @return {@code True} if the phone account has the capability.
+     */
+    public boolean hasCapabilities(int capability) {
+        return (mCapabilities & capability) == capability;
+    }
+
+    /**
      * A short label describing a {@code PhoneAccount}.
      *
      * @return A label for this {@code PhoneAccount}.
@@ -313,6 +392,15 @@
     }
 
     /**
+     * Determines whether this {@code PhoneAccount} is enabled.
+     *
+     * @return {@code True} if this {@code PhoneAccount} is enabled..
+     */
+    public boolean isEnabled() {
+        return mIsEnabled;
+    }
+
+    /**
      * The icon resource ID for the icon of this {@code PhoneAccount}.
      *
      * @return A resource ID.
@@ -367,6 +455,7 @@
         out.writeCharSequence(mLabel);
         out.writeCharSequence(mShortDescription);
         out.writeList(mSupportedUriSchemes);
+        out.writeInt(mIsEnabled ? 1 : 0);
     }
 
     public static final Creator<PhoneAccount> CREATOR
@@ -396,5 +485,6 @@
         List<String> supportedUriSchemes = new ArrayList<>();
         in.readList(supportedUriSchemes, classLoader);
         mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes);
+        mIsEnabled = in.readInt() == 1;
     }
 }
diff --git a/telecomm/java/android/telecomm/PhoneCapabilities.java b/telecomm/java/android/telecomm/PhoneCapabilities.java
index 7a338b4..ec11376 100644
--- a/telecomm/java/android/telecomm/PhoneCapabilities.java
+++ b/telecomm/java/android/telecomm/PhoneCapabilities.java
@@ -78,8 +78,19 @@
      */
     public static final int VoWIFI = 0x00000800;
 
-    public static final int ALL = HOLD | SUPPORT_HOLD | MERGE_CONFERENCE | SWAP_CONFERENCE | ADD_CALL
-            | RESPOND_VIA_TEXT | MUTE | MANAGE_CONFERENCE;
+    /**
+     * Call is able to be separated from its parent {@code Conference}, if any.
+     */
+    public static final int SEPARATE_FROM_CONFERENCE = 0x00001000;
+
+    /**
+     * Call is able to be individually disconnected when in a {@code Conference}.
+     */
+    public static final int DISCONNECT_FROM_CONFERENCE = 0x00002000;
+
+    public static final int ALL = HOLD | SUPPORT_HOLD | MERGE_CONFERENCE | SWAP_CONFERENCE
+            | ADD_CALL | RESPOND_VIA_TEXT | MUTE | MANAGE_CONFERENCE | SEPARATE_FROM_CONFERENCE
+            | DISCONNECT_FROM_CONFERENCE;
 
     public static String toString(int capabilities) {
         StringBuilder builder = new StringBuilder();
diff --git a/telecomm/java/android/telecomm/PropertyPresentation.java b/telecomm/java/android/telecomm/PropertyPresentation.java
deleted file mode 100644
index fe97b3d..0000000
--- a/telecomm/java/android/telecomm/PropertyPresentation.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2014, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telecomm;
-
-/**
- * Defines how properties such as phone numbers and names are displayed to the user.
- */
-public class PropertyPresentation {
-    /** Property is displayed normally. */
-    public static final int ALLOWED = 1;
-
-    /** Property was blocked. */
-    public static final int RESTRICTED = 2;
-
-    /** Presentation was not specified or is unknown. */
-    public static final int UNKNOWN = 3;
-
-    /** Property should be displayed as a pay phone. */
-    public static final int PAYPHONE = 4;
-}
diff --git a/telecomm/java/android/telecomm/RemoteConference.java b/telecomm/java/android/telecomm/RemoteConference.java
index b073827..dbff079 100644
--- a/telecomm/java/android/telecomm/RemoteConference.java
+++ b/telecomm/java/android/telecomm/RemoteConference.java
@@ -188,11 +188,11 @@
         return mDisconnectMessage;
     }
 
-    public final void addCallback(Callback callback) {
+    public final void registerCallback(Callback callback) {
         mCallbacks.add(callback);
     }
 
-    public final void removeCallback(Callback callback) {
+    public final void unregisterCallback(Callback callback) {
         mCallbacks.remove(callback);
     }
 }
diff --git a/telecomm/java/android/telecomm/RemoteConnection.java b/telecomm/java/android/telecomm/RemoteConnection.java
index 8ad8d19..f3a6085 100644
--- a/telecomm/java/android/telecomm/RemoteConnection.java
+++ b/telecomm/java/android/telecomm/RemoteConnection.java
@@ -42,7 +42,7 @@
  */
 public final class RemoteConnection {
 
-    public static abstract class Listener {
+    public static abstract class Callback {
         /**
          * Invoked when the state of this {@code RemoteConnection} has changed. See
          * {@link #getState()}.
@@ -53,25 +53,6 @@
         public void onStateChanged(RemoteConnection connection, int state) {}
 
         /**
-         * Invoked when the parent of this {@code RemoteConnection} has changed. See
-         * {@link #getParent()}.
-         *
-         * @param connection The {@code RemoteConnection} invoking this method.
-         * @param parent The new parent of the {@code RemoteConnection}.
-         */
-        public void onParentChanged(RemoteConnection connection, RemoteConnection parent) {}
-
-        /**
-         * Invoked when the children of this {@code RemoteConnection} have changed. See
-         * {@link #getChildren()}.
-         *
-         * @param connection The {@code RemoteConnection} invoking this method.
-         * @param children The new children of the {@code RemoteConnection}.
-         */
-        public void onChildrenChanged(
-                RemoteConnection connection, List<RemoteConnection> children) {}
-
-        /**
          * Invoked when this {@code RemoteConnection} is disconnected.
          *
          * @param connection The {@code RemoteConnection} invoking this method.
@@ -87,12 +68,12 @@
 
         /**
          * Invoked when this {@code RemoteConnection} is requesting ringback. See
-         * {@link #isRequestingRingback()}.
+         * {@link #isRingbackRequested()}.
          *
          * @param connection The {@code RemoteConnection} invoking this method.
          * @param ringback Whether the {@code RemoteConnection} is requesting ringback.
          */
-        public void onRequestingRingback(RemoteConnection connection, boolean ringback) {}
+        public void onRingbackRequested(RemoteConnection connection, boolean ringback) {}
 
         /**
          * Indicates that the call capabilities of this {@code RemoteConnection} have changed.
@@ -116,12 +97,12 @@
 
         /**
          * Indicates that the VOIP audio status of this {@code RemoteConnection} has changed.
-         * See {@link #getAudioModeIsVoip()}.
+         * See {@link #isVoipAudioMode()}.
          *
          * @param connection The {@code RemoteConnection} invoking this method.
          * @param isVoip Whether the new audio state of the {@code RemoteConnection} is VOIP.
          */
-        public void onAudioModeIsVoipChanged(RemoteConnection connection, boolean isVoip) {}
+        public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {}
 
         /**
          * Indicates that the status hints of this {@code RemoteConnection} have changed. See
@@ -133,15 +114,15 @@
         public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {}
 
         /**
-         * Indicates that the handle (e.g., phone number) of this {@code RemoteConnection} has
-         * changed. See {@link #getHandle()} and {@link #getHandlePresentation()}.
+         * Indicates that the address (e.g., phone number) of this {@code RemoteConnection} has
+         * changed. See {@link #getAddress()} and {@link #getAddressPresentation()}.
          *
          * @param connection The {@code RemoteConnection} invoking this method.
-         * @param handle The new handle of the {@code RemoteConnection}.
-         * @param presentation The {@link PropertyPresentation} which controls how the
-         *         handle is shown.
+         * @param address The new address of the {@code RemoteConnection}.
+         * @param presentation The presentation requirements for the address.
+         *        See {@link TelecommManager} for valid values.
          */
-        public void onHandleChanged(RemoteConnection connection, Uri handle, int presentation) {}
+        public void onAddressChanged(RemoteConnection connection, Uri address, int presentation) {}
 
         /**
          * Indicates that the caller display name of this {@code RemoteConnection} has changed.
@@ -149,8 +130,8 @@
          *
          * @param connection The {@code RemoteConnection} invoking this method.
          * @param callerDisplayName The new caller display name of the {@code RemoteConnection}.
-         * @param presentation The {@link PropertyPresentation} which controls how the
-         *         caller display name is shown.
+         * @param presentation The presentation requirements for the handle.
+         *        See {@link TelecommManager} for valid values.
          */
         public void onCallerDisplayNameChanged(
                 RemoteConnection connection, String callerDisplayName, int presentation) {}
@@ -396,8 +377,8 @@
      * load factor before resizing, 1 means we only expect a single thread to
      * access the map so make only a single shard
      */
-    private final Set<Listener> mListeners = Collections.newSetFromMap(
-            new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
+    private final Set<Callback> mCallbacks = Collections.newSetFromMap(
+            new ConcurrentHashMap<Callback, Boolean>(8, 0.9f, 1));
     private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>();
     private final List<RemoteConnection> mUnmodifiableconferenceableConnections =
             Collections.unmodifiableList(mConferenceableConnections);
@@ -405,15 +386,15 @@
     private int mState = Connection.STATE_NEW;
     private int mDisconnectCauseCode = DisconnectCause.NOT_VALID;
     private String mDisconnectCauseMessage;
-    private boolean mRequestingRingback;
+    private boolean mRingbackRequested;
     private boolean mConnected;
     private int mCallCapabilities;
     private int mVideoState;
     private VideoProvider mVideoProvider;
-    private boolean mAudioModeIsVoip;
+    private boolean mIsVoipAudioMode;
     private StatusHints mStatusHints;
-    private Uri mHandle;
-    private int mHandlePresentation;
+    private Uri mAddress;
+    private int mAddressPresentation;
     private String mCallerDisplayName;
     private int mCallerDisplayNamePresentation;
     private int mFailureCode;
@@ -450,42 +431,26 @@
     }
 
     /**
-     * Adds a listener to this {@code RemoteConnection}.
+     * Adds a callback to this {@code RemoteConnection}.
      *
-     * @param listener A {@code Listener}.
+     * @param callback A {@code Callback}.
      */
-    public void addListener(Listener listener) {
-        mListeners.add(listener);
+    public void registerCallback(Callback callback) {
+        mCallbacks.add(callback);
     }
 
     /**
-     * Removes a listener from this {@code RemoteConnection}.
+     * Removes a callback from this {@code RemoteConnection}.
      *
-     * @param listener A {@code Listener}.
+     * @param callback A {@code Callback}.
      */
-    public void removeListener(Listener listener) {
-        if (listener != null) {
-            mListeners.remove(listener);
+    public void unregisterCallback(Callback callback) {
+        if (callback != null) {
+            mCallbacks.remove(callback);
         }
     }
 
     /**
-     * Obtains the parent of this {@code RemoteConnection} in a conference, if any.
-     *
-     * @return The parent {@code RemoteConnection}, or {@code null} if this {@code RemoteConnection}
-     * is not a child of any conference {@code RemoteConnection}s.
-     */
-    public RemoteConnection getParent() { return null; }
-
-    /**
-     * Obtains the children of this conference {@code RemoteConnection}, if any.
-     *
-     * @return The children of this {@code RemoteConnection} if this {@code RemoteConnection} is
-     * a conference, or an empty {@code List} otherwise.
-     */
-    public List<RemoteConnection> getChildren() { return new ArrayList<>(); }
-
-    /**
      * Obtains the state of this {@code RemoteConnection}.
      *
      * @return A state value, chosen from the {@code STATE_*} constants.
@@ -522,8 +487,8 @@
     /**
      * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP.
      */
-    public boolean getAudioModeIsVoip() {
-        return mAudioModeIsVoip;
+    public boolean isVoipAudioMode() {
+        return mIsVoipAudioMode;
     }
 
     /**
@@ -535,31 +500,31 @@
     }
 
     /**
-     * @return The handle (e.g., phone number) to which the {@code RemoteConnection} is currently
+     * @return The address (e.g., phone number) to which the {@code RemoteConnection} is currently
      * connected.
      */
-    public Uri getHandle() {
-        return mHandle;
+    public Uri getAddress() {
+        return mAddress;
     }
 
     /**
-     * @return The presentation requirements for the handle. See
-     * {@link PropertyPresentation} for valid values.
+     * @return The presentation requirements for the address. See {@link TelecommManager} for valid
+     * values.
      */
-    public int getHandlePresentation() {
-        return mHandlePresentation;
+    public int getAddressPresentation() {
+        return mAddressPresentation;
     }
 
     /**
      * @return The display name for the caller.
      */
-    public String getCallerDisplayName() {
+    public CharSequence getCallerDisplayName() {
         return mCallerDisplayName;
     }
 
     /**
      * @return The presentation requirements for the caller display name. See
-     * {@link PropertyPresentation} for valid values.
+     * {@link TelecommManager} for valid values.
      */
     public int getCallerDisplayNamePresentation() {
         return mCallerDisplayNamePresentation;
@@ -601,7 +566,7 @@
      * @return Whether the {@code RemoteConnection} is requesting that the framework play a
      * ringback tone on its behalf.
      */
-    public boolean isRequestingRingback() {
+    public boolean isRingbackRequested() {
         return false;
     }
 
@@ -738,8 +703,8 @@
      * of time.
      *
      * If the DTMF string contains a {@link TelecommManager#DTMF_CHARACTER_WAIT} symbol, this
-     * {@code RemoteConnection} will pause playing the tones and notify listeners via
-     * {@link Listener#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
+     * {@code RemoteConnection} will pause playing the tones and notify callbackss via
+     * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
      * should display to the user an indication of this state and an affordance to continue
      * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
      * app should invoke the {@link #postDialContinue(boolean)} method.
@@ -806,8 +771,8 @@
     void setState(int state) {
         if (mState != state) {
             mState = state;
-            for (Listener l: mListeners) {
-                l.onStateChanged(this, state);
+            for (Callback c: mCallbacks) {
+                c.onStateChanged(this, state);
             }
         }
     }
@@ -821,8 +786,8 @@
             mDisconnectCauseCode = cause;
             mDisconnectCauseMessage = message;
 
-            for (Listener l : mListeners) {
-                l.onDisconnected(this, cause, message);
+            for (Callback c : mCallbacks) {
+                c.onDisconnected(this, cause, message);
             }
         }
     }
@@ -830,11 +795,11 @@
     /**
      * @hide
      */
-    void setRequestingRingback(boolean ringback) {
-        if (mRequestingRingback != ringback) {
-            mRequestingRingback = ringback;
-            for (Listener l : mListeners) {
-                l.onRequestingRingback(this, ringback);
+    void setRingbackRequested(boolean ringback) {
+        if (mRingbackRequested != ringback) {
+            mRingbackRequested = ringback;
+            for (Callback c : mCallbacks) {
+                c.onRingbackRequested(this, ringback);
             }
         }
     }
@@ -844,8 +809,8 @@
      */
     void setCallCapabilities(int callCapabilities) {
         mCallCapabilities = callCapabilities;
-        for (Listener l : mListeners) {
-            l.onCallCapabilitiesChanged(this, callCapabilities);
+        for (Callback c : mCallbacks) {
+            c.onCallCapabilitiesChanged(this, callCapabilities);
         }
     }
 
@@ -853,16 +818,16 @@
      * @hide
      */
     void setDestroyed() {
-        if (!mListeners.isEmpty()) {
-            // Make sure that the listeners are notified that the call is destroyed first.
+        if (!mCallbacks.isEmpty()) {
+            // Make sure that the callbacks are notified that the call is destroyed first.
             if (mState != Connection.STATE_DISCONNECTED) {
                 setDisconnected(DisconnectCause.ERROR_UNSPECIFIED, "Connection destroyed.");
             }
 
-            for (Listener l : mListeners) {
-                l.onDestroyed(this);
+            for (Callback c : mCallbacks) {
+                c.onDestroyed(this);
             }
-            mListeners.clear();
+            mCallbacks.clear();
 
             mConnected = false;
         }
@@ -872,8 +837,8 @@
      * @hide
      */
     void setPostDialWait(String remainingDigits) {
-        for (Listener l : mListeners) {
-            l.onPostDialWait(this, remainingDigits);
+        for (Callback c : mCallbacks) {
+            c.onPostDialWait(this, remainingDigits);
         }
     }
 
@@ -882,8 +847,8 @@
      */
     void setVideoState(int videoState) {
         mVideoState = videoState;
-        for (Listener l : mListeners) {
-            l.onVideoStateChanged(this, videoState);
+        for (Callback c : mCallbacks) {
+            c.onVideoStateChanged(this, videoState);
         }
     }
 
@@ -892,33 +857,33 @@
      */
     void setVideoProvider(VideoProvider videoProvider) {
         mVideoProvider = videoProvider;
-        for (Listener l : mListeners) {
-            l.onVideoProviderChanged(this, videoProvider);
+        for (Callback c : mCallbacks) {
+            c.onVideoProviderChanged(this, videoProvider);
         }
     }
 
     /** @hide */
-    void setAudioModeIsVoip(boolean isVoip) {
-        mAudioModeIsVoip = isVoip;
-        for (Listener l : mListeners) {
-            l.onAudioModeIsVoipChanged(this, isVoip);
+    void setIsVoipAudioMode(boolean isVoip) {
+        mIsVoipAudioMode = isVoip;
+        for (Callback c : mCallbacks) {
+            c.onVoipAudioChanged(this, isVoip);
         }
     }
 
     /** @hide */
     void setStatusHints(StatusHints statusHints) {
         mStatusHints = statusHints;
-        for (Listener l : mListeners) {
-            l.onStatusHintsChanged(this, statusHints);
+        for (Callback c : mCallbacks) {
+            c.onStatusHintsChanged(this, statusHints);
         }
     }
 
     /** @hide */
-    void setHandle(Uri handle, int presentation) {
-        mHandle = handle;
-        mHandlePresentation = presentation;
-        for (Listener l : mListeners) {
-            l.onHandleChanged(this, handle, presentation);
+    void setAddress(Uri address, int presentation) {
+        mAddress = address;
+        mAddressPresentation = presentation;
+        for (Callback c : mCallbacks) {
+            c.onAddressChanged(this, address, presentation);
         }
     }
 
@@ -926,8 +891,8 @@
     void setCallerDisplayName(String callerDisplayName, int presentation) {
         mCallerDisplayName = callerDisplayName;
         mCallerDisplayNamePresentation = presentation;
-        for (Listener l : mListeners) {
-            l.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
+        for (Callback c : mCallbacks) {
+            c.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
         }
     }
 
@@ -935,8 +900,8 @@
     void setConferenceableConnections(List<RemoteConnection> conferenceableConnections) {
         mConferenceableConnections.clear();
         mConferenceableConnections.addAll(conferenceableConnections);
-        for (Listener l : mListeners) {
-            l.onConferenceableConnectionsChanged(this, mUnmodifiableconferenceableConnections);
+        for (Callback c : mCallbacks) {
+            c.onConferenceableConnectionsChanged(this, mUnmodifiableconferenceableConnections);
         }
     }
 
@@ -944,8 +909,8 @@
     void setConference(RemoteConference conference) {
         if (mConference != conference) {
             mConference = conference;
-            for (Listener l : mListeners) {
-                l.onConferenceChanged(this, conference);
+            for (Callback c : mCallbacks) {
+                c.onConferenceChanged(this, conference);
             }
         }
     }
diff --git a/telecomm/java/android/telecomm/RemoteConnectionService.java b/telecomm/java/android/telecomm/RemoteConnectionService.java
index 8b8e8eb..d4dd9af 100644
--- a/telecomm/java/android/telecomm/RemoteConnectionService.java
+++ b/telecomm/java/android/telecomm/RemoteConnectionService.java
@@ -61,7 +61,7 @@
                 mPendingConnections.remove(connection);
                 // Unconditionally initialize the connection ...
                 connection.setCallCapabilities(parcel.getCapabilities());
-                connection.setHandle(
+                connection.setAddress(
                         parcel.getHandle(), parcel.getHandlePresentation());
                 connection.setCallerDisplayName(
                         parcel.getCallerDisplayName(),
@@ -131,9 +131,9 @@
         }
 
         @Override
-        public void setRequestingRingback(String callId, boolean ringing) {
-            findConnectionForAction(callId, "setRequestingRingback")
-                    .setRequestingRingback(ringing);
+        public void setRingbackRequested(String callId, boolean ringing) {
+            findConnectionForAction(callId, "setRingbackRequested")
+                    .setRingbackRequested(ringing);
         }
 
         @Override
@@ -192,7 +192,7 @@
             conference.setState(parcel.getState());
             conference.setCallCapabilities(parcel.getCapabilities());
             mConferenceById.put(callId, conference);
-            conference.addCallback(new RemoteConference.Callback() {
+            conference.registerCallback(new RemoteConference.Callback() {
                 @Override
                 public void onDestroyed(RemoteConference c) {
                     mConferenceById.remove(callId);
@@ -238,9 +238,9 @@
         }
 
         @Override
-        public void setAudioModeIsVoip(String callId, boolean isVoip) {
-            findConnectionForAction(callId, "setAudioModeIsVoip")
-                    .setAudioModeIsVoip(isVoip);
+        public void setIsVoipAudioMode(String callId, boolean isVoip) {
+            findConnectionForAction(callId, "setIsVoipAudioMode")
+                    .setIsVoipAudioMode(isVoip);
         }
 
         @Override
@@ -250,9 +250,9 @@
         }
 
         @Override
-        public void setHandle(String callId, Uri handle, int presentation) {
-            findConnectionForAction(callId, "setHandle")
-                    .setHandle(handle, presentation);
+        public void setAddress(String callId, Uri address, int presentation) {
+            findConnectionForAction(callId, "setAddress")
+                    .setAddress(address, presentation);
         }
 
         @Override
@@ -343,7 +343,7 @@
                     id,
                     newRequest,
                     isIncoming);
-            connection.addListener(new RemoteConnection.Listener() {
+            connection.registerCallback(new RemoteConnection.Callback() {
                 @Override
                 public void onDestroyed(RemoteConnection connection) {
                     mConnectionById.remove(id);
diff --git a/telecomm/java/android/telecomm/Response.java b/telecomm/java/android/telecomm/Response.java
index f879756..ad78ebd 100644
--- a/telecomm/java/android/telecomm/Response.java
+++ b/telecomm/java/android/telecomm/Response.java
@@ -17,10 +17,7 @@
 package android.telecomm;
 
 /**
- * <strong>OBSOLETE</strong> Used to inform a client of asynchronously returned results.
- * <p>
- * <strong>TODO:</strong> Remove onCreateConferenceConnection() async method
- * then delete this interface.
+ * @hide
  */
 public interface Response<IN, OUT> {
 
diff --git a/telecomm/java/android/telecomm/TelecommManager.java b/telecomm/java/android/telecomm/TelecommManager.java
index 5e9e6d0..e2c98cd 100644
--- a/telecomm/java/android/telecomm/TelecommManager.java
+++ b/telecomm/java/android/telecomm/TelecommManager.java
@@ -25,6 +25,7 @@
 import com.android.internal.telecomm.ITelecommService;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -69,6 +70,24 @@
             "android.telecomm.action.CHANGE_PHONE_ACCOUNTS";
 
     /**
+     * The {@link android.content.Intent} action used to inform a
+     * {@link android.telecomm.ConnectionService} that one of its {@link PhoneAccount}s has been
+     * enabled.  The {@link TelecommManager#EXTRA_PHONE_ACCOUNT_HANDLE} extra is used to indicate
+     * which {@link PhoneAccount} has been enabled.
+     */
+    public static final String ACTION_PHONE_ACCOUNT_ENABLED =
+            "android.telecom.action.PHONE_ACCOUNT_ENABLED";
+
+    /**
+     * The {@link android.content.Intent} action used to inform a
+     * {@link android.telecomm.ConnectionService} that one of its {@link PhoneAccount}s has been
+     * disabled.  The {@link TelecommManager#EXTRA_PHONE_ACCOUNT_HANDLE} extra is used to indicate
+     * which {@link PhoneAccount} has been disabled.
+     */
+    public static final String ACTION_PHONE_ACCOUNT_DISABLED =
+            "android.telecom.action.PHONE_ACCOUNT_DISABLED";
+
+    /**
      * Optional extra for {@link android.content.Intent#ACTION_CALL} containing a boolean that
      * determines whether the speakerphone should be automatically turned on for an outgoing call.
      */
@@ -141,6 +160,30 @@
             "android.telecomm.extra.CONNECTION_SERVICE";
 
     /**
+     * An optional {@link android.content.Intent#ACTION_CALL} intent extra denoting the
+     * package name of the app specifying an alternative gateway for the call.
+     * The value is a string.
+     *
+     * (The following comment corresponds to the all GATEWAY_* extras)
+     * An app which sends the {@link android.content.Intent#ACTION_CALL} intent can specify an
+     * alternative address to dial which is different from the one specified and displayed to
+     * the user. This alternative address is referred to as the gateway address.
+     */
+    public static final String GATEWAY_PROVIDER_PACKAGE =
+            "android.telecomm.extra.GATEWAY_PROVIDER_PACKAGE";
+
+    /**
+     * An optional {@link android.content.Intent#ACTION_CALL} intent extra corresponding to the
+     * original address to dial for the call. This is used when an alternative gateway address is
+     * provided to recall the original address.
+     * The value is a {@link android.net.Uri}.
+     *
+     * (See {@link #GATEWAY_PROVIDER_PACKAGE} for details)
+     */
+    public static final String GATEWAY_ORIGINAL_ADDRESS =
+            "android.telecomm.extra.GATEWAY_ORIGINAL_ADDRESS";
+
+    /**
      * The number which the party on the other side of the line will see (and use to return the
      * call).
      * <p>
@@ -238,6 +281,23 @@
     public static final String EXTRA_TTY_PREFERRED_MODE =
             "android.telecomm.intent.extra.TTY_PREFERRED";
 
+    /**
+     * The following 4 constants define how properties such as phone numbers and names are
+     * displayed to the user.
+     */
+
+    /** Property is displayed normally. */
+    public static final int PRESENTATION_ALLOWED = 1;
+
+    /** Property was blocked. */
+    public static final int PRESENTATION_RESTRICTED = 2;
+
+    /** Presentation was not specified or is unknown. */
+    public static final int PRESENTATION_UNKNOWN = 3;
+
+    /** Property should be displayed as a pay phone. */
+    public static final int PRESENTATION_PAYPHONE = 4;
+
     private static final String TAG = "TelecommManager";
 
     private static final String TELECOMM_SERVICE_NAME = "telecomm";
@@ -270,7 +330,7 @@
      * <p>
      * Apps must be prepared for this method to return {@code null}, indicating that there currently
      * exists no user-chosen default {@code PhoneAccount}. In this case, apps wishing to initiate a
-     * phone call must either create their {@link android.content .Intent#ACTION_CALL} or
+     * phone call must either create their {@link android.content.Intent#ACTION_CALL} or
      * {@link android.content.Intent#ACTION_DIAL} {@code Intent} with no
      * {@link TelecommManager#EXTRA_PHONE_ACCOUNT_HANDLE}, or present the user with an affordance to
      * select one of the elements of {@link #getEnabledPhoneAccounts()}.
@@ -330,8 +390,8 @@
     }
 
     /**
-     * Return a list of {@link PhoneAccountHandle}s which can be used to make and receive phone
-     * calls.
+     * Return a list of enabled {@link PhoneAccountHandle}s which can be used to make and receive
+     * phone calls.
      *
      * @see #EXTRA_PHONE_ACCOUNT_HANDLE
      * @return A list of {@code PhoneAccountHandle} objects.
@@ -339,10 +399,10 @@
     public List<PhoneAccountHandle> getEnabledPhoneAccounts() {
         try {
             if (isServiceConnected()) {
-                return getTelecommService().getOutgoingPhoneAccounts();
+                return getTelecommService().getEnabledPhoneAccounts();
             }
         } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelecommService#getOutgoingPhoneAccounts", e);
+            Log.e(TAG, "Error calling ITelecommService#getEnabledPhoneAccounts", e);
         }
         return new ArrayList<>();
     }
@@ -408,8 +468,8 @@
     }
 
     /**
-     * Returns a list of {@link PhoneAccountHandle}s which can be used to make and receive phone
-     * calls which support the specified URI scheme.
+     * Returns a list of the enabled {@link PhoneAccountHandle}s which can be used to make and
+     * receive phone calls which support the specified URI scheme.
      * <P>
      * For example, invoking with {@code "tel"} will find all {@link PhoneAccountHandle}s which
      * support telephone calls (e.g. URIs such as {@code tel:555-555-1212}).  Invoking with
@@ -459,6 +519,78 @@
     }
 
     /**
+     * Returns a count of enabled and disabled {@link PhoneAccount}s.
+     *
+     * @return The count of enabled and disabled {@link PhoneAccount}s.
+     * @hide
+     */
+    @SystemApi
+    public int getAllPhoneAccountsCount() {
+        try {
+            if (isServiceConnected()) {
+                return getTelecommService().getAllPhoneAccountsCount();
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelecommService#getAllPhoneAccountsCount", e);
+        }
+        return 0;
+    }
+
+    /**
+     * Returns a list of all {@link PhoneAccount}s.
+     *
+     * @return All {@link PhoneAccount}s.
+     * @hide
+     */
+    @SystemApi
+    public List<PhoneAccount> getAllPhoneAccounts() {
+        try {
+            if (isServiceConnected()) {
+                return getTelecommService().getAllPhoneAccounts();
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelecommService#getAllPhoneAccounts", e);
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+    /**
+     * Returns a list of all {@link PhoneAccountHandle}s.
+     *
+     * @return All {@link PhoneAccountHandle}s.
+     * @hide
+     */
+    @SystemApi
+    public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
+        try {
+            if (isServiceConnected()) {
+                return getTelecommService().getAllPhoneAccountHandles();
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelecommService#getAllPhoneAccountHandles", e);
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+    /**
+     * Enables or disables a {@link PhoneAccount}.
+     *
+     * @param account The {@link PhoneAccountHandle} to enable or disable.
+     * @param isEnabled {@code True} if the phone account should be enabled.
+     * @hide
+     */
+    @SystemApi
+    public void setPhoneAccountEnabled(PhoneAccountHandle account, boolean isEnabled) {
+        try {
+            if (isServiceConnected()) {
+                getTelecommService().setPhoneAccountEnabled(account, isEnabled);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelecommService#setPhoneAccountEnabled", e);
+        }
+    }
+
+    /**
      * Register a {@link PhoneAccount} for use by the system.
      *
      * @param account The complete {@link PhoneAccount}.
@@ -489,15 +621,13 @@
     }
 
     /**
-     * Remove all Accounts for a given package from the system.
-     *
-     * @param packageName A package name that may have registered Accounts.
+     * Remove all Accounts that belong to the calling package from the system.
      */
     @SystemApi
-    public void clearAccounts(String packageName) {
+    public void clearAccounts() {
         try {
             if (isServiceConnected()) {
-                getTelecommService().clearAccounts(packageName);
+                getTelecommService().clearAccounts(mContext.getPackageName());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelecommService#clearAccounts", e);
diff --git a/telecomm/java/com/android/internal/telecomm/IConnectionService.aidl b/telecomm/java/com/android/internal/telecomm/IConnectionService.aidl
index a673733..3af4ed3 100644
--- a/telecomm/java/com/android/internal/telecomm/IConnectionService.aidl
+++ b/telecomm/java/com/android/internal/telecomm/IConnectionService.aidl
@@ -70,6 +70,4 @@
     void swapConference(String conferenceCallId);
 
     void onPostDialContinue(String callId, boolean proceed);
-
-    void onPhoneAccountClicked(String callId);
 }
diff --git a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
index 610178e..4b636d1 100644
--- a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
@@ -49,7 +49,7 @@
 
     void setOnHold(String callId);
 
-    void setRequestingRingback(String callId, boolean ringing);
+    void setRingbackRequested(String callId, boolean ringing);
 
     void setCallCapabilities(String callId, int callCapabilities);
 
@@ -67,11 +67,11 @@
 
     void setVideoState(String callId, int videoState);
 
-    void setAudioModeIsVoip(String callId, boolean isVoip);
+    void setIsVoipAudioMode(String callId, boolean isVoip);
 
     void setStatusHints(String callId, in StatusHints statusHints);
 
-    void setHandle(String callId, in Uri handle, int presentation);
+    void setAddress(String callId, in Uri address, int presentation);
 
     void setCallerDisplayName(String callId, String callerDisplayName, int presentation);
 
diff --git a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
index 626bb91..808a410 100644
--- a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
@@ -46,8 +46,6 @@
 
     void postDialContinue(String callId, boolean proceed);
 
-    void phoneAccountClicked(String callId);
-
     void phoneAccountSelected(String callId, in PhoneAccountHandle accountHandle);
 
     void conference(String callId, String otherCallId);
diff --git a/telecomm/java/com/android/internal/telecomm/ITelecommService.aidl b/telecomm/java/com/android/internal/telecomm/ITelecommService.aidl
index 6ab78c4..30f2801 100644
--- a/telecomm/java/com/android/internal/telecomm/ITelecommService.aidl
+++ b/telecomm/java/com/android/internal/telecomm/ITelecommService.aidl
@@ -50,9 +50,9 @@
     void setUserSelectedOutgoingPhoneAccount(in PhoneAccountHandle account);
 
     /**
-     * @see TelecommServiceImpl#getOutgoingPhoneAccounts
+     * @see TelecommServiceImpl#getEnabledPhoneAccounts
      */
-    List<PhoneAccountHandle> getOutgoingPhoneAccounts();
+    List<PhoneAccountHandle> getEnabledPhoneAccounts();
 
     /**
      * @see TelecommManager#getPhoneAccountsSupportingScheme
@@ -65,6 +65,21 @@
     PhoneAccount getPhoneAccount(in PhoneAccountHandle account);
 
     /**
+     * @see TelecommManager#getAllPhoneAccountsCount
+     */
+    int getAllPhoneAccountsCount();
+
+    /**
+     * @see TelecommManager#getAllPhoneAccounts
+     */
+    List<PhoneAccount> getAllPhoneAccounts();
+
+    /**
+     * @see TelecommManager#getAllPhoneAccountHandles
+     */
+    List<PhoneAccountHandle> getAllPhoneAccountHandles();
+
+    /**
      * @see TelecommServiceImpl#getSimCallManager
      */
     PhoneAccountHandle getSimCallManager();
@@ -80,6 +95,11 @@
     List<PhoneAccountHandle> getSimCallManagers();
 
     /**
+     * @see TelecommServiceImpl#setPhoneAccountEnabled
+     */
+    void setPhoneAccountEnabled(in PhoneAccountHandle account, in boolean isEnabled);
+
+    /**
      * @see TelecommServiceImpl#registerPhoneAccount
      */
     void registerPhoneAccount(in PhoneAccount metadata);
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index d0f355e..fe68263 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -930,13 +930,20 @@
 
     /** @hide */
     public static boolean isValidSlotId(int slotId) {
-        return slotId > INVALID_SLOT_ID && slotId < TelephonyManager.getDefault().getSimCount();
+        // We are testing INVALID_SLOT_ID and slotId >= 0 independently because we should
+        // not assume that INVALID_SLOT_ID will always be a negative value.  Any negative
+        // value is invalid.
+        return slotId != INVALID_SLOT_ID && slotId >= 0 &&
+                slotId < TelephonyManager.getDefault().getSimCount();
     }
 
     /** @hide */
     public static boolean isValidPhoneId(int phoneId) {
-        return phoneId > INVALID_PHONE_ID
-                && phoneId < TelephonyManager.getDefault().getPhoneCount();
+        // We are testing INVALID_PHONE_ID and phoneId >= 0 independently because we should
+        // not assume that INVALID_PHONE_ID will always be a negative value.  Any negative
+        // value is invalid.
+        return phoneId != INVALID_PHONE_ID && phoneId >= 0 &&
+                phoneId < TelephonyManager.getDefault().getPhoneCount();
     }
 
     /** @hide */
diff --git a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java
index a68e04e..9df11fe 100644
--- a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java
+++ b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java
@@ -29,6 +29,7 @@
 import android.os.RemoteException;
 import android.util.Log;
 import android.util.SparseArray;
+import android.widget.Toast;
 
 import com.android.demo.jobSchedulerApp.MainActivity;
 
@@ -84,12 +85,15 @@
         currentId++;
         jobParamsMap.put(currentId, params);
         final int currId = this.currentId;
-        Log.d(TAG, "putting :" + currId + " for " + params.toString());
-        Log.d(TAG, " pulled: " + jobParamsMap.get(currId));
         if (mActivity != null) {
             mActivity.onReceivedStartJob(params);
         }
 
+        Toast.makeText(
+                this, "On start job: '" + params.getJobId() + "' deadline exceeded: " +
+                        params.isOverrideDeadlineExpired(),
+                Toast.LENGTH_LONG).show();
+
         return true;
     }
 
@@ -100,7 +104,7 @@
         int ind = jobParamsMap.indexOfValue(params);
         jobParamsMap.remove(ind);
         mActivity.onReceivedStopJob();
-        return true;
+        return false; // no reschedule
     }
 
     static int currentId = 0;
@@ -129,6 +133,7 @@
             return false;
         } else {
             jobFinished(params, false);
+            jobParamsMap.removeAt(0);
             return true;
         }
     }
diff --git a/tests/StatusBar/src/com/android/statusbartest/PowerTest.java b/tests/StatusBar/src/com/android/statusbartest/PowerTest.java
index 2ec620b..52527d9 100644
--- a/tests/StatusBar/src/com/android/statusbartest/PowerTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/PowerTest.java
@@ -77,9 +77,9 @@
                 mProx.release();
             }
         },
-        new Test("Disable proximity (WAIT_FOR_DISTANT_PROXIMITY") {
+        new Test("Disable proximity (RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY") {
             public void run() {
-                mProx.release(PowerManager.WAIT_FOR_DISTANT_PROXIMITY);
+                mProx.release(PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY);
             }
         },
         new Test("Enable proximity, wait 5 seconds then disable") {
@@ -93,13 +93,14 @@
                 }, 5000);
             }
         },
-        new Test("Enable proximity, wait 5 seconds then disable  (WAIT_FOR_DISTANT_PROXIMITY)") {
+        new Test("Enable proximity, wait 5 seconds then disable " +
+                "(RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY)") {
             public void run() {
                 mProx.acquire();
                 mHandler.postDelayed(new Runnable() {
                     @Override
                     public void run() {
-                        mProx.release(PowerManager.WAIT_FOR_DISTANT_PROXIMITY);
+                        mProx.release(PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY);
                     }
                 }, 5000);
             }
diff --git a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java
index 31e7c38..d9a3b61 100644
--- a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java
+++ b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java
@@ -86,7 +86,10 @@
                 }
                 mEvents.addFirst(event);
             }
-            notifyDataSetChanged();
+
+            if (lastTimeStamp != 0) {
+                notifyDataSetChanged();
+            }
             return lastTimeStamp;
         }
 
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 27e60f3..41d8502 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -2390,7 +2390,8 @@
             char* packageString = strtok(libs.lockBuffer(libs.length()), ":");
             while (packageString != NULL) {
                 // Write the R.java file out with the correct package name
-                err = writeResourceSymbols(bundle, assets, String8(packageString), true, false);
+                err = writeResourceSymbols(bundle, assets, String8(packageString), true,
+                        bundle->getBuildSharedLibrary());
                 if (err < 0) {
                     goto bail;
                 }
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 5deeca2..afec5ed 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -1926,110 +1926,75 @@
     return String16();
 }
 
-static void writeResourceLoadedCallback(FILE* fp, int indent) {
-    IndentPrinter p(fp, 4);
-    p.indent(indent);
-    p.println("private static void rewriteIntArrayField(java.lang.reflect.Field field, int packageId) throws IllegalAccessException {");
-    {
-        p.indent();
-        p.println("int requiredModifiers = java.lang.reflect.Modifier.STATIC | java.lang.reflect.Modifier.PUBLIC;");
-        p.println("if ((field.getModifiers() & requiredModifiers) != requiredModifiers) {");
-        {
-            p.indent();
-            p.println("throw new IllegalArgumentException(\"Field \" + field.getName() + \" is not rewritable\");");
-            p.indent(-1);
-        }
-        p.println("}");
-        p.println("if (field.getType() != int[].class) {");
-        {
-            p.indent();
-            p.println("throw new IllegalArgumentException(\"Field \" + field.getName() + \" is not an int array\");");
-            p.indent(-1);
-        }
-        p.println("}");
-        p.println("int[] array = (int[]) field.get(null);");
-        p.println("for (int i = 0; i < array.length; i++) {");
-        {
-            p.indent();
-            p.println("array[i] = (array[i] & 0x00ffffff) | (packageId << 24);");
-            p.indent(-1);
-        }
-        p.println("}");
-        p.indent(-1);
+static status_t writeResourceLoadedCallbackForLayoutClasses(
+    FILE* fp, const sp<AaptAssets>& assets,
+    const sp<AaptSymbols>& symbols, int indent, bool includePrivate)
+{
+    String16 attr16("attr");
+    String16 package16(assets->getPackage());
+
+    const char* indentStr = getIndentSpace(indent);
+    bool hasErrors = false;
+
+    size_t i;
+    size_t N = symbols->getNestedSymbols().size();
+    for (i=0; i<N; i++) {
+        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
+        String8 realClassName(symbols->getNestedSymbols().keyAt(i));
+        String8 nclassName(flattenSymbol(realClassName));
+
+        fprintf(fp,
+                "%sfor(int i = 0; i < styleable.%s.length; ++i) {\n"
+                "%sstyleable.%s[i] = (styleable.%s[i] & 0x00ffffff) | (packageId << 24);\n"
+                "%s}\n",
+                indentStr, nclassName.string(),
+                getIndentSpace(indent+1), nclassName.string(), nclassName.string(),
+                indentStr);
     }
-    p.println("}");
-    p.println();
-    p.println("private static void rewriteIntField(java.lang.reflect.Field field, int packageId) throws IllegalAccessException {");
-    {
-        p.indent();
-        p.println("int requiredModifiers = java.lang.reflect.Modifier.STATIC | java.lang.reflect.Modifier.PUBLIC;");
-        p.println("int bannedModifiers = java.lang.reflect.Modifier.FINAL;");
-        p.println("int mod = field.getModifiers();");
-        p.println("if ((mod & requiredModifiers) != requiredModifiers || (mod & bannedModifiers) != 0) {");
-        {
-            p.indent();
-            p.println("throw new IllegalArgumentException(\"Field \" + field.getName() + \" is not rewritable\");");
-            p.indent(-1);
+
+    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
+}
+
+static status_t writeResourceLoadedCallback(
+    FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,
+    const sp<AaptSymbols>& symbols, const String8& className, int indent)
+{
+    size_t i;
+    status_t err = NO_ERROR;
+
+    size_t N = symbols->getSymbols().size();
+    for (i=0; i<N; i++) {
+        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);
+        if (sym.typeCode == AaptSymbolEntry::TYPE_UNKNOWN) {
+            continue;
         }
-        p.println("}");
-        p.println("if (field.getType() != int.class && field.getType() != Integer.class) {");
-        {
-            p.indent();
-            p.println("throw new IllegalArgumentException(\"Field \" + field.getName() + \" is not an int\");");
-            p.indent(-1);
+        if (!assets->isJavaSymbol(sym, includePrivate)) {
+            continue;
         }
-        p.println("}");
-        p.println("int resId = field.getInt(null);");
-        p.println("field.setInt(null, (resId & 0x00ffffff) | (packageId << 24));");
-        p.indent(-1);
+        String8 flat_name(flattenSymbol(sym.name));
+        fprintf(fp,
+                "%s%s.%s = (%s.%s & 0x00ffffff) | (packageId << 24);\n",
+                getIndentSpace(indent), className.string(), flat_name.string(),
+                className.string(), flat_name.string());
     }
-    p.println("}");
-    p.println();
-    p.println("public static void onResourcesLoaded(int assignedPackageId) throws Exception {");
-    {
-        p.indent();
-        p.println("Class<?>[] declaredClasses = R.class.getDeclaredClasses();");
-        p.println("for (Class<?> clazz : declaredClasses) {");
-        {
-            p.indent();
-            p.println("if (clazz.getSimpleName().equals(\"styleable\")) {");
-            {
-                p.indent();
-                p.println("for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {");
-                {
-                    p.indent();
-                    p.println("if (field.getType() == int[].class) {");
-                    {
-                        p.indent();
-                        p.println("rewriteIntArrayField(field, assignedPackageId);");
-                        p.indent(-1);
-                    }
-                    p.println("}");
-                    p.indent(-1);
-                }
-                p.println("}");
-                p.indent(-1);
-            }
-            p.println("} else {");
-            {
-                p.indent();
-                p.println("for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {");
-                {
-                    p.indent();
-                    p.println("rewriteIntField(field, assignedPackageId);");
-                    p.indent(-1);
-                }
-                p.println("}");
-                p.indent(-1);
-            }
-            p.println("}");
-            p.indent(-1);
+
+    N = symbols->getNestedSymbols().size();
+    for (i=0; i<N; i++) {
+        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
+        String8 nclassName(symbols->getNestedSymbols().keyAt(i));
+        if (nclassName == "styleable") {
+            err = writeResourceLoadedCallbackForLayoutClasses(
+                    fp, assets, nsymbols, indent, includePrivate);
+        } else {
+            err = writeResourceLoadedCallback(fp, assets, includePrivate, nsymbols,
+                    nclassName, indent);
         }
-        p.println("}");
-        p.indent(-1);
+        if (err != NO_ERROR) {
+            return err;
+        }
     }
-    p.println("}");
-    p.println();
+
+    return NO_ERROR;
 }
 
 static status_t writeLayoutClasses(
@@ -2485,7 +2450,10 @@
     }
 
     if (emitCallback) {
-        writeResourceLoadedCallback(fp, indent);
+        fprintf(fp, "%spublic static void onResourcesLoaded(int packageId) {\n",
+                getIndentSpace(indent));
+        writeResourceLoadedCallback(fp, assets, includePrivate, symbols, className, indent + 1);
+        fprintf(fp, "%s}\n", getIndentSpace(indent));
     }
 
     indent--;