merge in lmp-release history after reset to ebb6b4224ee02b2ef7ae5d58c9e7cdf3ab16b090
diff --git a/Android.mk b/Android.mk
index 35bb66c..419b1ed 100644
--- a/Android.mk
+++ b/Android.mk
@@ -150,7 +150,7 @@
 	core/java/android/hardware/ISerialManager.aidl \
 	core/java/android/hardware/display/IDisplayManager.aidl \
 	core/java/android/hardware/display/IDisplayManagerCallback.aidl \
-	core/java/android/hardware/display/IVirtualDisplayCallbacks.aidl \
+	core/java/android/hardware/display/IVirtualDisplayCallback.aidl \
 	core/java/android/hardware/hdmi/IHdmiControlCallback.aidl \
 	core/java/android/hardware/hdmi/IHdmiControlService.aidl \
 	core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl \
diff --git a/api/current.txt b/api/current.txt
index 009b534..60668ba 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3430,7 +3430,6 @@
     method public int getTaskId();
     method public final java.lang.CharSequence getTitle();
     method public final int getTitleColor();
-    method public android.app.VoiceInteractor getVoiceInteractor();
     method public final int getVolumeControlStream();
     method public android.view.Window getWindow();
     method public android.view.WindowManager getWindowManager();
@@ -3442,7 +3441,6 @@
     method public boolean isFinishing();
     method public boolean isImmersive();
     method public boolean isTaskRoot();
-    method public boolean isVoiceInteraction();
     method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public boolean moveTaskToBack(boolean);
     method public boolean navigateUpTo(android.content.Intent);
@@ -3917,6 +3915,7 @@
     field public static final int MODE_IGNORED = 1; // 0x1
     field public static final java.lang.String OPSTR_COARSE_LOCATION = "android:coarse_location";
     field public static final java.lang.String OPSTR_FINE_LOCATION = "android:fine_location";
+    field public static final java.lang.String OPSTR_GET_USAGE_STATS = "android:get_usage_stats";
     field public static final java.lang.String OPSTR_MONITOR_HIGH_POWER_LOCATION = "android:monitor_location_high_power";
     field public static final java.lang.String OPSTR_MONITOR_LOCATION = "android:monitor_location";
   }
@@ -5267,41 +5266,6 @@
     field public static final int MODE_NIGHT_YES = 2; // 0x2
   }
 
-  public class VoiceInteractor {
-    method public boolean submitRequest(android.app.VoiceInteractor.Request);
-    method public boolean[] supportsCommands(java.lang.String[]);
-  }
-
-  public static class VoiceInteractor.AbortVoiceRequest extends android.app.VoiceInteractor.Request {
-    ctor public VoiceInteractor.AbortVoiceRequest(java.lang.CharSequence, android.os.Bundle);
-    method public void onAbortResult(android.os.Bundle);
-  }
-
-  public static class VoiceInteractor.CommandRequest extends android.app.VoiceInteractor.Request {
-    ctor public VoiceInteractor.CommandRequest(java.lang.String, android.os.Bundle);
-    method public void onCommandResult(android.os.Bundle);
-  }
-
-  public static class VoiceInteractor.CompleteVoiceRequest extends android.app.VoiceInteractor.Request {
-    ctor public VoiceInteractor.CompleteVoiceRequest(java.lang.CharSequence, android.os.Bundle);
-    method public void onCompleteResult(android.os.Bundle);
-  }
-
-  public static class VoiceInteractor.ConfirmationRequest extends android.app.VoiceInteractor.Request {
-    ctor public VoiceInteractor.ConfirmationRequest(java.lang.CharSequence, android.os.Bundle);
-    method public void onConfirmationResult(boolean, android.os.Bundle);
-  }
-
-  public static abstract class VoiceInteractor.Request {
-    ctor public VoiceInteractor.Request();
-    method public void cancel();
-    method public android.app.Activity getActivity();
-    method public android.content.Context getContext();
-    method public void onAttached(android.app.Activity);
-    method public void onCancel();
-    method public void onDetached();
-  }
-
   public final class WallpaperInfo implements android.os.Parcelable {
     ctor public WallpaperInfo(android.content.Context, android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public int describeContents();
@@ -7718,7 +7682,6 @@
     field public static final java.lang.String ACTION_GET_RESTRICTION_ENTRIES = "android.intent.action.GET_RESTRICTION_ENTRIES";
     field public static final java.lang.String ACTION_GTALK_SERVICE_CONNECTED = "android.intent.action.GTALK_CONNECTED";
     field public static final java.lang.String ACTION_GTALK_SERVICE_DISCONNECTED = "android.intent.action.GTALK_DISCONNECTED";
-    field public static final java.lang.String ACTION_HDMI_AUDIO_PLUG = "android.intent.action.HDMI_AUDIO_PLUG";
     field public static final java.lang.String ACTION_HEADSET_PLUG = "android.intent.action.HEADSET_PLUG";
     field public static final java.lang.String ACTION_INPUT_METHOD_CHANGED = "android.intent.action.INPUT_METHOD_CHANGED";
     field public static final java.lang.String ACTION_INSERT = "android.intent.action.INSERT";
@@ -7827,7 +7790,6 @@
     field public static final java.lang.String CATEGORY_TAB = "android.intent.category.TAB";
     field public static final java.lang.String CATEGORY_TEST = "android.intent.category.TEST";
     field public static final java.lang.String CATEGORY_UNIT_TEST = "android.intent.category.UNIT_TEST";
-    field public static final java.lang.String CATEGORY_VOICE = "android.intent.category.VOICE";
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final java.lang.String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
     field public static final java.lang.String EXTRA_ALLOW_MULTIPLE = "android.intent.extra.ALLOW_MULTIPLE";
@@ -13273,7 +13235,7 @@
 
   public final class DisplayManager {
     method public android.hardware.display.VirtualDisplay createVirtualDisplay(java.lang.String, int, int, int, android.view.Surface, int);
-    method public android.hardware.display.VirtualDisplay createVirtualDisplay(java.lang.String, int, int, int, android.view.Surface, int, android.hardware.display.VirtualDisplay.Callbacks, android.os.Handler);
+    method public android.hardware.display.VirtualDisplay createVirtualDisplay(java.lang.String, int, int, int, android.view.Surface, int, android.hardware.display.VirtualDisplay.Callback, android.os.Handler);
     method public android.view.Display getDisplay(int);
     method public android.view.Display[] getDisplays();
     method public android.view.Display[] getDisplays(java.lang.String);
@@ -13301,11 +13263,11 @@
     method public void setSurface(android.view.Surface);
   }
 
-  public static abstract class VirtualDisplay.Callbacks {
-    ctor public VirtualDisplay.Callbacks();
-    method public void onDisplayPaused();
-    method public void onDisplayResumed();
-    method public void onDisplayStopped();
+  public static abstract class VirtualDisplay.Callback {
+    ctor public VirtualDisplay.Callback();
+    method public void onPaused();
+    method public void onResumed();
+    method public void onStopped();
   }
 
 }
@@ -14207,6 +14169,8 @@
     method public deprecated void unregisterRemoteControlClient(android.media.RemoteControlClient);
     method public deprecated void unregisterRemoteController(android.media.RemoteController);
     field public static final java.lang.String ACTION_AUDIO_BECOMING_NOISY = "android.media.AUDIO_BECOMING_NOISY";
+    field public static final java.lang.String ACTION_HDMI_AUDIO_PLUG = "android.media.action.HDMI_AUDIO_PLUG";
+    field public static final java.lang.String ACTION_HEADSET_PLUG = "android.intent.action.HEADSET_PLUG";
     field public static final deprecated java.lang.String ACTION_SCO_AUDIO_STATE_CHANGED = "android.media.SCO_AUDIO_STATE_CHANGED";
     field public static final java.lang.String ACTION_SCO_AUDIO_STATE_UPDATED = "android.media.ACTION_SCO_AUDIO_STATE_UPDATED";
     field public static final int ADJUST_LOWER = -1; // 0xffffffff
@@ -14224,6 +14188,9 @@
     field public static final int AUDIO_SESSION_ID_GENERATE = 0; // 0x0
     field public static final int ERROR = -1; // 0xffffffff
     field public static final int ERROR_DEAD_OBJECT = -6; // 0xfffffffa
+    field public static final java.lang.String EXTRA_AUDIO_PLUG_STATE = "android.media.extra.audio_plug_state";
+    field public static final java.lang.String EXTRA_ENCODINGS = "android.media.extra.encodings";
+    field public static final java.lang.String EXTRA_MAX_CHANNEL_COUNT = "android.media.extra.max_channel_count";
     field public static final java.lang.String EXTRA_RINGER_MODE = "android.media.EXTRA_RINGER_MODE";
     field public static final java.lang.String EXTRA_SCO_AUDIO_PREVIOUS_STATE = "android.media.extra.SCO_AUDIO_PREVIOUS_STATE";
     field public static final java.lang.String EXTRA_SCO_AUDIO_STATE = "android.media.extra.SCO_AUDIO_STATE";
@@ -16250,12 +16217,12 @@
     method public void connect();
     method public void disconnect();
     method public android.os.Bundle getExtras();
-    method public android.net.Uri getRoot();
+    method public java.lang.String getRoot();
     method public android.content.ComponentName getServiceComponent();
     method public android.media.session.MediaSession.Token getSessionToken();
     method public boolean isConnected();
-    method public void subscribe(android.net.Uri, android.media.browse.MediaBrowser.SubscriptionCallback);
-    method public void unsubscribe(android.net.Uri);
+    method public void subscribe(java.lang.String, android.media.browse.MediaBrowser.SubscriptionCallback);
+    method public void unsubscribe(java.lang.String);
   }
 
   public static class MediaBrowser.ConnectionCallback {
@@ -16281,8 +16248,8 @@
 
   public static abstract class MediaBrowser.SubscriptionCallback {
     ctor public MediaBrowser.SubscriptionCallback();
-    method public void onChildrenLoaded(android.net.Uri, java.util.List<android.media.browse.MediaBrowser.MediaItem>);
-    method public void onError(android.net.Uri);
+    method public void onChildrenLoaded(java.lang.String, java.util.List<android.media.browse.MediaBrowser.MediaItem>);
+    method public void onError(java.lang.String);
   }
 
 }
@@ -16346,7 +16313,7 @@
 
   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.Callbacks, 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 stop();
   }
@@ -17984,23 +17951,6 @@
     enum_constant public static final android.net.wifi.SupplicantState UNINITIALIZED;
   }
 
-  public class WifiAdapter implements android.os.Parcelable {
-    method public int describeContents();
-    method public java.lang.String getName();
-    method public boolean is5GHzBandSupported();
-    method public boolean isDeviceToApRttSupported();
-    method public boolean isDeviceToDeviceRttSupported();
-    method public boolean isEnhancedPowerReportingSupported();
-    method public boolean isOffChannelTdlsSupported();
-    method public boolean isP2pSupported();
-    method public boolean isPasspointSupported();
-    method public boolean isPortableHotspotSupported();
-    method public boolean isPreferredNetworkOffloadSupported();
-    method public boolean isTdlsSupported();
-    method public boolean isWifiScannerSupported();
-    method public void writeToParcel(android.os.Parcel, int);
-  }
-
   public class WifiConfiguration implements android.os.Parcelable {
     ctor public WifiConfiguration();
     method public int describeContents();
@@ -18134,7 +18084,7 @@
   public class WifiManager {
     method public int addNetwork(android.net.wifi.WifiConfiguration);
     method public static int calculateSignalLevel(int, int);
-    method public void cancelWps(android.net.wifi.WifiManager.ActionListener);
+    method public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
     method public static int compareSignalLevel(int, int);
     method public android.net.wifi.WifiManager.MulticastLock createMulticastLock(java.lang.String);
     method public android.net.wifi.WifiManager.WifiLock createWifiLock(int, java.lang.String);
@@ -18142,13 +18092,18 @@
     method public boolean disableNetwork(int);
     method public boolean disconnect();
     method public boolean enableNetwork(int, boolean);
-    method public java.util.List<android.net.wifi.WifiAdapter> getAdapters();
     method public java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
     method public android.net.wifi.WifiInfo getConnectionInfo();
     method public android.net.DhcpInfo getDhcpInfo();
     method public java.util.List<android.net.wifi.ScanResult> getScanResults();
     method public int getWifiState();
+    method public boolean is5GHzBandSupported();
+    method public boolean isDeviceToApRttSupported();
+    method public boolean isEnhancedPowerReportingSupported();
+    method public boolean isP2pSupported();
+    method public boolean isPreferredNetworkOffloadSupported();
     method public boolean isScanAlwaysAvailable();
+    method public boolean isTdlsSupported();
     method public boolean isWifiEnabled();
     method public boolean pingSupplicant();
     method public boolean reassociate();
@@ -18159,12 +18114,10 @@
     method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
     method public boolean setWifiEnabled(boolean);
     method public boolean startScan();
-    method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsListener);
+    method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
     method public int updateNetwork(android.net.wifi.WifiConfiguration);
     field public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
     field public static final java.lang.String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
-    field public static final int BUSY = 2; // 0x2
-    field public static final int ERROR = 0; // 0x0
     field public static final int ERROR_AUTHENTICATING = 1; // 0x1
     field public static final java.lang.String EXTRA_BSSID = "bssid";
     field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
@@ -18175,8 +18128,6 @@
     field public static final java.lang.String EXTRA_SUPPLICANT_ERROR = "supplicantError";
     field public static final java.lang.String EXTRA_WIFI_INFO = "wifiInfo";
     field public static final java.lang.String EXTRA_WIFI_STATE = "wifi_state";
-    field public static final int INVALID_ARGS = 8; // 0x8
-    field public static final int IN_PROGRESS = 1; // 0x1
     field public static final java.lang.String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
     field public static final java.lang.String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE";
     field public static final java.lang.String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
@@ -18199,11 +18150,6 @@
     field public static final int WPS_WEP_PROHIBITED = 4; // 0x4
   }
 
-  public static abstract interface WifiManager.ActionListener {
-    method public abstract void onFailure(int);
-    method public abstract void onSuccess();
-  }
-
   public class WifiManager.MulticastLock {
     method public void acquire();
     method public boolean isHeld();
@@ -18219,10 +18165,11 @@
     method public void setWorkSource(android.os.WorkSource);
   }
 
-  public static abstract interface WifiManager.WpsListener {
-    method public abstract void onCompletion();
-    method public abstract void onFailure(int);
-    method public abstract void onStartSuccess(java.lang.String);
+  public static abstract class WifiManager.WpsCallback {
+    ctor public WifiManager.WpsCallback();
+    method public abstract void onFailed(int);
+    method public abstract void onStarted(java.lang.String);
+    method public abstract void onSucceeded();
   }
 
   public class WpsInfo implements android.os.Parcelable {
@@ -25330,14 +25277,12 @@
     field public static final java.lang.String ACTION_SYNC_SETTINGS = "android.settings.SYNC_SETTINGS";
     field public static final java.lang.String ACTION_USAGE_ACCESS_SETTINGS = "android.settings.USAGE_ACCESS_SETTINGS";
     field public static final java.lang.String ACTION_USER_DICTIONARY_SETTINGS = "android.settings.USER_DICTIONARY_SETTINGS";
-    field public static final java.lang.String ACTION_VOICE_CONTROL_AIRPLANE_MODE = "android.settings.VOICE_CONTROL_AIRPLANE_MODE";
     field public static final java.lang.String ACTION_VOICE_INPUT_SETTINGS = "android.settings.VOICE_INPUT_SETTINGS";
     field public static final java.lang.String ACTION_WIFI_IP_SETTINGS = "android.settings.WIFI_IP_SETTINGS";
     field public static final java.lang.String ACTION_WIFI_SETTINGS = "android.settings.WIFI_SETTINGS";
     field public static final java.lang.String ACTION_WIRELESS_SETTINGS = "android.settings.WIRELESS_SETTINGS";
     field public static final java.lang.String AUTHORITY = "settings";
     field public static final java.lang.String EXTRA_ACCOUNT_TYPES = "account_types";
-    field public static final java.lang.String EXTRA_AIRPLANE_MODE_ENABLED = "airplane_mode_enabled";
     field public static final java.lang.String EXTRA_AUTHORITIES = "authorities";
     field public static final java.lang.String EXTRA_INPUT_METHOD_ID = "input_method_id";
   }
@@ -27063,18 +27008,18 @@
     ctor public MediaBrowserService();
     method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
     method public android.media.session.MediaSession.Token getSessionToken();
-    method public void notifyChildrenChanged(android.net.Uri);
+    method public void notifyChildrenChanged(java.lang.String);
     method public android.os.IBinder onBind(android.content.Intent);
     method public abstract android.service.media.MediaBrowserService.BrowserRoot onGetRoot(java.lang.String, int, android.os.Bundle);
-    method public abstract void onLoadChildren(android.net.Uri, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>);
+    method public abstract void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>);
     method public void setSessionToken(android.media.session.MediaSession.Token);
     field public static final java.lang.String SERVICE_ACTION = "android.media.browse.MediaBrowserService";
   }
 
   public static final class MediaBrowserService.BrowserRoot {
-    ctor public MediaBrowserService.BrowserRoot(android.net.Uri, android.os.Bundle);
+    ctor public MediaBrowserService.BrowserRoot(java.lang.String, android.os.Bundle);
     method public android.os.Bundle getExtras();
-    method public android.net.Uri getRootUri();
+    method public java.lang.String getRootId();
   }
 
   public class MediaBrowserService.Result {
@@ -27235,52 +27180,14 @@
     ctor public VoiceInteractionSession(android.content.Context);
     ctor public VoiceInteractionSession(android.content.Context, android.os.Handler);
     method public void finish();
-    method public android.view.LayoutInflater getLayoutInflater();
-    method public android.app.Dialog getWindow();
-    method public void hideWindow();
-    method public void onAbortVoice(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.os.Bundle);
-    method public void onBackPressed();
-    method public abstract void onCancel(android.service.voice.VoiceInteractionSession.Request);
     method public void onCloseSystemDialogs();
-    method public abstract void onCommand(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.String, android.os.Bundle);
-    method public void onCompleteVoice(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.os.Bundle);
-    method public void onComputeInsets(android.service.voice.VoiceInteractionSession.Insets);
-    method public abstract void onConfirm(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.os.Bundle);
     method public void onCreate(android.os.Bundle);
-    method public android.view.View onCreateContentView();
     method public void onDestroy();
-    method public boolean[] onGetSupportedCommands(android.service.voice.VoiceInteractionSession.Caller, java.lang.String[]);
     method public boolean onKeyDown(int, android.view.KeyEvent);
     method public boolean onKeyLongPress(int, android.view.KeyEvent);
     method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
     method public boolean onKeyUp(int, android.view.KeyEvent);
-    method public void onTaskFinished(android.content.Intent, int);
-    method public void onTaskStarted(android.content.Intent, int);
     method public void setContentView(android.view.View);
-    method public void setTheme(int);
-    method public void showWindow();
-    method public void startVoiceActivity(android.content.Intent);
-  }
-
-  public static class VoiceInteractionSession.Caller {
-  }
-
-  public static final class VoiceInteractionSession.Insets {
-    ctor public VoiceInteractionSession.Insets();
-    field public static final int TOUCHABLE_INSETS_CONTENT = 1; // 0x1
-    field public static final int TOUCHABLE_INSETS_FRAME = 0; // 0x0
-    field public static final int TOUCHABLE_INSETS_REGION = 3; // 0x3
-    field public final android.graphics.Rect contentInsets;
-    field public int touchableInsets;
-    field public final android.graphics.Region touchableRegion;
-  }
-
-  public static class VoiceInteractionSession.Request {
-    method public void sendAbortVoiceResult(android.os.Bundle);
-    method public void sendCancelResult();
-    method public void sendCommandResult(boolean, android.os.Bundle);
-    method public void sendCompleteVoiceResult(android.os.Bundle);
-    method public void sendConfirmResult(boolean, android.os.Bundle);
   }
 
   public abstract class VoiceInteractionSessionService extends android.app.Service {
@@ -28774,44 +28681,6 @@
     field public static int STATUS_UNKNOWN_ERROR;
   }
 
-  public class MessagingConfigurationManager {
-    method public boolean getCarrierConfigBoolean(java.lang.String, boolean);
-    method public boolean getCarrierConfigBoolean(long, java.lang.String, boolean);
-    method public int getCarrierConfigInt(java.lang.String, int);
-    method public int getCarrierConfigInt(long, java.lang.String, int);
-    method public java.lang.String getCarrierConfigString(java.lang.String, java.lang.String);
-    method public java.lang.String getCarrierConfigString(long, java.lang.String, java.lang.String);
-    method public static android.telephony.MessagingConfigurationManager getDefault();
-    field public static final java.lang.String CONF_ALIAS_ENABLED = "aliasEnabled";
-    field public static final java.lang.String CONF_ALIAS_MAX_CHARS = "aliasMaxChars";
-    field public static final java.lang.String CONF_ALIAS_MIN_CHARS = "aliasMinChars";
-    field public static final java.lang.String CONF_ALLOW_ATTACH_AUDIO = "allowAttachAudio";
-    field public static final java.lang.String CONF_APPEND_TRANSACTION_ID = "enabledTransID";
-    field public static final java.lang.String CONF_EMAIL_GATEWAY_NUMBER = "emailGatewayNumber";
-    field public static final java.lang.String CONF_HTTP_PARAMS = "httpParams";
-    field public static final java.lang.String CONF_HTTP_SOCKET_TIMEOUT = "httpSocketTimeout";
-    field public static final java.lang.String CONF_MAX_IMAGE_HEIGHT = "maxImageHeight";
-    field public static final java.lang.String CONF_MAX_IMAGE_WIDTH = "maxImageWidth";
-    field public static final java.lang.String CONF_MAX_MESSAGE_SIZE = "maxMessageSize";
-    field public static final java.lang.String CONF_MESSAGE_TEXT_MAX_SIZE = "maxMessageTextSize";
-    field public static final java.lang.String CONF_MMS_DELIVERY_REPORT_ENABLED = "enableMMSDeliveryReports";
-    field public static final java.lang.String CONF_MMS_ENABLED = "enabledMMS";
-    field public static final java.lang.String CONF_MMS_READ_REPORT_ENABLED = "enableMMSReadReports";
-    field public static final java.lang.String CONF_MULTIPART_SMS_ENABLED = "enableMultipartSMS";
-    field public static final java.lang.String CONF_NAI_SUFFIX = "naiSuffix";
-    field public static final java.lang.String CONF_NOTIFY_WAP_MMSC_ENABLED = "enabledNotifyWapMMSC";
-    field public static final java.lang.String CONF_RECIPIENT_LIMIT = "recipientLimit";
-    field public static final java.lang.String CONF_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES = "sendMultipartSmsAsSeparateMessages";
-    field public static final java.lang.String CONF_SMS_DELIVERY_REPORT_ENABLED = "enableSMSDeliveryReports";
-    field public static final java.lang.String CONF_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD = "smsToMmsTextLengthThreshold";
-    field public static final java.lang.String CONF_SMS_TO_MMS_TEXT_THRESHOLD = "smsToMmsTextThreshold";
-    field public static final java.lang.String CONF_SUBJECT_MAX_LENGTH = "maxSubjectLength";
-    field public static final java.lang.String CONF_SUPPORT_MMS_CONTENT_DISPOSITION = "supportMmsContentDisposition";
-    field public static final java.lang.String CONF_UA_PROF_TAG_NAME = "uaProfTagName";
-    field public static final java.lang.String CONF_UA_PROF_URL = "uaProfUrl";
-    field public static final java.lang.String CONF_USER_AGENT = "userAgent";
-  }
-
   public class NeighboringCellInfo implements android.os.Parcelable {
     ctor public deprecated NeighboringCellInfo();
     ctor public deprecated NeighboringCellInfo(int, int);
@@ -28961,28 +28830,54 @@
     method public boolean deleteStoredMessage(android.net.Uri);
     method public java.util.ArrayList<java.lang.String> divideMessage(java.lang.String);
     method public void downloadMultimediaMessage(java.lang.String, android.content.ContentValues, android.app.PendingIntent);
-    method public void downloadMultimediaMessage(long, java.lang.String, android.content.ContentValues, android.app.PendingIntent);
     method public boolean getAutoPersisting();
+    method public android.os.Bundle getCarrierConfigValues();
     method public static android.telephony.SmsManager getDefault();
+    method public static android.telephony.SmsManager getSmsManagerForSubId(long);
+    method public long getSubId();
     method public android.net.Uri importMultimediaMessage(byte[], java.lang.String, long, boolean, boolean);
     method public android.net.Uri importTextMessage(java.lang.String, int, java.lang.String, long, boolean, boolean);
     method public void injectSmsPdu(byte[], java.lang.String, android.app.PendingIntent);
     method public void sendDataMessage(java.lang.String, java.lang.String, short, byte[], android.app.PendingIntent, android.app.PendingIntent);
     method public void sendMultimediaMessage(byte[], java.lang.String, android.content.ContentValues, android.app.PendingIntent);
-    method public void sendMultimediaMessage(long, byte[], java.lang.String, android.content.ContentValues, android.app.PendingIntent);
     method public void sendMultipartTextMessage(java.lang.String, java.lang.String, java.util.ArrayList<java.lang.String>, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
     method public void sendStoredMultimediaMessage(android.net.Uri, android.content.ContentValues, android.app.PendingIntent);
-    method public void sendStoredMultimediaMessage(long, android.net.Uri, android.content.ContentValues, android.app.PendingIntent);
     method public void sendStoredMultipartTextMessage(android.net.Uri, java.lang.String, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
-    method public void sendStoredMultipartTextMessage(long, android.net.Uri, java.lang.String, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
     method public void sendStoredTextMessage(android.net.Uri, java.lang.String, android.app.PendingIntent, android.app.PendingIntent);
-    method public void sendStoredTextMessage(long, android.net.Uri, java.lang.String, android.app.PendingIntent, android.app.PendingIntent);
     method public void sendTextMessage(java.lang.String, java.lang.String, java.lang.String, android.app.PendingIntent, android.app.PendingIntent);
     method public void setAutoPersisting(boolean);
     method public void updateMmsDownloadStatus(int, byte[]);
     method public void updateMmsSendStatus(int, boolean);
     method public void updateSmsSendStatus(int, boolean);
     method public boolean updateStoredMessageStatus(android.net.Uri, android.content.ContentValues);
+    field public static final java.lang.String MMS_CONFIG_ALIAS_ENABLED = "aliasEnabled";
+    field public static final java.lang.String MMS_CONFIG_ALIAS_MAX_CHARS = "aliasMaxChars";
+    field public static final java.lang.String MMS_CONFIG_ALIAS_MIN_CHARS = "aliasMinChars";
+    field public static final java.lang.String MMS_CONFIG_ALLOW_ATTACH_AUDIO = "allowAttachAudio";
+    field public static final java.lang.String MMS_CONFIG_APPEND_TRANSACTION_ID = "enabledTransID";
+    field public static final java.lang.String MMS_CONFIG_EMAIL_GATEWAY_NUMBER = "emailGatewayNumber";
+    field public static final java.lang.String MMS_CONFIG_HTTP_PARAMS = "httpParams";
+    field public static final java.lang.String MMS_CONFIG_HTTP_SOCKET_TIMEOUT = "httpSocketTimeout";
+    field public static final java.lang.String MMS_CONFIG_MAX_IMAGE_HEIGHT = "maxImageHeight";
+    field public static final java.lang.String MMS_CONFIG_MAX_IMAGE_WIDTH = "maxImageWidth";
+    field public static final java.lang.String MMS_CONFIG_MAX_MESSAGE_SIZE = "maxMessageSize";
+    field public static final java.lang.String MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE = "maxMessageTextSize";
+    field public static final java.lang.String MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED = "enableMMSDeliveryReports";
+    field public static final java.lang.String MMS_CONFIG_MMS_ENABLED = "enabledMMS";
+    field public static final java.lang.String MMS_CONFIG_MMS_READ_REPORT_ENABLED = "enableMMSReadReports";
+    field public static final java.lang.String MMS_CONFIG_MULTIPART_SMS_ENABLED = "enableMultipartSMS";
+    field public static final java.lang.String MMS_CONFIG_NAI_SUFFIX = "naiSuffix";
+    field public static final java.lang.String MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED = "enabledNotifyWapMMSC";
+    field public static final java.lang.String MMS_CONFIG_RECIPIENT_LIMIT = "recipientLimit";
+    field public static final java.lang.String MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES = "sendMultipartSmsAsSeparateMessages";
+    field public static final java.lang.String MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED = "enableSMSDeliveryReports";
+    field public static final java.lang.String MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD = "smsToMmsTextLengthThreshold";
+    field public static final java.lang.String MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD = "smsToMmsTextThreshold";
+    field public static final java.lang.String MMS_CONFIG_SUBJECT_MAX_LENGTH = "maxSubjectLength";
+    field public static final java.lang.String MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION = "supportMmsContentDisposition";
+    field public static final java.lang.String MMS_CONFIG_UA_PROF_TAG_NAME = "uaProfTagName";
+    field public static final java.lang.String MMS_CONFIG_UA_PROF_URL = "uaProfUrl";
+    field public static final java.lang.String MMS_CONFIG_USER_AGENT = "userAgent";
     field public static final java.lang.String MESSAGE_STATUS_READ = "read";
     field public static final java.lang.String MESSAGE_STATUS_SEEN = "seen";
     field public static final int MMS_ERROR_HTTP_FAILURE = 4; // 0x4
@@ -35903,7 +35798,7 @@
     method public boolean performPrivateCommand(java.lang.String, android.os.Bundle);
     method public static final void removeComposingSpans(android.text.Spannable);
     method public boolean reportFullscreenMode(boolean);
-    method public boolean requestUpdateCursorAnchorInfo(int);
+    method public boolean requestCursorUpdates(int);
     method public boolean sendKeyEvent(android.view.KeyEvent);
     method public boolean setComposingRegion(int, int);
     method public static void setComposingSpans(android.text.Spannable);
@@ -35942,20 +35837,16 @@
     method public int getComposingTextStart();
     method public float getInsertionMarkerBaseline();
     method public float getInsertionMarkerBottom();
+    method public int getInsertionMarkerFlags();
     method public float getInsertionMarkerHorizontal();
     method public float getInsertionMarkerTop();
     method public android.graphics.Matrix getMatrix();
     method public int getSelectionEnd();
     method public int getSelectionStart();
-    method public boolean isInsertionMarkerClipped();
     method public void writeToParcel(android.os.Parcel, int);
-    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
     field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int FLAG_HAS_INVISIBLE_REGION = 2; // 0x2
+    field public static final int FLAG_HAS_VISIBLE_REGION = 1; // 0x1
   }
 
   public static final class CursorAnchorInfo.Builder {
@@ -35964,7 +35855,7 @@
     method public android.view.inputmethod.CursorAnchorInfo build();
     method public void reset();
     method public android.view.inputmethod.CursorAnchorInfo.Builder setComposingText(int, java.lang.CharSequence);
-    method public android.view.inputmethod.CursorAnchorInfo.Builder setInsertionMarkerLocation(float, float, float, float, boolean);
+    method public android.view.inputmethod.CursorAnchorInfo.Builder setInsertionMarkerLocation(float, float, float, float, int);
     method public android.view.inputmethod.CursorAnchorInfo.Builder setMatrix(android.graphics.Matrix);
     method public android.view.inputmethod.CursorAnchorInfo.Builder setSelectionRange(int, int);
   }
@@ -36066,15 +35957,15 @@
     method public abstract boolean performEditorAction(int);
     method public abstract boolean performPrivateCommand(java.lang.String, android.os.Bundle);
     method public abstract boolean reportFullscreenMode(boolean);
-    method public abstract boolean requestUpdateCursorAnchorInfo(int);
+    method public abstract boolean requestCursorUpdates(int);
     method public abstract boolean sendKeyEvent(android.view.KeyEvent);
     method public abstract boolean setComposingRegion(int, int);
     method public abstract boolean setComposingText(java.lang.CharSequence, int);
     method public abstract boolean setSelection(int, int);
+    field public static final int CURSOR_UPDATE_IMMEDIATE = 1; // 0x1
+    field public static final int CURSOR_UPDATE_MONITOR = 2; // 0x2
     field public static final int GET_EXTRACTED_TEXT_MONITOR = 1; // 0x1
     field public static final int GET_TEXT_WITH_STYLES = 1; // 0x1
-    field public static final int REQUEST_UPDATE_CURSOR_ANCHOR_INFO_IMMEDIATE = 1; // 0x1
-    field public static final int REQUEST_UPDATE_CURSOR_ANCHOR_INFO_MONITOR = 2; // 0x2
   }
 
   public class InputConnectionWrapper implements android.view.inputmethod.InputConnection {
@@ -36096,7 +35987,7 @@
     method public boolean performEditorAction(int);
     method public boolean performPrivateCommand(java.lang.String, android.os.Bundle);
     method public boolean reportFullscreenMode(boolean);
-    method public boolean requestUpdateCursorAnchorInfo(int);
+    method public boolean requestCursorUpdates(int);
     method public boolean sendKeyEvent(android.view.KeyEvent);
     method public boolean setComposingRegion(int, int);
     method public boolean setComposingText(java.lang.CharSequence, int);
diff --git a/api/removed.txt b/api/removed.txt
index 8915fc3..a910e78 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -48,6 +48,38 @@
 
 }
 
+package android.view.inputmethod {
+
+  public class BaseInputConnection implements android.view.inputmethod.InputConnection {
+    method public final boolean requestUpdateCursorAnchorInfo(int);
+  }
+
+  public final class CursorAnchorInfo implements android.os.Parcelable {
+    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 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);
+  }
+
+}
+
 package com.android.internal {
 
   public static final class R.attr {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 2503d17..8ab344e 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1236,18 +1236,22 @@
     }
 
     /**
+     * @hide
      * Check whether this activity is running as part of a voice interaction with the user.
      * If true, it should perform its interaction with the user through the
      * {@link VoiceInteractor} returned by {@link #getVoiceInteractor}.
      */
+    @SystemApi
     public boolean isVoiceInteraction() {
         return mVoiceInteractor != null;
     }
 
     /**
+     * @hide
      * Retrieve the active {@link VoiceInteractor} that the user is going through to
      * interact with this activity.
      */
+    @SystemApi
     public VoiceInteractor getVoiceInteractor() {
         return mVoiceInteractor;
     }
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 66928ca..ba9c9d6 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -220,6 +220,9 @@
     /** Continually monitoring location data with a relatively high power request. */
     public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
             = "android:monitor_location_high_power";
+    /** Access to {@link android.app.usage.UsageStatsManager}. */
+    public static final String OPSTR_GET_USAGE_STATS
+            = "android:get_usage_stats";
     /** Activate a VPN connection without user intervention. @hide */
     @SystemApi
     public static final String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
@@ -331,7 +334,7 @@
             null,
             OPSTR_MONITOR_LOCATION,
             OPSTR_MONITOR_HIGH_POWER_LOCATION,
-            null,
+            OPSTR_GET_USAGE_STATS,
             null,
             null,
             null,
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index f31800d..3760b96 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -19,6 +19,7 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.content.Intent;
+import android.graphics.Color;
 import android.graphics.Matrix;
 import android.graphics.RectF;
 import android.graphics.drawable.ColorDrawable;
@@ -222,10 +223,7 @@
             delayCancel();
             moveSharedElementsToOverlay();
             if (getDecor().getBackground() == null) {
-                ColorDrawable black = new ColorDrawable(0xFF000000);
-                black.setAlpha(0);
-                getWindow().setBackgroundDrawable(black);
-                black.setAlpha(255);
+                getWindow().setBackgroundDrawable(new ColorDrawable(Color.BLACK));
             }
             ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(mActivity, this,
                     mAllSharedElementNames, resultCode, data);
diff --git a/core/java/android/app/VoiceInteractor.java b/core/java/android/app/VoiceInteractor.java
index dcdfd78..723cb9b 100644
--- a/core/java/android/app/VoiceInteractor.java
+++ b/core/java/android/app/VoiceInteractor.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -33,6 +34,7 @@
 import java.util.ArrayList;
 
 /**
+ * @hide
  * Interface for an {@link Activity} to interact with the user through voice.  Use
  * {@link android.app.Activity#getVoiceInteractor() Activity.getVoiceInteractor}
  * to retrieve the interface, if the activity is currently involved in a voice interaction.
@@ -54,6 +56,7 @@
  * request, rather than holding on to the activity instance yourself, either explicitly
  * or implicitly through a non-static inner class.
  */
+@SystemApi
 public class VoiceInteractor {
     static final String TAG = "VoiceInteractor";
     static final boolean DEBUG = true;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 61e105b..b825c94 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2216,104 +2216,14 @@
     /**
      * Broadcast Action: Wired Headset plugged in or unplugged.
      *
-     * You <em>cannot</em> receive this through components declared
-     * in manifests, only by explicitly registering for it with
-     * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
-     * Context.registerReceiver()}.
-     *
-     * <p>The intent will have the following extra values:
-     * <ul>
-     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
-     *   <li><em>name</em> - Headset type, human readable string </li>
-     *   <li><em>microphone</em> - 1 if headset has a microphone, 0 otherwise </li>
-     * </ul>
-     * </ul>
+     * Same as {@link android.media.AudioManager#ACTION_HEADSET_PLUG}, to be consulted for value
+     *   and documentation.
+     * <p>If the minimum SDK version of your application is
+     * {@link android.os.Build.VERSION_CODES#L}, it is recommended to refer
+     * to the <code>AudioManager</code> constant in your receiver registration code instead.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_HEADSET_PLUG =
-            "android.intent.action.HEADSET_PLUG";
-
-    /**
-     * Broadcast Action: An analog audio speaker/headset plugged in or unplugged.
-     *
-     * <p>The intent will have the following extra values:
-     * <ul>
-     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
-     *   <li><em>name</em> - Headset type, human readable string </li>
-     * </ul>
-     * </ul>
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_ANALOG_AUDIO_DOCK_PLUG =
-            "android.intent.action.ANALOG_AUDIO_DOCK_PLUG";
-
-    /**
-     * Broadcast Action: A digital audio speaker/headset plugged in or unplugged.
-     *
-     * <p>The intent will have the following extra values:
-     * <ul>
-     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
-     *   <li><em>name</em> - Headset type, human readable string </li>
-     * </ul>
-     * </ul>
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_DIGITAL_AUDIO_DOCK_PLUG =
-            "android.intent.action.DIGITAL_AUDIO_DOCK_PLUG";
-
-    /**
-     * Broadcast Action: A sticky broadcast indicating an HMDI cable was plugged or unplugged
-     *
-     * <p>The intent will have the following extra values:
-     * <ul>
-     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
-     *   <li><em>name</em> - HDMI cable, human readable string </li>
-     *   <li><em>maxChannelCount</em> - the maximum number of output channels supported by the
-     *       connected HDMI device, only available when <i>state</i> is 1.</li>
-     *   <li><em>encodings</em> - an array of formats supported by the connected HDMI device,
-     *       only available when <i>state</i> is 1. Encoding values are defined in
-     *       {@link android.media.AudioFormat} (for instance see
-     *       {@link android.media.AudioFormat#ENCODING_PCM_16BIT}). Use
-     *       {@link #getIntArrayExtra(String)} to retrieve the encoding values.</li>
-     * </ul>
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_HDMI_AUDIO_PLUG =
-            "android.intent.action.HDMI_AUDIO_PLUG";
-
-    /**
-     * Broadcast Action: A USB audio accessory was plugged in or unplugged.
-     *
-     * <p>The intent will have the following extra values:
-     * <ul>
-     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
-     *   <li><em>card</em> - ALSA card number (integer) </li>
-     *   <li><em>device</em> - ALSA device number (integer) </li>
-     * </ul>
-     * </ul>
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_USB_AUDIO_ACCESSORY_PLUG =
-            "android.intent.action.USB_AUDIO_ACCESSORY_PLUG";
-
-    /**
-     * Broadcast Action: A USB audio device was plugged in or unplugged.
-     *
-     * <p>The intent will have the following extra values:
-     * <ul>
-     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
-     *   <li><em>card</em> - ALSA card number (integer) </li>
-     *   <li><em>device</em> - ALSA device number (integer) </li>
-     * </ul>
-     * </ul>
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_USB_AUDIO_DEVICE_PLUG =
-            "android.intent.action.USB_AUDIO_DEVICE_PLUG";
+    public static final String ACTION_HEADSET_PLUG = android.media.AudioManager.ACTION_HEADSET_PLUG;
 
     /**
      * <p>Broadcast Action: The user has switched on advanced settings in the settings app:</p>
@@ -2833,12 +2743,14 @@
     @SdkConstant(SdkConstantType.INTENT_CATEGORY)
     public static final String CATEGORY_BROWSABLE = "android.intent.category.BROWSABLE";
     /**
+     * @hide
      * Categories for activities that can participate in voice interaction.
      * An activity that supports this category must be prepared to run with
      * no UI shown at all (though in some case it may have a UI shown), and
      * rely on {@link android.app.VoiceInteractor} to interact with the user.
      */
     @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+    @SystemApi
     public static final String CATEGORY_VOICE = "android.intent.category.VOICE";
     /**
      * Set if the activity should be considered as an alternative action to
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 51b7229..b077e06 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -472,7 +472,7 @@
     /**
      * Creates a virtual display.
      *
-     * @see #createVirtualDisplay(String, int, int, int, Surface, int, VirtualDisplay.Callbacks)
+     * @see #createVirtualDisplay(String, int, int, int, Surface, int, VirtualDisplay.Callback)
      */
     public VirtualDisplay createVirtualDisplay(@NonNull String name,
             int width, int height, int densityDpi, @Nullable Surface surface, int flags) {
@@ -513,7 +513,7 @@
      * {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}, {@link #VIRTUAL_DISPLAY_FLAG_PRESENTATION},
      * {@link #VIRTUAL_DISPLAY_FLAG_SECURE}, {@link #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY},
      * or {@link #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR}.
-     * @param callbacks Callbacks to call when the state of the {@link VirtualDisplay} changes
+     * @param callback Callback to call when the state of the {@link VirtualDisplay} changes
      * @param handler The handler on which the listener should be invoked, or null
      * if the listener should be invoked on the calling thread's looper.
      * @return The newly created virtual display, or null if the application could
@@ -524,17 +524,17 @@
      */
     public VirtualDisplay createVirtualDisplay(@NonNull String name,
             int width, int height, int densityDpi, @Nullable Surface surface, int flags,
-            @Nullable VirtualDisplay.Callbacks callbacks, @Nullable Handler handler) {
+            @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
         return createVirtualDisplay(null,
-                name, width, height, densityDpi, surface, flags, callbacks, handler);
+                name, width, height, densityDpi, surface, flags, callback, handler);
     }
 
     /** @hide */
     public VirtualDisplay createVirtualDisplay(@Nullable MediaProjection projection,
             @NonNull String name, int width, int height, int densityDpi, @Nullable Surface surface,
-            int flags, @Nullable VirtualDisplay.Callbacks callbacks, @Nullable Handler handler) {
+            int flags, @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
         return mGlobal.createVirtualDisplay(mContext, projection,
-                name, width, height, densityDpi, surface, flags, callbacks, handler);
+                name, width, height, densityDpi, surface, flags, callback, handler);
     }
 
     /**
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 8b44f3b..0051ef5 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -372,7 +372,7 @@
 
     public VirtualDisplay createVirtualDisplay(Context context, MediaProjection projection,
             String name, int width, int height, int densityDpi, Surface surface, int flags,
-            VirtualDisplay.Callbacks callbacks, Handler handler) {
+            VirtualDisplay.Callback callback, Handler handler) {
         if (TextUtils.isEmpty(name)) {
             throw new IllegalArgumentException("name must be non-null and non-empty");
         }
@@ -381,7 +381,7 @@
                     + "greater than 0");
         }
 
-        VirtualDisplayCallbacks callbackWrapper = new VirtualDisplayCallbacks(callbacks, handler);
+        VirtualDisplayCallback callbackWrapper = new VirtualDisplayCallback(callback, handler);
         IMediaProjection projectionToken = projection != null ? projection.getProjection() : null;
         int displayId;
         try {
@@ -408,7 +408,7 @@
         return new VirtualDisplay(this, display, callbackWrapper, surface);
     }
 
-    public void setVirtualDisplaySurface(IVirtualDisplayCallbacks token, Surface surface) {
+    public void setVirtualDisplaySurface(IVirtualDisplayCallback token, Surface surface) {
         try {
             mDm.setVirtualDisplaySurface(token, surface);
         } catch (RemoteException ex) {
@@ -416,7 +416,7 @@
         }
     }
 
-    public void resizeVirtualDisplay(IVirtualDisplayCallbacks token,
+    public void resizeVirtualDisplay(IVirtualDisplayCallback token,
             int width, int height, int densityDpi) {
         try {
             mDm.resizeVirtualDisplay(token, width, height, densityDpi);
@@ -425,7 +425,7 @@
         }
     }
 
-    public void releaseVirtualDisplay(IVirtualDisplayCallbacks token) {
+    public void releaseVirtualDisplay(IVirtualDisplayCallback token) {
         try {
             mDm.releaseVirtualDisplay(token);
         } catch (RemoteException ex) {
@@ -476,61 +476,61 @@
         }
     }
 
-    private final static class VirtualDisplayCallbacks extends IVirtualDisplayCallbacks.Stub {
-        private VirtualDisplayCallbacksDelegate mDelegate;
+    private final static class VirtualDisplayCallback extends IVirtualDisplayCallback.Stub {
+        private VirtualDisplayCallbackDelegate mDelegate;
 
-        public VirtualDisplayCallbacks(VirtualDisplay.Callbacks callbacks, Handler handler) {
-            if (callbacks != null) {
-                mDelegate = new VirtualDisplayCallbacksDelegate(callbacks, handler);
+        public VirtualDisplayCallback(VirtualDisplay.Callback callback, Handler handler) {
+            if (callback != null) {
+                mDelegate = new VirtualDisplayCallbackDelegate(callback, handler);
             }
         }
 
         @Override // Binder call
-        public void onDisplayPaused() {
+        public void onPaused() {
             if (mDelegate != null) {
-                mDelegate.sendEmptyMessage(VirtualDisplayCallbacksDelegate.MSG_DISPLAY_PAUSED);
+                mDelegate.sendEmptyMessage(VirtualDisplayCallbackDelegate.MSG_DISPLAY_PAUSED);
             }
         }
 
         @Override // Binder call
-        public void onDisplayResumed() {
+        public void onResumed() {
             if (mDelegate != null) {
-                mDelegate.sendEmptyMessage(VirtualDisplayCallbacksDelegate.MSG_DISPLAY_RESUMED);
+                mDelegate.sendEmptyMessage(VirtualDisplayCallbackDelegate.MSG_DISPLAY_RESUMED);
             }
         }
 
         @Override // Binder call
-        public void onDisplayStopped() {
+        public void onStopped() {
             if (mDelegate != null) {
-                mDelegate.sendEmptyMessage(VirtualDisplayCallbacksDelegate.MSG_DISPLAY_STOPPED);
+                mDelegate.sendEmptyMessage(VirtualDisplayCallbackDelegate.MSG_DISPLAY_STOPPED);
             }
         }
     }
 
-    private final static class VirtualDisplayCallbacksDelegate extends Handler {
+    private final static class VirtualDisplayCallbackDelegate extends Handler {
         public static final int MSG_DISPLAY_PAUSED = 0;
         public static final int MSG_DISPLAY_RESUMED = 1;
         public static final int MSG_DISPLAY_STOPPED = 2;
 
-        private final VirtualDisplay.Callbacks mCallbacks;
+        private final VirtualDisplay.Callback mCallback;
 
-        public VirtualDisplayCallbacksDelegate(VirtualDisplay.Callbacks callbacks,
+        public VirtualDisplayCallbackDelegate(VirtualDisplay.Callback callback,
                 Handler handler) {
             super(handler != null ? handler.getLooper() : Looper.myLooper(), null, true /*async*/);
-            mCallbacks = callbacks;
+            mCallback = callback;
         }
 
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MSG_DISPLAY_PAUSED:
-                    mCallbacks.onDisplayPaused();
+                    mCallback.onPaused();
                     break;
                 case MSG_DISPLAY_RESUMED:
-                    mCallbacks.onDisplayResumed();
+                    mCallback.onResumed();
                     break;
                 case MSG_DISPLAY_STOPPED:
-                    mCallbacks.onDisplayStopped();
+                    mCallback.onStopped();
                     break;
             }
         }
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index cfaa5a0..4486dd4 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -17,7 +17,7 @@
 package android.hardware.display;
 
 import android.hardware.display.IDisplayManagerCallback;
-import android.hardware.display.IVirtualDisplayCallbacks;
+import android.hardware.display.IVirtualDisplayCallback;
 import android.hardware.display.WifiDisplay;
 import android.hardware.display.WifiDisplayStatus;
 import android.media.projection.IMediaProjection;
@@ -61,17 +61,17 @@
 
     // Requires CAPTURE_VIDEO_OUTPUT, CAPTURE_SECURE_VIDEO_OUTPUT, or an appropriate
     // MediaProjection token for certain combinations of flags.
-    int createVirtualDisplay(in IVirtualDisplayCallbacks callbacks,
+    int createVirtualDisplay(in IVirtualDisplayCallback callback,
             in IMediaProjection projectionToken, String packageName, String name,
             int width, int height, int densityDpi, in Surface surface, int flags);
 
     // No permissions required, but must be same Uid as the creator.
-    void resizeVirtualDisplay(in IVirtualDisplayCallbacks token,
+    void resizeVirtualDisplay(in IVirtualDisplayCallback token,
             int width, int height, int densityDpi);
 
     // No permissions required but must be same Uid as the creator.
-    void setVirtualDisplaySurface(in IVirtualDisplayCallbacks token, in Surface surface);
+    void setVirtualDisplaySurface(in IVirtualDisplayCallback token, in Surface surface);
 
     // No permissions required but must be same Uid as the creator.
-    void releaseVirtualDisplay(in IVirtualDisplayCallbacks token);
+    void releaseVirtualDisplay(in IVirtualDisplayCallback token);
 }
diff --git a/core/java/android/hardware/display/IVirtualDisplayCallbacks.aidl b/core/java/android/hardware/display/IVirtualDisplayCallback.aidl
similarity index 90%
rename from core/java/android/hardware/display/IVirtualDisplayCallbacks.aidl
rename to core/java/android/hardware/display/IVirtualDisplayCallback.aidl
index a1cdc01..c3490d17 100644
--- a/core/java/android/hardware/display/IVirtualDisplayCallbacks.aidl
+++ b/core/java/android/hardware/display/IVirtualDisplayCallback.aidl
@@ -16,20 +16,20 @@
 package android.hardware.display;
 
 /** @hide */
-oneway interface IVirtualDisplayCallbacks {
+oneway interface IVirtualDisplayCallback {
     /**
      * Called when the virtual display video projection has been
      * paused by the system or when the surface has been detached
      * by the application by calling setSurface(null).
      * The surface will not receive any more buffers while paused.
      */
-    void onDisplayPaused();
+    void onPaused();
 
     /**
      * Called when the virtual display video projection has been
      * resumed after having been paused.
      */
-    void onDisplayResumed();
+    void onResumed();
 
     /**
      * Called when the virtual display video projection has been
@@ -37,5 +37,5 @@
      * and it will never be resumed.  It is still the responsibility
      * of the application to release() the virtual display.
      */
-    void onDisplayStopped();
+    void onStopped();
 }
diff --git a/core/java/android/hardware/display/VirtualDisplay.java b/core/java/android/hardware/display/VirtualDisplay.java
index 1dd6978..4ddf10f 100644
--- a/core/java/android/hardware/display/VirtualDisplay.java
+++ b/core/java/android/hardware/display/VirtualDisplay.java
@@ -35,11 +35,11 @@
 public final class VirtualDisplay {
     private final DisplayManagerGlobal mGlobal;
     private final Display mDisplay;
-    private IVirtualDisplayCallbacks mToken;
+    private IVirtualDisplayCallback mToken;
     private Surface mSurface;
 
     VirtualDisplay(DisplayManagerGlobal global, Display display,
-            IVirtualDisplayCallbacks token, Surface surface) {
+            IVirtualDisplayCallback token, Surface surface) {
         mGlobal = global;
         mDisplay = display;
         mToken = token;
@@ -114,20 +114,20 @@
     /**
      * Interface for receiving information about a {@link VirtualDisplay}'s state changes.
      */
-    public static abstract class Callbacks {
+    public static abstract class Callback {
         /**
          * Called when the virtual display video projection has been
          * paused by the system or when the surface has been detached
          * by the application by calling setSurface(null).
          * The surface will not receive any more buffers while paused.
          */
-         public void onDisplayPaused() { }
+         public void onPaused() { }
 
         /**
          * Called when the virtual display video projection has been
          * resumed after having been paused.
          */
-         public void onDisplayResumed() { }
+         public void onResumed() { }
 
         /**
          * Called when the virtual display video projection has been
@@ -135,6 +135,6 @@
          * and it will never be resumed.  It is still the responsibility
          * of the application to release() the virtual display.
          */
-        public void onDisplayStopped() { }
+        public void onStopped() { }
     }
 }
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 4bfef41..3c219fd 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -685,6 +685,23 @@
     }
 
     /**
+     * Returns the {@link Network} object currently serving a given type, or
+     * null if the given type is not connected.
+     *
+     * <p>This method requires the caller to hold the permission
+     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
+     *
+     * @hide
+     */
+    public Network getNetworkForType(int networkType) {
+        try {
+            return mService.getNetworkForType(networkType);
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
      * Returns an array of all {@link Network} currently tracked by the
      * framework.
      *
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index b2fc3be..974c4cd 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -48,6 +48,7 @@
     NetworkInfo getNetworkInfo(int networkType);
     NetworkInfo getNetworkInfoForNetwork(in Network network);
     NetworkInfo[] getAllNetworkInfo();
+    Network getNetworkForType(int networkType);
     Network[] getAllNetworks();
 
     NetworkInfo getProvisioningOrActiveNetworkInfo();
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index d2a4728..e686be7 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -35,6 +35,7 @@
 import java.util.concurrent.atomic.AtomicReference;
 import javax.net.SocketFactory;
 
+import com.android.okhttp.ConnectionPool;
 import com.android.okhttp.HostResolver;
 import com.android.okhttp.OkHttpClient;
 
@@ -60,6 +61,17 @@
     private volatile OkHttpClient mOkHttpClient = null;
     private Object mLock = new Object();
 
+    // Default connection pool values. These are evaluated at startup, just
+    // like the OkHttp code. Also like the OkHttp code, we will throw parse
+    // exceptions at class loading time if the properties are set but are not
+    // valid integers.
+    private static final boolean httpKeepAlive =
+            Boolean.parseBoolean(System.getProperty("http.keepAlive", "true"));
+    private static final int httpMaxConnections =
+            httpKeepAlive ? Integer.parseInt(System.getProperty("http.maxConnections", "5")) : 0;
+    private static final long httpKeepAliveDurationMs =
+            Long.parseLong(System.getProperty("http.keepAliveDuration", "300000"));  // 5 minutes.
+
     /**
      * @hide
      */
@@ -183,6 +195,20 @@
         return mNetworkBoundSocketFactory;
     }
 
+    // TODO: This creates an OkHttpClient with its own connection pool for
+    // every Network object, instead of one for every NetId. This is
+    // suboptimal, because an app could potentially have more than one
+    // Network object for the same NetId, causing increased memory footprint
+    // and performance penalties due to lack of connection reuse (connection
+    // setup time, congestion window growth time, etc.).
+    //
+    // Instead, investigate only having one OkHttpClient for every NetId,
+    // perhaps by using a static HashMap of NetIds to OkHttpClient objects. The
+    // tricky part is deciding when to remove an OkHttpClient; a WeakHashMap
+    // shouldn't be used because whether a Network is referenced doesn't
+    // correlate with whether a new Network will be instantiated in the near
+    // future with the same NetID. A good solution would involve purging empty
+    // (or when all connections are timed out) ConnectionPools.
     private void maybeInitHttpClient() {
         if (mOkHttpClient == null) {
             synchronized (mLock) {
@@ -193,9 +219,12 @@
                             return Network.this.getAllByName(host);
                         }
                     };
+                    ConnectionPool pool = new ConnectionPool(httpMaxConnections,
+                                                             httpKeepAliveDurationMs);
                     mOkHttpClient = new OkHttpClient()
                             .setSocketFactory(getSocketFactory())
-                            .setHostResolver(hostResolver);
+                            .setHostResolver(hostResolver)
+                            .setConnectionPool(pool);
                 }
             }
         }
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index d279412..7664c95 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -128,14 +128,6 @@
     private boolean mIsAvailable;
 
     /**
-     * @param type network type
-     * @deprecated
-     * @hide because this constructor was only meant for internal use (and
-     * has now been superseded by the package-private constructor below).
-     */
-    public NetworkInfo(int type) {}
-
-    /**
      * @hide
      */
     public NetworkInfo(int type, int subtype, String typeName, String subtypeName) {
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 6d4a302..b3e28ea 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -19,6 +19,7 @@
 
 import android.net.InterfaceConfiguration;
 import android.net.INetworkManagementEventObserver;
+import android.net.Network;
 import android.net.NetworkStats;
 import android.net.RouteInfo;
 import android.net.UidRange;
@@ -164,10 +165,10 @@
     /**
      * Sets the list of DNS forwarders (in order of priority)
      */
-    void setDnsForwarders(in String[] dns);
+    void setDnsForwarders(in Network network, in String[] dns);
 
     /**
-     * Returns the list of DNS fowarders (in order of priority)
+     * Returns the list of DNS forwarders (in order of priority)
      */
     String[] getDnsForwarders();
 
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 713fcd8..3286627 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -52,4 +52,5 @@
     void removeRestrictions();
     void setDefaultGuestRestrictions(in Bundle restrictions);
     Bundle getDefaultGuestRestrictions();
+    boolean markGuestForDeletion(int userHandle);
 }
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index e215669..f793667 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -676,6 +676,22 @@
     }
 
     /**
+     * @hide
+     * Marks the guest user for deletion to allow a new guest to be created before deleting
+     * the current user who is a guest.
+     * @param userHandle
+     * @return
+     */
+    public boolean markGuestForDeletion(int userHandle) {
+        try {
+            return mService.markGuestForDeletion(userHandle);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not mark guest for deletion", re);
+            return false;
+        }
+    }
+
+    /**
      * Sets the user as enabled, if such an user exists.
      * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      * Note that the default is true, it's only that managed profiles might not be enabled.
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index d1fadd6..cf407f4 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -1518,10 +1518,14 @@
     static final int ENCRYPTION_STATE_NONE = 1;
     /** The volume has been encrypted succesfully. */
     static final int ENCRYPTION_STATE_OK = 0;
-    /** The volume is in a bad state. */
+    /** The volume is in a bad state.*/
     static final int ENCRYPTION_STATE_ERROR_UNKNOWN = -1;
-    /** The volume is in a bad state - partially encrypted. Data is likely irrecoverable. */
+    /** Encryption is incomplete */
     static final int ENCRYPTION_STATE_ERROR_INCOMPLETE = -2;
+    /** Encryption is incomplete and irrecoverable */
+    static final int ENCRYPTION_STATE_ERROR_INCONSISTENT = -3;
+    /** Underlying data is corrupt */
+    static final int ENCRYPTION_STATE_ERROR_CORRUPT = -4;
 
     /**
      * Determines the encryption state of the volume.
diff --git a/core/java/android/preference/CheckBoxPreference.java b/core/java/android/preference/CheckBoxPreference.java
index 1ce98b8..fee3f0f1 100644
--- a/core/java/android/preference/CheckBoxPreference.java
+++ b/core/java/android/preference/CheckBoxPreference.java
@@ -66,7 +66,6 @@
         View checkboxView = view.findViewById(com.android.internal.R.id.checkbox);
         if (checkboxView != null && checkboxView instanceof Checkable) {
             ((Checkable) checkboxView).setChecked(mChecked);
-            sendAccessibilityEvent(checkboxView);
         }
 
         syncSummaryView(view);
diff --git a/core/java/android/preference/SwitchPreference.java b/core/java/android/preference/SwitchPreference.java
index 46be928..53b5aad 100644
--- a/core/java/android/preference/SwitchPreference.java
+++ b/core/java/android/preference/SwitchPreference.java
@@ -130,8 +130,6 @@
 
             ((Checkable) checkableView).setChecked(mChecked);
 
-            sendAccessibilityEvent(checkableView);
-
             if (checkableView instanceof Switch) {
                 final Switch switchView = (Switch) checkableView;
                 switchView.setTextOn(mSwitchOn);
diff --git a/core/java/android/preference/TwoStatePreference.java b/core/java/android/preference/TwoStatePreference.java
index 6f8be1f..3823b27 100644
--- a/core/java/android/preference/TwoStatePreference.java
+++ b/core/java/android/preference/TwoStatePreference.java
@@ -24,8 +24,6 @@
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
 import android.widget.TextView;
 
 /**
@@ -39,7 +37,6 @@
     private CharSequence mSummaryOff;
     boolean mChecked;
     private boolean mCheckedSet;
-    private boolean mSendClickAccessibilityEvent;
     private boolean mDisableDependentsState;
 
     public TwoStatePreference(
@@ -63,15 +60,10 @@
     protected void onClick() {
         super.onClick();
 
-        boolean newValue = !isChecked();
-
-        mSendClickAccessibilityEvent = true;
-
-        if (!callChangeListener(newValue)) {
-            return;
+        final boolean newValue = !isChecked();
+        if (callChangeListener(newValue)) {
+            setChecked(newValue);
         }
-
-        setChecked(newValue);
     }
 
     /**
@@ -196,21 +188,6 @@
                 : (Boolean) defaultValue);
     }
 
-    void sendAccessibilityEvent(View view) {
-        // Since the view is still not attached we create, populate,
-        // and send the event directly since we do not know when it
-        // will be attached and posting commands is not as clean.
-        AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getContext());
-        if (mSendClickAccessibilityEvent && accessibilityManager.isEnabled()) {
-            AccessibilityEvent event = AccessibilityEvent.obtain();
-            event.setEventType(AccessibilityEvent.TYPE_VIEW_CLICKED);
-            view.onInitializeAccessibilityEvent(event);
-            view.dispatchPopulateAccessibilityEvent(event);
-            accessibilityManager.sendAccessibilityEvent(event);
-        }
-        mSendClickAccessibilityEvent = false;
-    }
-
     /**
      * Sync a summary view contained within view's subhierarchy with the correct summary text.
      * @param view View where a summary should be located
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 33e0468..f4c2dc8 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -18,6 +18,7 @@
 
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
 import android.app.SearchManager;
 import android.app.WallpaperManager;
 import android.content.ComponentName;
@@ -131,6 +132,7 @@
             "android.settings.AIRPLANE_MODE_SETTINGS";
 
     /**
+     * @hide
      * Activity Action: Modify Airplane mode settings using the users voice.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you safeguard against this.
@@ -152,6 +154,7 @@
      * Output: Nothing.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    @SystemApi
     public static final String ACTION_VOICE_CONTROL_AIRPLANE_MODE =
             "android.settings.VOICE_CONTROL_AIRPLANE_MODE";
 
@@ -975,11 +978,13 @@
     public static final String EXTRA_INPUT_METHOD_ID = "input_method_id";
 
     /**
+     * @hide
      * Activity Extra: Enable or disable Airplane Mode.
      * <p>
      * This can be passed as an extra field to the {@link #ACTION_VOICE_CONTROL_AIRPLANE_MODE}
      * intent as a boolean.
      */
+    @SystemApi
     public static final String EXTRA_AIRPLANE_MODE_ENABLED = "airplane_mode_enabled";
 
     private static final String JID_RESOURCE_PREFIX = "android";
@@ -2561,7 +2566,6 @@
          * Call Preference String.
          * "SIP_ALWAYS" : Always use SIP with network access
          * "SIP_ADDRESS_ONLY" : Only if destination is a SIP address
-         * "SIP_ASK_ME_EACH_TIME" : Always ask me each time
          * @hide
          */
         public static final String SIP_CALL_OPTIONS = "sip_call_options";
@@ -2579,9 +2583,13 @@
         public static final String SIP_ADDRESS_ONLY = "SIP_ADDRESS_ONLY";
 
         /**
-         * One of the sip call options: Always ask me each time.
+         * @deprecated Use SIP_ALWAYS or SIP_ADDRESS_ONLY instead.  Formerly used to indicate that
+         * the user should be prompted each time a call is made whether it should be placed using
+         * SIP.  The {@link com.android.providers.settings.DatabaseHelper} replaces this with
+         * SIP_ADDRESS_ONLY.
          * @hide
          */
+        @Deprecated
         public static final String SIP_ASK_ME_EACH_TIME = "SIP_ASK_ME_EACH_TIME";
 
         /**
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 65e6988..0cde4f2 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -40,16 +40,15 @@
 
 /**
  * Top-level service of the current global voice interactor, which is providing
- * support for hotwording, the back-end of a {@link android.app.VoiceInteractor}, etc.
+ * support for hotwording etc.
  * The current VoiceInteractionService that has been selected by the user is kept
  * always running by the system, to allow it to do things like listen for hotwords
- * in the background to instigate voice interactions.
+ * in the background.
  *
  * <p>Because this service is always running, it should be kept as lightweight as
  * possible.  Heavy-weight operations (including showing UI) should be implemented
- * in the associated {@link android.service.voice.VoiceInteractionSessionService} when
- * an actual voice interaction is taking place, and that service should run in a
- * separate process from this one.
+ * in the associated {@link android.service.voice.VoiceInteractionSessionService}
+ * that only runs while the operation is active.
  */
 public class VoiceInteractionService extends Service {
     /**
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 19d14bf..749f813 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -16,6 +16,7 @@
 
 package android.service.voice;
 
+import android.annotation.SystemApi;
 import android.app.Dialog;
 import android.app.Instrumentation;
 import android.content.Context;
@@ -53,15 +54,7 @@
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
 /**
- * An active voice interaction session, providing a facility for the implementation
- * to interact with the user in the voice interaction layer.  This interface is no shown
- * by default, but you can request that it be shown with {@link #showWindow()}, which
- * will result in a later call to {@link #onCreateContentView()} in which the UI can be
- * built
- *
- * <p>A voice interaction session can be self-contained, ultimately calling {@link #finish}
- * when done.  It can also initiate voice interactions with applications by calling
- * {@link #startVoiceActivity}</p>.
+ * An active interaction session, started by a {@link VoiceInteractionService}.
  */
 public abstract class VoiceInteractionSession implements KeyEvent.Callback {
     static final String TAG = "VoiceInteractionSession";
@@ -175,6 +168,10 @@
         }
     };
 
+    /**
+     * @hide
+     */
+    @SystemApi
     public static class Request {
         final IVoiceInteractorRequest mInterface = new IVoiceInteractorRequest.Stub() {
             @Override
@@ -258,6 +255,10 @@
         }
     }
 
+    /**
+     * @hide
+     */
+    @SystemApi
     public static class Caller {
         final String packageName;
         final int uid;
@@ -353,8 +354,10 @@
     final MyCallbacks mCallbacks = new MyCallbacks();
 
     /**
+     * @hide
      * Information about where interesting parts of the input method UI appear.
      */
+    @SystemApi
     public static final class Insets {
         /**
          * This is the part of the UI that is the main content.  It is
@@ -474,6 +477,10 @@
         mContentFrame = (FrameLayout)mRootView.findViewById(android.R.id.content);
     }
 
+    /**
+     * @hide
+     */
+    @SystemApi
     public void showWindow() {
         if (DEBUG) Log.v(TAG, "Showing window: mWindowAdded=" + mWindowAdded
                 + " mWindowVisible=" + mWindowVisible);
@@ -502,6 +509,10 @@
         }
     }
 
+    /**
+     * @hide
+     */
+    @SystemApi
     public void hideWindow() {
         if (mWindowVisible) {
             mWindow.hide();
@@ -510,11 +521,13 @@
     }
 
     /**
+     * @hide
      * You can call this to customize the theme used by your IME's window.
      * This must be set before {@link #onCreate}, so you
      * will typically call it in your constructor with the resource ID
      * of your custom theme.
      */
+    @SystemApi
     public void setTheme(int theme) {
         if (mWindow != null) {
             throw new IllegalStateException("Must be called before onCreate()");
@@ -523,6 +536,7 @@
     }
 
     /**
+     * @hide
      * Ask that a new activity be started for voice interaction.  This will create a
      * new dedicated task in the activity manager for this voice interaction session;
      * this means that {@link Intent#FLAG_ACTIVITY_NEW_TASK Intent.FLAG_ACTIVITY_NEW_TASK}
@@ -543,6 +557,7 @@
      * always have {@link Intent#CATEGORY_VOICE Intent.CATEGORY_VOICE} added to it, since
      * this is part of a voice interaction.
      */
+    @SystemApi
     public void startVoiceActivity(Intent intent) {
         if (mToken == null) {
             throw new IllegalStateException("Can't call before onCreate()");
@@ -558,15 +573,19 @@
     }
 
     /**
+     * @hide
      * Convenience for inflating views.
      */
+    @SystemApi
     public LayoutInflater getLayoutInflater() {
         return mInflater;
     }
 
     /**
+     * @hide
      * Retrieve the window being used to show the session's UI.
      */
+    @SystemApi
     public Dialog getWindow() {
         return mWindow;
     }
@@ -612,8 +631,10 @@
     }
 
     /**
+     * @hide
      * Hook in which to create the session's UI.
      */
+    @SystemApi
     public View onCreateContentView() {
         return null;
     }
@@ -626,22 +647,42 @@
 
     }
 
+    /**
+     * @hide
+     */
+    @SystemApi
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         return false;
     }
 
+    /**
+     * @hide
+     */
+    @SystemApi
     public boolean onKeyLongPress(int keyCode, KeyEvent event) {
         return false;
     }
 
+    /**
+     * @hide
+     */
+    @SystemApi
     public boolean onKeyUp(int keyCode, KeyEvent event) {
         return false;
     }
 
+    /**
+     * @hide
+     */
+    @SystemApi
     public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) {
         return false;
     }
 
+    /**
+     * @hide
+     */
+    @SystemApi
     public void onBackPressed() {
         finish();
     }
@@ -656,12 +697,14 @@
     }
 
     /**
+     * @hide
      * Compute the interesting insets into your UI.  The default implementation
      * uses the entire window frame as the insets.  The default touchable
      * insets are {@link Insets#TOUCHABLE_INSETS_FRAME}.
      *
      * @param outInsets Fill in with the current UI insets.
      */
+    @SystemApi
     public void onComputeInsets(Insets outInsets) {
         int[] loc = mTmpLocation;
         View decor = getWindow().getWindow().getDecorView();
@@ -675,6 +718,8 @@
     }
 
     /**
+     * @hide
+     * @SystemApi
      * Called when a task initiated by {@link #startVoiceActivity(android.content.Intent)}
      * has actually started.
      *
@@ -686,6 +731,8 @@
     }
 
     /**
+     * @hide
+     * @SystemApi
      * Called when the last activity of a task initiated by
      * {@link #startVoiceActivity(android.content.Intent)} has finished.  The default
      * implementation calls {@link #finish()} on the assumption that this represents
@@ -701,6 +748,8 @@
     }
 
     /**
+     * @hide
+     * @SystemApi
      * Request to query for what extended commands the session supports.
      *
      * @param caller Who is making the request.
@@ -715,6 +764,8 @@
     }
 
     /**
+     * @hide
+     * @SystemApi
      * Request to confirm with the user before proceeding with an unrecoverable operation,
      * corresponding to a {@link android.app.VoiceInteractor.ConfirmationRequest
      * VoiceInteractor.ConfirmationRequest}.
@@ -730,6 +781,8 @@
             Bundle extras);
 
     /**
+     * @hide
+     * @SystemApi
      * Request to complete the voice interaction session because the voice activity successfully
      * completed its interaction using voice.  Corresponds to
      * {@link android.app.VoiceInteractor.CompleteVoiceRequest
@@ -751,6 +804,8 @@
     }
 
     /**
+     * @hide
+     * @SystemApi
      * Request to abort the voice interaction session because the voice activity can not
      * complete its interaction using voice.  Corresponds to
      * {@link android.app.VoiceInteractor.AbortVoiceRequest
@@ -769,6 +824,8 @@
     }
 
     /**
+     * @hide
+     * @SystemApi
      * Process an arbitrary extended command from the caller,
      * corresponding to a {@link android.app.VoiceInteractor.CommandRequest
      * VoiceInteractor.CommandRequest}.
@@ -783,6 +840,8 @@
     public abstract void onCommand(Caller caller, Request request, String command, Bundle extras);
 
     /**
+     * @hide
+     * @SystemApi
      * Called when the {@link android.app.VoiceInteractor} has asked to cancel a {@link Request}
      * that was previously delivered to {@link #onConfirm} or {@link #onCommand}.
      *
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 477c994..a10dda3 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -18,6 +18,7 @@
 
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
@@ -96,7 +97,7 @@
     }
 
     public void findAccessibilityNodeInfoByAccessibilityIdClientThread(
-            long accessibilityNodeId, int interactionId,
+            long accessibilityNodeId, Region interactiveRegion, int interactionId,
             IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
             long interrogatingTid, MagnificationSpec spec) {
         Message message = mHandler.obtainMessage();
@@ -109,6 +110,7 @@
         args.argi3 = interactionId;
         args.arg1 = callback;
         args.arg2 = spec;
+        args.arg3 = interactiveRegion;
         message.obj = args;
 
         // If the interrogation is performed by the same thread as the main UI
@@ -133,6 +135,7 @@
         final IAccessibilityInteractionConnectionCallback callback =
             (IAccessibilityInteractionConnectionCallback) args.arg1;
         final MagnificationSpec spec = (MagnificationSpec) args.arg2;
+        final Region interactiveRegion = (Region) args.arg3;
 
         args.recycle();
 
@@ -159,6 +162,7 @@
                 if (spec != null) {
                     spec.recycle();
                 }
+                adjustIsVisibleToUserIfNeeded(infos, interactiveRegion);
                 callback.setFindAccessibilityNodeInfosResult(infos, interactionId);
                 infos.clear();
             } catch (RemoteException re) {
@@ -168,8 +172,9 @@
     }
 
     public void findAccessibilityNodeInfosByViewIdClientThread(long accessibilityNodeId,
-            String viewId, int interactionId, IAccessibilityInteractionConnectionCallback callback,
-            int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+            String viewId, Region interactiveRegion, int interactionId,
+            IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
+            long interrogatingTid, MagnificationSpec spec) {
         Message message = mHandler.obtainMessage();
         message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID;
         message.arg1 = flags;
@@ -180,6 +185,7 @@
         args.arg1 = callback;
         args.arg2 = spec;
         args.arg3 = viewId;
+        args.arg4 = interactiveRegion;
 
         message.obj = args;
 
@@ -205,6 +211,7 @@
             (IAccessibilityInteractionConnectionCallback) args.arg1;
         final MagnificationSpec spec = (MagnificationSpec) args.arg2;
         final String viewId = (String) args.arg3;
+        final Region interactiveRegion = (Region) args.arg4;
 
         args.recycle();
 
@@ -241,6 +248,7 @@
                 if (spec != null) {
                     spec.recycle();
                 }
+                adjustIsVisibleToUserIfNeeded(infos, interactiveRegion);
                 callback.setFindAccessibilityNodeInfosResult(infos, interactionId);
             } catch (RemoteException re) {
                 /* ignore - the other side will time out */
@@ -249,8 +257,9 @@
     }
 
     public void findAccessibilityNodeInfosByTextClientThread(long accessibilityNodeId,
-            String text, int interactionId, IAccessibilityInteractionConnectionCallback callback,
-            int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+            String text, Region interactiveRegion, int interactionId,
+            IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
+            long interrogatingTid, MagnificationSpec spec) {
         Message message = mHandler.obtainMessage();
         message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT;
         message.arg1 = flags;
@@ -262,6 +271,7 @@
         args.argi1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
         args.argi2 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId);
         args.argi3 = interactionId;
+        args.arg4 = interactiveRegion;
         message.obj = args;
 
         // If the interrogation is performed by the same thread as the main UI
@@ -287,6 +297,7 @@
         final int accessibilityViewId = args.argi1;
         final int virtualDescendantId = args.argi2;
         final int interactionId = args.argi3;
+        final Region interactiveRegion = (Region) args.arg4;
         args.recycle();
 
         List<AccessibilityNodeInfo> infos = null;
@@ -347,6 +358,7 @@
                 if (spec != null) {
                     spec.recycle();
                 }
+                adjustIsVisibleToUserIfNeeded(infos, interactiveRegion);
                 callback.setFindAccessibilityNodeInfosResult(infos, interactionId);
             } catch (RemoteException re) {
                 /* ignore - the other side will time out */
@@ -354,7 +366,8 @@
         }
     }
 
-    public void findFocusClientThread(long accessibilityNodeId, int focusType, int interactionId,
+    public void findFocusClientThread(long accessibilityNodeId, int focusType,
+            Region interactiveRegion, int interactionId,
             IAccessibilityInteractionConnectionCallback callback, int flags, int interogatingPid,
             long interrogatingTid, MagnificationSpec spec) {
         Message message = mHandler.obtainMessage();
@@ -368,6 +381,7 @@
         args.argi3 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId);
         args.arg1 = callback;
         args.arg2 = spec;
+        args.arg3 = interactiveRegion;
 
         message.obj = args;
 
@@ -394,6 +408,7 @@
         final IAccessibilityInteractionConnectionCallback callback =
             (IAccessibilityInteractionConnectionCallback) args.arg1;
         final MagnificationSpec spec = (MagnificationSpec) args.arg2;
+        final Region interactiveRegion = (Region) args.arg3;
         args.recycle();
 
         AccessibilityNodeInfo focused = null;
@@ -457,6 +472,7 @@
                 if (spec != null) {
                     spec.recycle();
                 }
+                adjustIsVisibleToUserIfNeeded(focused, interactiveRegion);
                 callback.setFindAccessibilityNodeInfoResult(focused, interactionId);
             } catch (RemoteException re) {
                 /* ignore - the other side will time out */
@@ -464,7 +480,8 @@
         }
     }
 
-    public void focusSearchClientThread(long accessibilityNodeId, int direction, int interactionId,
+    public void focusSearchClientThread(long accessibilityNodeId, int direction,
+            Region interactiveRegion, int interactionId,
             IAccessibilityInteractionConnectionCallback callback, int flags, int interogatingPid,
             long interrogatingTid, MagnificationSpec spec) {
         Message message = mHandler.obtainMessage();
@@ -477,6 +494,7 @@
         args.argi3 = interactionId;
         args.arg1 = callback;
         args.arg2 = spec;
+        args.arg3 = interactiveRegion;
 
         message.obj = args;
 
@@ -502,6 +520,7 @@
         final IAccessibilityInteractionConnectionCallback callback =
             (IAccessibilityInteractionConnectionCallback) args.arg1;
         final MagnificationSpec spec = (MagnificationSpec) args.arg2;
+        final Region interactiveRegion = (Region) args.arg3;
 
         args.recycle();
 
@@ -530,6 +549,7 @@
                 if (spec != null) {
                     spec.recycle();
                 }
+                adjustIsVisibleToUserIfNeeded(next, interactiveRegion);
                 callback.setFindAccessibilityNodeInfoResult(next, interactionId);
             } catch (RemoteException re) {
                 /* ignore - the other side will time out */
@@ -644,6 +664,30 @@
         }
     }
 
+    private void adjustIsVisibleToUserIfNeeded(List<AccessibilityNodeInfo> infos,
+            Region interactiveRegion) {
+        if (interactiveRegion == null || infos == null) {
+            return;
+        }
+        final int infoCount = infos.size();
+        for (int i = 0; i < infoCount; i++) {
+            AccessibilityNodeInfo info = infos.get(i);
+            adjustIsVisibleToUserIfNeeded(info, interactiveRegion);
+        }
+    }
+
+    private void adjustIsVisibleToUserIfNeeded(AccessibilityNodeInfo info,
+            Region interactiveRegion) {
+        if (interactiveRegion == null || info == null) {
+            return;
+        }
+        Rect boundsInScreen = mTempRect;
+        info.getBoundsInScreen(boundsInScreen);
+        if (interactiveRegion.quickReject(boundsInScreen)) {
+            info.setVisibleToUser(false);
+        }
+    }
+
     private void applyAppScaleAndMagnificationSpecIfNeeded(AccessibilityNodeInfo info,
             MagnificationSpec spec) {
         if (info == null) {
diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java
index 063a08d..7dcad68 100644
--- a/core/java/android/view/PointerIcon.java
+++ b/core/java/android/view/PointerIcon.java
@@ -149,9 +149,9 @@
      * Creates a custom pointer from the given bitmap and hotspot information.
      *
      * @param bitmap The bitmap for the icon.
-     * @param hotspotX The X offset of the pointer icon hotspot in the bitmap.
+     * @param hotSpotX The X offset of the pointer icon hotspot in the bitmap.
      *        Must be within the [0, bitmap.getWidth()) range.
-     * @param hotspotY The Y offset of the pointer icon hotspot in the bitmap.
+     * @param hotSpotY The Y offset of the pointer icon hotspot in the bitmap.
      *        Must be within the [0, bitmap.getHeight()) range.
      * @return A pointer icon for this bitmap.
      *
@@ -374,18 +374,18 @@
     }
 
     private void loadResource(Context context, Resources resources, int resourceId) {
-        XmlResourceParser parser = resources.getXml(resourceId);
+        final XmlResourceParser parser = resources.getXml(resourceId);
         final int bitmapRes;
         final float hotSpotX;
         final float hotSpotY;
         try {
             XmlUtils.beginDocument(parser, "pointer-icon");
 
-            TypedArray a = resources.obtainAttributes(
+            final TypedArray a = resources.obtainAttributes(
                     parser, com.android.internal.R.styleable.PointerIcon);
             bitmapRes = a.getResourceId(com.android.internal.R.styleable.PointerIcon_bitmap, 0);
-            hotSpotX = a.getFloat(com.android.internal.R.styleable.PointerIcon_hotSpotX, 0);
-            hotSpotY = a.getFloat(com.android.internal.R.styleable.PointerIcon_hotSpotY, 0);
+            hotSpotX = a.getDimension(com.android.internal.R.styleable.PointerIcon_hotSpotX, 0);
+            hotSpotY = a.getDimension(com.android.internal.R.styleable.PointerIcon_hotSpotY, 0);
             a.recycle();
         } catch (Exception ex) {
             throw new IllegalArgumentException("Exception parsing pointer icon resource.", ex);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 49d925f..dd1cbc93 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -6629,14 +6629,15 @@
 
         @Override
         public void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId,
-                int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
+                Region interactiveRegion, int interactionId,
+                IAccessibilityInteractionConnectionCallback callback, int flags,
                 int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
             ViewRootImpl viewRootImpl = mViewRootImpl.get();
             if (viewRootImpl != null && viewRootImpl.mView != null) {
                 viewRootImpl.getAccessibilityInteractionController()
                     .findAccessibilityNodeInfoByAccessibilityIdClientThread(accessibilityNodeId,
-                            interactionId, callback, flags, interrogatingPid, interrogatingTid,
-                            spec);
+                            interactiveRegion, interactionId, callback, flags, interrogatingPid,
+                            interrogatingTid, spec);
             } else {
                 // We cannot make the call and notify the caller so it does not wait.
                 try {
@@ -6669,15 +6670,15 @@
 
         @Override
         public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId,
-                String viewId, int interactionId,
+                String viewId, Region interactiveRegion, int interactionId,
                 IAccessibilityInteractionConnectionCallback callback, int flags,
                 int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
             ViewRootImpl viewRootImpl = mViewRootImpl.get();
             if (viewRootImpl != null && viewRootImpl.mView != null) {
                 viewRootImpl.getAccessibilityInteractionController()
                     .findAccessibilityNodeInfosByViewIdClientThread(accessibilityNodeId,
-                            viewId, interactionId, callback, flags, interrogatingPid,
-                            interrogatingTid, spec);
+                            viewId, interactiveRegion, interactionId, callback, flags,
+                            interrogatingPid, interrogatingTid, spec);
             } else {
                 // We cannot make the call and notify the caller so it does not wait.
                 try {
@@ -6690,14 +6691,15 @@
 
         @Override
         public void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text,
-                int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
+                Region interactiveRegion, int interactionId,
+                IAccessibilityInteractionConnectionCallback callback, int flags,
                 int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
             ViewRootImpl viewRootImpl = mViewRootImpl.get();
             if (viewRootImpl != null && viewRootImpl.mView != null) {
                 viewRootImpl.getAccessibilityInteractionController()
                     .findAccessibilityNodeInfosByTextClientThread(accessibilityNodeId, text,
-                            interactionId, callback, flags, interrogatingPid, interrogatingTid,
-                            spec);
+                            interactiveRegion, interactionId, callback, flags, interrogatingPid,
+                            interrogatingTid, spec);
             } else {
                 // We cannot make the call and notify the caller so it does not wait.
                 try {
@@ -6709,14 +6711,15 @@
         }
 
         @Override
-        public void findFocus(long accessibilityNodeId, int focusType, int interactionId,
-                IAccessibilityInteractionConnectionCallback callback, int flags,
+        public void findFocus(long accessibilityNodeId, int focusType, Region interactiveRegion,
+                int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
                 int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
             ViewRootImpl viewRootImpl = mViewRootImpl.get();
             if (viewRootImpl != null && viewRootImpl.mView != null) {
                 viewRootImpl.getAccessibilityInteractionController()
-                    .findFocusClientThread(accessibilityNodeId, focusType, interactionId, callback,
-                            flags, interrogatingPid, interrogatingTid, spec);
+                    .findFocusClientThread(accessibilityNodeId, focusType, interactiveRegion,
+                            interactionId, callback, flags, interrogatingPid, interrogatingTid,
+                            spec);
             } else {
                 // We cannot make the call and notify the caller so it does not wait.
                 try {
@@ -6728,14 +6731,15 @@
         }
 
         @Override
-        public void focusSearch(long accessibilityNodeId, int direction, int interactionId,
-                IAccessibilityInteractionConnectionCallback callback, int flags,
+        public void focusSearch(long accessibilityNodeId, int direction, Region interactiveRegion,
+                int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
                 int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
             ViewRootImpl viewRootImpl = mViewRootImpl.get();
             if (viewRootImpl != null && viewRootImpl.mView != null) {
                 viewRootImpl.getAccessibilityInteractionController()
-                    .focusSearchClientThread(accessibilityNodeId, direction, interactionId,
-                            callback, flags, interrogatingPid, interrogatingTid, spec);
+                    .focusSearchClientThread(accessibilityNodeId, direction, interactiveRegion,
+                            interactionId, callback, flags, interrogatingPid, interrogatingTid,
+                            spec);
             } else {
                 // We cannot make the call and notify the caller so it does not wait.
                 try {
diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
index 8d15472..faf7789 100644
--- a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
@@ -16,6 +16,7 @@
 
 package android.view.accessibility;
 
+import android.graphics.Region;
 import android.os.Bundle;
 import android.view.MagnificationSpec;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -29,23 +30,23 @@
  */
 oneway interface IAccessibilityInteractionConnection {
 
-    void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId, int interactionId,
-        IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
-        long interrogatingTid, in MagnificationSpec spec);
-
-    void findAccessibilityNodeInfosByViewId(long accessibilityNodeId, String viewId,
+    void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId, in Region bounds,
         int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
         int interrogatingPid, long interrogatingTid, in MagnificationSpec spec);
 
-    void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text, int interactionId,
+    void findAccessibilityNodeInfosByViewId(long accessibilityNodeId, String viewId,
+        in Region bounds, int interactionId, IAccessibilityInteractionConnectionCallback callback,
+        int flags, int interrogatingPid, long interrogatingTid, in MagnificationSpec spec);
+
+    void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text, in Region bounds,
+        int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
+        int interrogatingPid, long interrogatingTid, in MagnificationSpec spec);
+
+    void findFocus(long accessibilityNodeId, int focusType, in Region bounds, int interactionId,
         IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
         long interrogatingTid, in MagnificationSpec spec);
 
-    void findFocus(long accessibilityNodeId, int focusType, int interactionId,
-        IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
-        long interrogatingTid, in MagnificationSpec spec);
-
-    void focusSearch(long accessibilityNodeId, int direction, int interactionId,
+    void focusSearch(long accessibilityNodeId, int direction, in Region bounds, int interactionId,
         IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
         long interrogatingTid, in MagnificationSpec spec);
 
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index 4d2f57a..20adfe4 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -431,7 +431,15 @@
     /**
      * The default implementation does nothing.
      */
-    public boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) {
+    public boolean requestCursorUpdates(int cursorUpdateMode) {
+        return false;
+    }
+
+    /**
+     * The default implementation does nothing.
+     * @removed
+     */
+    public final boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) {
         return false;
     }
 
diff --git a/core/java/android/view/inputmethod/CursorAnchorInfo.java b/core/java/android/view/inputmethod/CursorAnchorInfo.java
index 0492824..fe0f5b9 100644
--- a/core/java/android/view/inputmethod/CursorAnchorInfo.java
+++ b/core/java/android/view/inputmethod/CursorAnchorInfo.java
@@ -45,9 +45,9 @@
     private final CharSequence mComposingText;
 
     /**
-     * {@code True} if the insertion marker is partially or entirely clipped by other UI elements.
+     * Flags of the insertion marker. See {@link #FLAG_HAS_VISIBLE_REGION} for example.
      */
-    private final boolean mInsertionMarkerClipped;
+    private final int mInsertionMarkerFlags;
     /**
      * Horizontal position of the insertion marker, in the local coordinates that will be
      * transformed with the transformation matrix when rendered on the screen. This should be
@@ -90,27 +90,47 @@
      */
     private final Matrix mMatrix;
 
+    /**
+     * Flag for {@link #getInsertionMarkerFlags()} and {@link #getCharacterRectFlags(int)}: the
+     * insertion marker or character bounds have at least one visible region.
+     */
+    public static final int FLAG_HAS_VISIBLE_REGION = 0x01;
+
+    /**
+     * Flag for {@link #getInsertionMarkerFlags()} and {@link #getCharacterRectFlags(int)}: the
+     * insertion marker or character bounds have at least one invisible (clipped) region.
+     */
+    public static final int FLAG_HAS_INVISIBLE_REGION = 0x02;
+
+    /**
+     * @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;
 
@@ -119,7 +139,7 @@
         mSelectionEnd = source.readInt();
         mComposingTextStart = source.readInt();
         mComposingText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
-        mInsertionMarkerClipped = (source.readInt() != 0);
+        mInsertionMarkerFlags = source.readInt();
         mInsertionMarkerHorizontal = source.readFloat();
         mInsertionMarkerTop = source.readFloat();
         mInsertionMarkerBaseline = source.readFloat();
@@ -141,7 +161,7 @@
         dest.writeInt(mSelectionEnd);
         dest.writeInt(mComposingTextStart);
         TextUtils.writeToParcel(mComposingText, dest, flags);
-        dest.writeInt(mInsertionMarkerClipped ? 1 : 0);
+        dest.writeInt(mInsertionMarkerFlags);
         dest.writeFloat(mInsertionMarkerHorizontal);
         dest.writeFloat(mInsertionMarkerTop);
         dest.writeFloat(mInsertionMarkerBaseline);
@@ -159,7 +179,7 @@
                 + mInsertionMarkerBaseline + mInsertionMarkerBottom;
         int hash = floatHash > 0 ? (int) floatHash : (int)(-floatHash);
         hash *= 31;
-        hash += (mInsertionMarkerClipped ? 2 : 1);
+        hash += mInsertionMarkerFlags;
         hash *= 31;
         hash += mSelectionStart + mSelectionEnd + mComposingTextStart;
         hash *= 31;
@@ -204,7 +224,7 @@
                 || !Objects.equals(mComposingText, that.mComposingText)) {
             return false;
         }
-        if (mInsertionMarkerClipped != that.mInsertionMarkerClipped
+        if (mInsertionMarkerFlags != that.mInsertionMarkerFlags
                 || !areSameFloatImpl(mInsertionMarkerHorizontal, that.mInsertionMarkerHorizontal)
                 || !areSameFloatImpl(mInsertionMarkerTop, that.mInsertionMarkerTop)
                 || !areSameFloatImpl(mInsertionMarkerBaseline, that.mInsertionMarkerBaseline)
@@ -225,7 +245,7 @@
         return "SelectionInfo{mSelection=" + mSelectionStart + "," + mSelectionEnd
                 + " mComposingTextStart=" + mComposingTextStart
                 + " mComposingText=" + Objects.toString(mComposingText)
-                + " mInsertionMarkerClipped=" + mInsertionMarkerClipped
+                + " mInsertionMarkerFlags=" + mInsertionMarkerFlags
                 + " mInsertionMarkerHorizontal=" + mInsertionMarkerHorizontal
                 + " mInsertionMarkerTop=" + mInsertionMarkerTop
                 + " mInsertionMarkerBaseline=" + mInsertionMarkerBaseline
@@ -272,6 +292,20 @@
         private CharSequence mComposingText = null;
 
         /**
+         * @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.
@@ -288,24 +322,24 @@
          * @param lineBottom vertical position of the insertion marker, in the local coordinates
          * that will be transformed with the transformation matrix when rendered on the screen. This
          * should be calculated or compatible with {@link Layout#getLineBottom(int)}.
-         * @param clipped {@code true} is the insertion marker is partially or entierly clipped by
-         * other UI elements.
+         * @param flags flags of the insertion marker. See {@link #FLAG_HAS_VISIBLE_REGION} for
+         * example.
          */
         public Builder setInsertionMarkerLocation(final float horizontalPosition,
                 final float lineTop, final float lineBaseline, final float lineBottom,
-                final boolean clipped){
+                final int flags){
             mInsertionMarkerHorizontal = horizontalPosition;
             mInsertionMarkerTop = lineTop;
             mInsertionMarkerBaseline = lineBaseline;
             mInsertionMarkerBottom = lineBottom;
-            mInsertionMarkerClipped = clipped;
+            mInsertionMarkerFlags = flags;
             return this;
         }
         private float mInsertionMarkerHorizontal = Float.NaN;
         private float mInsertionMarkerTop = Float.NaN;
         private float mInsertionMarkerBaseline = Float.NaN;
         private float mInsertionMarkerBottom = Float.NaN;
-        private boolean mInsertionMarkerClipped = false;
+        private int mInsertionMarkerFlags = 0;
 
         /**
          * Adds the bounding box of the character specified with the index.
@@ -320,8 +354,8 @@
          * 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 type and flags for this character. See
-         * {@link #CHARACTER_RECT_TYPE_FULLY_VISIBLE} for example.
+         * @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.
          */
@@ -331,11 +365,6 @@
             if (index < 0) {
                 throw new IllegalArgumentException("index must not be a negative integer.");
             }
-            final int type = flags & CHARACTER_RECT_TYPE_MASK;
-            if (type == CHARACTER_RECT_TYPE_UNSPECIFIED) {
-                throw new IllegalArgumentException("Type except for "
-                        + "CHARACTER_RECT_TYPE_UNSPECIFIED must be specified.");
-            }
             if (mCharacterRectBuilder == null) {
                 mCharacterRectBuilder = new SparseRectFArrayBuilder();
             }
@@ -388,7 +417,7 @@
             mSelectionEnd = -1;
             mComposingTextStart = -1;
             mComposingText = null;
-            mInsertionMarkerClipped = false;
+            mInsertionMarkerFlags = 0;
             mInsertionMarkerHorizontal = Float.NaN;
             mInsertionMarkerTop = Float.NaN;
             mInsertionMarkerBaseline = Float.NaN;
@@ -406,7 +435,7 @@
         mSelectionEnd = builder.mSelectionEnd;
         mComposingTextStart = builder.mComposingTextStart;
         mComposingText = builder.mComposingText;
-        mInsertionMarkerClipped = builder.mInsertionMarkerClipped;
+        mInsertionMarkerFlags = builder.mInsertionMarkerFlags;
         mInsertionMarkerHorizontal = builder.mInsertionMarkerHorizontal;
         mInsertionMarkerTop = builder.mInsertionMarkerTop;
         mInsertionMarkerBaseline = builder.mInsertionMarkerBaseline;
@@ -449,11 +478,20 @@
     }
 
     /**
+     * Returns the flag of the insertion marker.
+     * @return the flag of the insertion marker. {@code 0} if no flag is specified.
+     */
+    public int getInsertionMarkerFlags() {
+        return mInsertionMarkerFlags;
+    }
+
+    /**
      * Returns the visibility of the insertion marker.
      * @return {@code true} if the insertion marker is partially or entirely clipped.
+     * @removed
      */
     public boolean isInsertionMarkerClipped() {
-        return mInsertionMarkerClipped;
+        return (mInsertionMarkerFlags & FLAG_HAS_VISIBLE_REGION) != 0;
     }
 
     /**
@@ -522,17 +560,17 @@
     }
 
     /**
-     * Returns the flags associated with the character specified with the index.
+     * Returns the flags associated with the character rect specified with the index.
      * @param index index of the character in a Java chars.
-     * @return {@link #CHARACTER_RECT_TYPE_UNSPECIFIED} if no flag is specified.
+     * @return {@code 0} if no flag is specified.
      */
     // TODO: Prepare a document about the expected behavior for surrogate pairs, combining
     // characters, and non-graphical chars.
     public int getCharacterRectFlags(final int index) {
         if (mCharacterRects == null) {
-            return CHARACTER_RECT_TYPE_UNSPECIFIED;
+            return 0;
         }
-        return mCharacterRects.getFlags(index, CHARACTER_RECT_TYPE_UNSPECIFIED);
+        return mCharacterRects.getFlags(index, 0);
     }
 
     /**
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index ca094c1..093fb2f 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -728,31 +728,47 @@
      * The editor is requested to call
      * {@link InputMethodManager#updateCursorAnchorInfo(android.view.View, CursorAnchorInfo)} at
      * once, as soon as possible, regardless of cursor/anchor position changes. This flag can be
-     * used together with {@link #REQUEST_UPDATE_CURSOR_ANCHOR_INFO_MONITOR}.
+     * used together with {@link #CURSOR_UPDATE_MONITOR}.
      */
-    public static final int REQUEST_UPDATE_CURSOR_ANCHOR_INFO_IMMEDIATE = 1 << 0;
+    public static final int CURSOR_UPDATE_IMMEDIATE = 1 << 0;
 
     /**
      * The editor is requested to call
      * {@link InputMethodManager#updateCursorAnchorInfo(android.view.View, CursorAnchorInfo)}
      * whenever cursor/anchor position is changed. To disable monitoring, call
-     * {@link InputConnection#requestUpdateCursorAnchorInfo(int)} again with this flag off.
+     * {@link InputConnection#requestCursorUpdates(int)} again with this flag off.
      * <p>
-     * This flag can be used together with {@link #REQUEST_UPDATE_CURSOR_ANCHOR_INFO_IMMEDIATE}.
+     * This flag can be used together with {@link #CURSOR_UPDATE_IMMEDIATE}.
      * </p>
      */
-    public static final int REQUEST_UPDATE_CURSOR_ANCHOR_INFO_MONITOR = 1 << 1;
+    public static final int CURSOR_UPDATE_MONITOR = 1 << 1;
 
     /**
      * Called by the input method to ask the editor for calling back
      * {@link InputMethodManager#updateCursorAnchorInfo(android.view.View, CursorAnchorInfo)} to
      * notify cursor/anchor locations.
      *
-     * @param cursorUpdateMode {@link #REQUEST_UPDATE_CURSOR_ANCHOR_INFO_IMMEDIATE} and/or
-     * {@link #REQUEST_UPDATE_CURSOR_ANCHOR_INFO_MONITOR}
+     * @param cursorUpdateMode {@link #CURSOR_UPDATE_IMMEDIATE} and/or
+     * {@link #CURSOR_UPDATE_MONITOR}. Pass {@code 0} to disable the effect of
+     * {@link #CURSOR_UPDATE_MONITOR}.
      * @return {@code true} if the request is scheduled. {@code false} to indicate that when the
      * application will not call
      * {@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 d95df25..87853de 100644
--- a/core/java/android/view/inputmethod/InputConnectionWrapper.java
+++ b/core/java/android/view/inputmethod/InputConnectionWrapper.java
@@ -126,7 +126,14 @@
         return mTarget.performPrivateCommand(action, data);
     }
 
-    public boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) {
-        return mTarget.requestUpdateCursorAnchorInfo(cursorUpdateMode);
+    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/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 0a472c7..b56378f 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1526,7 +1526,7 @@
      * Return true if the current input method wants to watch the location
      * of the input editor's cursor in its window.
      *
-     * @deprecated Use {@link InputConnection#requestUpdateCursorAnchorInfo(int)} instead.
+     * @deprecated Use {@link InputConnection#requestCursorUpdates(int)} instead.
      */
     @Deprecated
     public boolean isWatchingCursor(View view) {
@@ -1542,9 +1542,9 @@
     public boolean isCursorAnchorInfoEnabled() {
         synchronized (mH) {
             final boolean isImmediate = (mRequestUpdateCursorAnchorInfoMonitorMode &
-                    InputConnection.REQUEST_UPDATE_CURSOR_ANCHOR_INFO_IMMEDIATE) != 0;
+                    InputConnection.CURSOR_UPDATE_IMMEDIATE) != 0;
             final boolean isMonitoring = (mRequestUpdateCursorAnchorInfoMonitorMode &
-                    InputConnection.REQUEST_UPDATE_CURSOR_ANCHOR_INFO_MONITOR) != 0;
+                    InputConnection.CURSOR_UPDATE_MONITOR) != 0;
             return isImmediate || isMonitoring;
         }
     }
@@ -1608,7 +1608,7 @@
             // If immediate bit is set, we will call updateCursorAnchorInfo() even when the data has
             // not been changed from the previous call.
             final boolean isImmediate = (mRequestUpdateCursorAnchorInfoMonitorMode &
-                    InputConnection.REQUEST_UPDATE_CURSOR_ANCHOR_INFO_IMMEDIATE) != 0;
+                    InputConnection.CURSOR_UPDATE_IMMEDIATE) != 0;
             if (!isImmediate && Objects.equals(mCursorAnchorInfo, cursorAnchorInfo)) {
                 // TODO: Consider always emitting this message once we have addressed redundant
                 // calls of this method from android.widget.Editor.
@@ -1624,7 +1624,7 @@
                 mCursorAnchorInfo = cursorAnchorInfo;
                 // Clear immediate bit (if any).
                 mRequestUpdateCursorAnchorInfoMonitorMode &=
-                        ~InputConnection.REQUEST_UPDATE_CURSOR_ANCHOR_INFO_IMMEDIATE;
+                        ~InputConnection.CURSOR_UPDATE_IMMEDIATE;
             } catch (RemoteException e) {
                 Log.w(TAG, "IME died: " + mCurId, e);
             }
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index eb93745..eef85546 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -5717,8 +5717,16 @@
         }
 
         @Override
+        public boolean requestCursorUpdates(int cursorUpdateMode) {
+            return getTarget().requestCursorUpdates(cursorUpdateMode);
+        }
+
+        /**
+         * @removed
+         */
+        @Override
         public boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) {
-            return getTarget().requestUpdateCursorAnchorInfo(cursorUpdateMode);
+            return getTarget().requestCursorUpdates(cursorUpdateMode);
         }
     }
 
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 1da22ca..b9f891c 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -297,10 +297,10 @@
     public boolean performItemClick(View view, int position, long id) {
         if (mOnItemClickListener != null) {
             playSoundEffect(SoundEffectConstants.CLICK);
+            mOnItemClickListener.onItemClick(this, view, position, id);
             if (view != null) {
                 view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
             }
-            mOnItemClickListener.onItemClick(this, view, position, id);
             return true;
         }
 
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 46b225d..22138d0 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3089,13 +3089,12 @@
                     final boolean isLeadingEdgeTopVisible = isPositionVisible(leadingEdgeX, top);
                     final boolean isTrailingEdgeBottomVisible =
                             isPositionVisible(trailingEdgeX, bottom);
-                    final int characterRectFlags;
-                    if (isLeadingEdgeTopVisible && isTrailingEdgeBottomVisible) {
-                        characterRectFlags = CursorAnchorInfo.CHARACTER_RECT_TYPE_FULLY_VISIBLE;
-                    } else if (isLeadingEdgeTopVisible || isTrailingEdgeBottomVisible) {
-                        characterRectFlags = CursorAnchorInfo.CHARACTER_RECT_TYPE_PARTIALLY_VISIBLE;
-                    } else {
-                        characterRectFlags = CursorAnchorInfo.CHARACTER_RECT_TYPE_INVISIBLE;
+                    int characterRectFlags = 0;
+                    if (isLeadingEdgeTopVisible || isTrailingEdgeBottomVisible) {
+                        characterRectFlags |= CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
+                    }
+                    if (!isLeadingEdgeTopVisible || !isTrailingEdgeBottomVisible) {
+                        characterRectFlags |= CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
                     }
                     // Here offset is the index in Java chars.
                     // TODO: We must have a well-defined specification. For example, how
@@ -3117,11 +3116,19 @@
                         + viewportToContentVerticalOffset;
                 final float insertionMarkerBottom = layout.getLineBottom(line)
                         + viewportToContentVerticalOffset;
-                // Take TextView's padding and scroll into account.
-                final boolean isClipped = !isPositionVisible(insertionMarkerX, insertionMarkerTop)
-                        || !isPositionVisible(insertionMarkerX, insertionMarkerBottom);
+                final boolean isTopVisible =
+                        isPositionVisible(insertionMarkerX, insertionMarkerTop);
+                final boolean isBottomVisible =
+                        isPositionVisible(insertionMarkerX, insertionMarkerBottom);
+                int insertionMarkerFlags = 0;
+                if (isTopVisible || isBottomVisible) {
+                    insertionMarkerFlags |= CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
+                }
+                if (!isTopVisible || !isBottomVisible) {
+                    insertionMarkerFlags |= CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
+                }
                 builder.setInsertionMarkerLocation(insertionMarkerX, insertionMarkerTop,
-                        insertionMarkerBaseline, insertionMarkerBottom, isClipped);
+                        insertionMarkerBaseline, insertionMarkerBottom, insertionMarkerFlags);
             }
 
             imm.updateCursorAnchorInfo(mTextView, builder.build());
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 9b3a1e0..3e1b674 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1861,6 +1861,10 @@
             return getCompoundPaddingTop();
         }
 
+        if (mLayout == null) {
+            assumeLayout();
+        }
+
         if (mLayout.getLineCount() <= mMaximum) {
             return getCompoundPaddingTop();
         }
@@ -1894,6 +1898,10 @@
             return getCompoundPaddingBottom();
         }
 
+        if (mLayout == null) {
+            assumeLayout();
+        }
+
         if (mLayout.getLineCount() <= mMaximum) {
             return getCompoundPaddingBottom();
         }
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index ece8aa4..3ba03b8 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -248,11 +248,12 @@
         final Drawable navIcon = a.getDrawable(R.styleable.Toolbar_navigationIcon);
         if (navIcon != null) {
             setNavigationIcon(navIcon);
-            final CharSequence navDesc = a.getText(
-                    R.styleable.Toolbar_navigationContentDescription);
-            if (!TextUtils.isEmpty(navDesc)) {
-                setNavigationContentDescription(navDesc);
-            }
+        }
+
+        final CharSequence navDesc = a.getText(
+                R.styleable.Toolbar_navigationContentDescription);
+        if (!TextUtils.isEmpty(navDesc)) {
+            setNavigationContentDescription(navDesc);
         }
         a.recycle();
     }
diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java
index cb0c3d0..572cca2 100644
--- a/core/java/android/widget/VideoView.java
+++ b/core/java/android/widget/VideoView.java
@@ -253,6 +253,10 @@
      *
      * @param uri     the URI of the video.
      * @param headers the headers for the URI request.
+     *                Note that the cross domain redirection is allowed by default, but that can be
+     *                changed with key/value pairs through the headers parameter with
+     *                "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value
+     *                to disallow or allow cross domain redirection.
      */
     public void setVideoURI(Uri uri, Map<String, String> headers) {
         mUri = uri;
diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java
index abe8a9f..6f1c7ec 100644
--- a/core/java/com/android/internal/app/ToolbarActionBar.java
+++ b/core/java/com/android/internal/app/ToolbarActionBar.java
@@ -22,6 +22,7 @@
 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;
@@ -32,6 +33,7 @@
 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.widget.DecorToolbar;
 import com.android.internal.widget.ToolbarWidgetWrapper;
@@ -44,6 +46,8 @@
     private boolean mToolbarMenuPrepared;
     private Window.Callback mWindowCallback;
 
+    private CharSequence mHomeDescription;
+
     private boolean mLastMenuVisibility;
     private ArrayList<OnMenuVisibilityListener> mMenuVisibilityListeners =
             new ArrayList<OnMenuVisibilityListener>();
@@ -70,6 +74,8 @@
         mDecorToolbar.setWindowCallback(mWindowCallback);
         toolbar.setOnMenuItemClickListener(mMenuClicker);
         mDecorToolbar.setWindowTitle(title);
+        mHomeDescription = mToolbar.getNavigationContentDescription();
+        updateNavDescription();
     }
 
     public Window.Callback getWrappedWindowCallback() {
@@ -161,6 +167,7 @@
     @Override
     public void setHomeActionContentDescription(CharSequence description) {
         mToolbar.setNavigationContentDescription(description);
+        mHomeDescription = description;
     }
 
     @Override
@@ -171,6 +178,7 @@
     @Override
     public void setHomeActionContentDescription(int resId) {
         mToolbar.setNavigationContentDescription(resId);
+        mHomeDescription = mToolbar.getNavigationContentDescription();
     }
 
     @Override
@@ -247,8 +255,22 @@
 
     @Override
     public void setDisplayOptions(@DisplayOptions int options, @DisplayOptions int mask) {
-        mDecorToolbar.setDisplayOptions((options & mask) |
-                mDecorToolbar.getDisplayOptions() & ~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/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java
index b1f5d90..e19b2b6 100644
--- a/core/java/com/android/internal/view/IInputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java
@@ -437,7 +437,7 @@
                         return;
                     }
                     args.callback.setRequestUpdateCursorAnchorInfoResult(
-                            ic.requestUpdateCursorAnchorInfo(msg.arg1), args.seq);
+                            ic.requestCursorUpdates(msg.arg1), args.seq);
                 } catch (RemoteException e) {
                     Log.w(TAG, "Got RemoteException calling requestCursorAnchorInfo", e);
                 }
diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java
index a8526c8..0c65ad1 100644
--- a/core/java/com/android/internal/view/InputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/InputConnectionWrapper.java
@@ -428,7 +428,7 @@
         }
     }
 
-    public boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) {
+    public boolean requestCursorUpdates(int cursorUpdateMode) {
         boolean result = false;
         try {
             InputContextCallback callback = InputContextCallback.getInstance();
@@ -445,4 +445,11 @@
         }
         return result;
     }
+
+    /**
+     * @removed
+     */
+    public boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) {
+        return requestCursorUpdates(cursorUpdateMode);
+    }
 }
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index ba236f39..f211ff2 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -188,13 +188,13 @@
     }
 
     @Override
-    public boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) {
+    public boolean requestCursorUpdates(int cursorUpdateMode) {
         if (DEBUG) Log.v(TAG, "requestUpdateCursorAnchorInfo " + cursorUpdateMode);
 
         // It is possible that any other bit is used as a valid flag in a future release.
         // We should reject the entire request in such a case.
-        final int KNOWN_FLAGS_MASK = InputConnection.REQUEST_UPDATE_CURSOR_ANCHOR_INFO_IMMEDIATE |
-                InputConnection.REQUEST_UPDATE_CURSOR_ANCHOR_INFO_MONITOR;
+        final int KNOWN_FLAGS_MASK = InputConnection.CURSOR_UPDATE_IMMEDIATE |
+                InputConnection.CURSOR_UPDATE_MONITOR;
         final int unknownFlags = cursorUpdateMode & ~KNOWN_FLAGS_MASK;
         if (unknownFlags != 0) {
             if (DEBUG) {
@@ -212,7 +212,7 @@
             return false;
         }
         mIMM.setUpdateCursorAnchorInfoMode(cursorUpdateMode);
-        if ((cursorUpdateMode & InputConnection.REQUEST_UPDATE_CURSOR_ANCHOR_INFO_IMMEDIATE) != 0) {
+        if ((cursorUpdateMode & InputConnection.CURSOR_UPDATE_IMMEDIATE) != 0) {
             if (mTextView == null) {
                 // In this case, FLAG_CURSOR_ANCHOR_INFO_IMMEDIATE is silently ignored.
                 // TODO: Return some notification code for the input method that indicates
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 62ea351..8ea28ec 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -367,6 +367,9 @@
                 peeker.mOpticalInsets[0], peeker.mOpticalInsets[1], peeker.mOpticalInsets[2], peeker.mOpticalInsets[3],
                 peeker.mOutlineInsets[0], peeker.mOutlineInsets[1], peeker.mOutlineInsets[2], peeker.mOutlineInsets[3],
                 peeker.mOutlineRadius, peeker.mOutlineAlpha, scale);
+        if (ninePatchInsets == NULL) {
+            return nullObjectReturn("nine patch insets == null");
+        }
         if (javaBitmap != NULL) {
             env->SetObjectField(javaBitmap, gBitmap_ninePatchInsetsFieldID, ninePatchInsets);
         }
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 7c41c2e..d7b75db 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -419,6 +419,7 @@
 {
     SkASSERT(bitmap);
     SkASSERT(bitmap->pixelRef());
+    SkASSERT(!env->ExceptionCheck());
     bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable;
     bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied;
 
diff --git a/core/res/res/drawable-hdpi/pointer_arrow_icon.xml b/core/res/res/drawable-hdpi/pointer_arrow_icon.xml
deleted file mode 100644
index a4cce5c..0000000
--- a/core/res/res/drawable-hdpi/pointer_arrow_icon.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
-    android:bitmap="@drawable/pointer_arrow"
-    android:hotSpotX="9"
-    android:hotSpotY="9" />
diff --git a/core/res/res/drawable-hdpi/pointer_spot_anchor.png b/core/res/res/drawable-hdpi/pointer_spot_anchor.png
index d7aca36..bdb5311 100644
--- a/core/res/res/drawable-hdpi/pointer_spot_anchor.png
+++ b/core/res/res/drawable-hdpi/pointer_spot_anchor.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/pointer_spot_hover.png b/core/res/res/drawable-hdpi/pointer_spot_hover.png
index 5041aa3..e7f2a0c 100644
--- a/core/res/res/drawable-hdpi/pointer_spot_hover.png
+++ b/core/res/res/drawable-hdpi/pointer_spot_hover.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/pointer_spot_touch.png b/core/res/res/drawable-hdpi/pointer_spot_touch.png
index 64a42a1..0326f91 100644
--- a/core/res/res/drawable-hdpi/pointer_spot_touch.png
+++ b/core/res/res/drawable-hdpi/pointer_spot_touch.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_spot_anchor.png b/core/res/res/drawable-mdpi/pointer_spot_anchor.png
index d7aca36..4e282e7 100644
--- a/core/res/res/drawable-mdpi/pointer_spot_anchor.png
+++ b/core/res/res/drawable-mdpi/pointer_spot_anchor.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_spot_anchor_icon.xml b/core/res/res/drawable-mdpi/pointer_spot_anchor_icon.xml
deleted file mode 100644
index 2222b8e..0000000
--- a/core/res/res/drawable-mdpi/pointer_spot_anchor_icon.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
-    android:bitmap="@drawable/pointer_spot_anchor"
-    android:hotSpotX="33"
-    android:hotSpotY="33" />
diff --git a/core/res/res/drawable-mdpi/pointer_spot_hover.png b/core/res/res/drawable-mdpi/pointer_spot_hover.png
index 5041aa3..67d0b06 100644
--- a/core/res/res/drawable-mdpi/pointer_spot_hover.png
+++ b/core/res/res/drawable-mdpi/pointer_spot_hover.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_spot_hover_icon.xml b/core/res/res/drawable-mdpi/pointer_spot_hover_icon.xml
deleted file mode 100644
index dc62a69..0000000
--- a/core/res/res/drawable-mdpi/pointer_spot_hover_icon.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
-    android:bitmap="@drawable/pointer_spot_hover"
-    android:hotSpotX="33"
-    android:hotSpotY="33" />
diff --git a/core/res/res/drawable-mdpi/pointer_spot_touch.png b/core/res/res/drawable-mdpi/pointer_spot_touch.png
index 64a42a1..45dc5c08 100644
--- a/core/res/res/drawable-mdpi/pointer_spot_touch.png
+++ b/core/res/res/drawable-mdpi/pointer_spot_touch.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_spot_touch_icon.xml b/core/res/res/drawable-mdpi/pointer_spot_touch_icon.xml
deleted file mode 100644
index 4bffee6..0000000
--- a/core/res/res/drawable-mdpi/pointer_spot_touch_icon.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
-    android:bitmap="@drawable/pointer_spot_touch"
-    android:hotSpotX="24"
-    android:hotSpotY="24" />
diff --git a/core/res/res/drawable-xhdpi/pointer_arrow_icon.xml b/core/res/res/drawable-xhdpi/pointer_arrow_icon.xml
deleted file mode 100644
index 2fbe45a..0000000
--- a/core/res/res/drawable-xhdpi/pointer_arrow_icon.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
-    android:bitmap="@drawable/pointer_arrow"
-    android:hotSpotX="12"
-    android:hotSpotY="12" />
diff --git a/core/res/res/drawable-xhdpi/pointer_spot_anchor.png b/core/res/res/drawable-xhdpi/pointer_spot_anchor.png
index ad41c97..fa9226e 100644
--- a/core/res/res/drawable-xhdpi/pointer_spot_anchor.png
+++ b/core/res/res/drawable-xhdpi/pointer_spot_anchor.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_spot_hover.png b/core/res/res/drawable-xhdpi/pointer_spot_hover.png
index e9b98f6..f09a778 100644
--- a/core/res/res/drawable-xhdpi/pointer_spot_hover.png
+++ b/core/res/res/drawable-xhdpi/pointer_spot_hover.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_spot_touch.png b/core/res/res/drawable-xhdpi/pointer_spot_touch.png
index e10d998..53d7a20 100644
--- a/core/res/res/drawable-xhdpi/pointer_spot_touch.png
+++ b/core/res/res/drawable-xhdpi/pointer_spot_touch.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_arrow_icon.xml b/core/res/res/drawable/pointer_arrow_icon.xml
similarity index 73%
rename from core/res/res/drawable-mdpi/pointer_arrow_icon.xml
rename to core/res/res/drawable/pointer_arrow_icon.xml
index 2f5676f..8f7d658 100644
--- a/core/res/res/drawable-mdpi/pointer_arrow_icon.xml
+++ b/core/res/res/drawable/pointer_arrow_icon.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
     android:bitmap="@drawable/pointer_arrow"
-    android:hotSpotX="6"
-    android:hotSpotY="6" />
+    android:hotSpotX="6dp"
+    android:hotSpotY="6dp" />
diff --git a/core/res/res/drawable-hdpi/pointer_spot_anchor_icon.xml b/core/res/res/drawable/pointer_spot_anchor_icon.xml
similarity index 73%
rename from core/res/res/drawable-hdpi/pointer_spot_anchor_icon.xml
rename to core/res/res/drawable/pointer_spot_anchor_icon.xml
index 2222b8e..73c0c11 100644
--- a/core/res/res/drawable-hdpi/pointer_spot_anchor_icon.xml
+++ b/core/res/res/drawable/pointer_spot_anchor_icon.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
     android:bitmap="@drawable/pointer_spot_anchor"
-    android:hotSpotX="33"
-    android:hotSpotY="33" />
+    android:hotSpotX="22dp"
+    android:hotSpotY="22dp" />
diff --git a/core/res/res/drawable-hdpi/pointer_spot_hover_icon.xml b/core/res/res/drawable/pointer_spot_hover_icon.xml
similarity index 73%
rename from core/res/res/drawable-hdpi/pointer_spot_hover_icon.xml
rename to core/res/res/drawable/pointer_spot_hover_icon.xml
index dc62a69..1d7440b 100644
--- a/core/res/res/drawable-hdpi/pointer_spot_hover_icon.xml
+++ b/core/res/res/drawable/pointer_spot_hover_icon.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
     android:bitmap="@drawable/pointer_spot_hover"
-    android:hotSpotX="33"
-    android:hotSpotY="33" />
+    android:hotSpotX="22dp"
+    android:hotSpotY="22dp" />
diff --git a/core/res/res/drawable-hdpi/pointer_spot_touch_icon.xml b/core/res/res/drawable/pointer_spot_touch_icon.xml
similarity index 73%
rename from core/res/res/drawable-hdpi/pointer_spot_touch_icon.xml
rename to core/res/res/drawable/pointer_spot_touch_icon.xml
index 4bffee6..f4f0639 100644
--- a/core/res/res/drawable-hdpi/pointer_spot_touch_icon.xml
+++ b/core/res/res/drawable/pointer_spot_touch_icon.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
     android:bitmap="@drawable/pointer_spot_touch"
-    android:hotSpotX="24"
-    android:hotSpotY="24" />
+    android:hotSpotX="16dp"
+    android:hotSpotY="16dp" />
diff --git a/core/res/res/layout/preference_material.xml b/core/res/res/layout/preference_material.xml
index 778e70a..a137149 100644
--- a/core/res/res/layout/preference_material.xml
+++ b/core/res/res/layout/preference_material.xml
@@ -24,7 +24,8 @@
     android:gravity="center_vertical"
     android:paddingStart="?attr/listPreferredItemPaddingStart"
     android:paddingEnd="?attr/listPreferredItemPaddingEnd"
-    android:background="?attr/activatedBackgroundIndicator">
+    android:background="?attr/activatedBackgroundIndicator"
+    android:clipToPadding="false">
 
     <LinearLayout
         android:id="@+id/icon_frame"
diff --git a/core/res/res/layout/screen_toolbar.xml b/core/res/res/layout/screen_toolbar.xml
index 039e89f..88c9cf6 100644
--- a/core/res/res/layout/screen_toolbar.xml
+++ b/core/res/res/layout/screen_toolbar.xml
@@ -41,6 +41,7 @@
             android:id="@+id/action_bar"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:navigationContentDescription="@string/action_bar_up_description"
             style="?attr/toolbarStyle" />
         <com.android.internal.widget.ActionBarContextView
             android:id="@+id/action_context_bar"
diff --git a/core/res/res/values-mcc310-mnc260/config.xml b/core/res/res/values-mcc310-mnc260/config.xml
index d602c9f..00cdaeb7 100644
--- a/core/res/res/values-mcc310-mnc260/config.xml
+++ b/core/res/res/values-mcc310-mnc260/config.xml
@@ -25,4 +25,9 @@
     -->
     <integer name="config_mobile_mtu">1440</integer>
 
+    <!-- Values for GPS configuration -->
+    <string-array translatable="false" name="config_gpsParameters">
+        <item>"SUPL_PORT=7279"</item>
+        <item>GPS_LOCK=1</item>
+    </string-array>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410/config.xml b/core/res/res/values-mcc310-mnc410/config.xml
index c7ae8c8..9e63047 100644
--- a/core/res/res/values-mcc310-mnc410/config.xml
+++ b/core/res/res/values-mcc310-mnc410/config.xml
@@ -40,4 +40,8 @@
         <item>315</item>
         <item>316</item>
     </string-array>
+    <!-- Values for GPS configuration -->
+    <string-array translatable="false" name="config_gpsParameters">
+        <item>"SUPL_HOST=supl.google.com"</item>
+    </string-array>
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a798d2e..ce2bc85 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -7112,9 +7112,9 @@
         <!-- Drawable to use as the icon bitmap. -->
         <attr name="bitmap" format="reference" />
         <!-- X coordinate of the icon hot spot. -->
-        <attr name="hotSpotX" format="float" />
+        <attr name="hotSpotX" format="dimension" />
         <!-- Y coordinate of the icon hot spot. -->
-        <attr name="hotSpotY" format="float" />
+        <attr name="hotSpotY" format="dimension" />
     </declare-styleable>
 
     <declare-styleable name="Storage">
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index af213ba..f5f079c 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1695,4 +1695,21 @@
     <string-array translatable="false" name="no_ems_support_sim_operators" />
 
     <bool name="config_auto_attach_data_on_creation">true</bool>
+
+    <!-- Values for GPS configuration -->
+    <string-array translatable="false" name="config_gpsParameters">
+        <item>SUPL_HOST=supl.google.com</item>
+        <item>SUPL_PORT=7275</item>
+        <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra2.bin</item>
+        <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra2.bin</item>
+        <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra2.bin</item>
+        <item>NTP_SERVER=north-america.pool.ntp.org</item>
+        <item>SUPL_VER=0x20000</item>
+        <item>CAPABILITIES=0x33</item>
+        <item>LPP_PROFILE=0</item>
+        <item>NMEA_PROVIDER=0</item>
+        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
+        <item>ERR_ESTIMATE=0</item>
+        <item>INTERMEDIATE_POS=0</item>
+    </string-array>
 </resources>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 8b3cbaf..452ee11 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -1068,16 +1068,16 @@
     <!-- Dialog styles -->
 
     <style name="AlertDialog.Material" parent="AlertDialog">
-        <item name="fullDark">@color/transparent</item>
-        <item name="topDark">@color/transparent</item>
-        <item name="centerDark">@color/transparent</item>
-        <item name="bottomDark">@color/transparent</item>
-        <item name="fullBright">@color/transparent</item>
-        <item name="topBright">@color/transparent</item>
-        <item name="centerBright">@color/transparent</item>
-        <item name="bottomBright">@color/transparent</item>
-        <item name="bottomMedium">@color/transparent</item>
-        <item name="centerMedium">@color/transparent</item>
+        <item name="fullDark">@null</item>
+        <item name="topDark">@null</item>
+        <item name="centerDark">@null</item>
+        <item name="bottomDark">@null</item>
+        <item name="fullBright">@null</item>
+        <item name="topBright">@null</item>
+        <item name="centerBright">@null</item>
+        <item name="bottomBright">@null</item>
+        <item name="bottomMedium">@null</item>
+        <item name="centerMedium">@null</item>
         <item name="layout">@layout/alert_dialog_material</item>
         <item name="listLayout">@layout/select_dialog_material</item>
         <item name="progressLayout">@layout/progress_dialog_material</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 0a274f8..06bd2ec 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1037,6 +1037,7 @@
   <java-symbol type="array" name="config_globalActionsList" />
   <java-symbol type="array" name="config_telephonyHardware" />
   <java-symbol type="array" name="config_keySystemUuidMapping" />
+  <java-symbol type="array" name="config_gpsParameters" />
 
   <java-symbol type="drawable" name="default_wallpaper" />
   <java-symbol type="drawable" name="indicator_input_error" />
diff --git a/graphics/java/android/graphics/drawable/RippleBackground.java b/graphics/java/android/graphics/drawable/RippleBackground.java
index 40a5e18..ab43e01 100644
--- a/graphics/java/android/graphics/drawable/RippleBackground.java
+++ b/graphics/java/android/graphics/drawable/RippleBackground.java
@@ -107,9 +107,6 @@
     /** Whether we have an explicit maximum radius. */
     private boolean mHasMaxRadius;
 
-    /** Whether we were canceled externally and should avoid self-removal. */
-    private boolean mCanceled;
-
     /**
      * Creates a new ripple.
      */
@@ -406,6 +403,9 @@
 
         mHardwareAnimating = true;
 
+        // Set up the software values to match the hardware end values.
+        mOuterOpacity = 0;
+
         invalidateSelf();
     }
 
@@ -414,10 +414,8 @@
      * removing the ripple from the list of animating ripples.
      */
     public void jump() {
-        mCanceled = true;
         endSoftwareAnimations();
         endHardwareAnimations();
-        mCanceled = false;
     }
 
     private void endSoftwareAnimations() {
@@ -446,7 +444,6 @@
         // listener on a pending animation, we also need to remove ourselves.
         if (!mPendingAnimations.isEmpty()) {
             mPendingAnimations.clear();
-            removeSelf();
         }
 
         mHardwareAnimating = false;
@@ -526,10 +523,8 @@
      * the ripple from the list of animating ripples.
      */
     public void cancel() {
-        mCanceled = true;
         cancelSoftwareAnimations();
         cancelHardwareAnimations(true);
-        mCanceled = false;
     }
 
     private void cancelSoftwareAnimations() {
@@ -555,7 +550,6 @@
         for (int i = 0; i < N; i++) {
             runningAnimations.get(i).cancel();
         }
-
         runningAnimations.clear();
 
         if (cancelPending && !mPendingAnimations.isEmpty()) {
@@ -565,13 +559,6 @@
         mHardwareAnimating = false;
     }
 
-    private void removeSelf() {
-        // The owner will invalidate itself.
-        if (!mCanceled) {
-            mOwner.removeBackground(this);
-        }
-    }
-
     private void invalidateSelf() {
         mOwner.invalidateSelf();
     }
@@ -579,7 +566,7 @@
     private final AnimatorListenerAdapter mAnimationListener = new AnimatorListenerAdapter() {
         @Override
         public void onAnimationEnd(Animator animation) {
-            removeSelf();
+            mHardwareAnimating = false;
         }
     };
 
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index b90fd81..e87a114 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -628,11 +628,10 @@
 
     @Override
     public void draw(@NonNull Canvas canvas) {
-        final boolean isProjected = isProjected();
         final boolean hasMask = mMask != null;
         final boolean drawNonMaskContent = mLayerState.mNum > (hasMask ? 1 : 0);
         final boolean drawMask = hasMask && mMask.getOpacity() != PixelFormat.OPAQUE;
-        final Rect bounds = isProjected ? getDirtyBounds() : getBounds();
+        final Rect bounds = getDirtyBounds();
 
         // If we have content, draw it into a layer first.
         final int contentLayer = drawNonMaskContent ?
@@ -685,13 +684,6 @@
         }
     }
 
-    void removeBackground(RippleBackground background) {
-        if (mBackground == background) {
-            mBackground = null;
-            invalidateSelf();
-        }
-    }
-
     private int getRippleIndex(Ripple ripple) {
         final Ripple[] ripples = mExitingRipples;
         final int count = mExitingRipplesCount;
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index b5d9729..1072b3c 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -195,6 +195,7 @@
     public Page openPage(int index) {
         throwIfClosed();
         throwIfPageOpened();
+        throwIfPageNotInDocument(index);
         mCurrentPage = new Page(index);
         return mCurrentPage;
     }
@@ -237,6 +238,12 @@
         }
     }
 
+    private void throwIfPageNotInDocument(int pageIndex) {
+        if (pageIndex >= mPageCount) {
+            throw new IllegalArgumentException("Invalid page index");
+        }
+    }
+
     /**
      * This class represents a PDF document page for rendering.
      */
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index c802b18..23fe1b9 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -88,7 +88,7 @@
         "varying vec2 ditherTexCoords;\n",
 };
 const char* gVS_Header_Varyings_HasRoundRectClip =
-        "varying vec2 roundRectPos;\n";
+        "varying highp vec2 roundRectPos;\n";
 const char* gVS_Main =
         "\nvoid main(void) {\n";
 const char* gVS_Main_OutTexCoords =
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 491a295..0a17e132 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -110,8 +110,7 @@
 }
 
 void CanvasContext::pauseSurface(ANativeWindow* window) {
-    // TODO: For now we just need a fence, in the future suspend any animations
-    // and such to prevent from trying to render into this surface
+    stopDrawing();
 }
 
 void CanvasContext::setup(int width, int height, const Vector3& lightCenter, float lightRadius,
diff --git a/location/java/android/location/GpsMeasurement.java b/location/java/android/location/GpsMeasurement.java
index 591a6ca..1550dc2 100644
--- a/location/java/android/location/GpsMeasurement.java
+++ b/location/java/android/location/GpsMeasurement.java
@@ -49,7 +49,7 @@
     private double mCarrierPhase;
     private double mCarrierPhaseUncertainty;
     private byte mLossOfLock;
-    private short mBitNumber;
+    private int mBitNumber;
     private short mTimeFromLastBitInMs;
     private double mDopplerShiftInHz;
     private double mDopplerShiftUncertaintyInHz;
@@ -784,14 +784,14 @@
      *
      * The value is only available if {@link #hasBitNumber()} is true.
      */
-    public short getBitNumber() {
+    public int getBitNumber() {
         return mBitNumber;
     }
 
     /**
      * Sets the bit number within the broadcast frame.
      */
-    public void setBitNumber(short bitNumber) {
+    public void setBitNumber(int bitNumber) {
         setFlag(HAS_BIT_NUMBER);
         mBitNumber = bitNumber;
     }
@@ -801,7 +801,7 @@
      */
     public void resetBitNumber() {
         resetFlag(HAS_BIT_NUMBER);
-        mBitNumber = Short.MIN_VALUE;
+        mBitNumber = Integer.MIN_VALUE;
     }
 
     /**
@@ -1161,7 +1161,7 @@
             gpsMeasurement.mCarrierPhase = parcel.readDouble();
             gpsMeasurement.mCarrierPhaseUncertainty = parcel.readDouble();
             gpsMeasurement.mLossOfLock = parcel.readByte();
-            gpsMeasurement.mBitNumber = (short) parcel.readInt();
+            gpsMeasurement.mBitNumber = parcel.readInt();
             gpsMeasurement.mTimeFromLastBitInMs = (short) parcel.readInt();
             gpsMeasurement.mDopplerShiftInHz = parcel.readDouble();
             gpsMeasurement.mDopplerShiftUncertaintyInHz = parcel.readDouble();
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index e2770b4..9ee7027 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -206,6 +206,125 @@
     public static final String EXTRA_MASTER_VOLUME_MUTED =
         "android.media.EXTRA_MASTER_VOLUME_MUTED";
 
+    /**
+     * Broadcast Action: Wired Headset plugged in or unplugged.
+     *
+     * You <em>cannot</em> receive this through components declared
+     * in manifests, only by explicitly registering for it with
+     * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
+     * Context.registerReceiver()}.
+     *
+     * <p>The intent will have the following extra values:
+     * <ul>
+     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
+     *   <li><em>name</em> - Headset type, human readable string </li>
+     *   <li><em>microphone</em> - 1 if headset has a microphone, 0 otherwise </li>
+     * </ul>
+     * </ul>
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_HEADSET_PLUG =
+            "android.intent.action.HEADSET_PLUG";
+
+    /**
+     * Broadcast Action: A sticky broadcast indicating an HMDI cable was plugged or unplugged
+     *
+     * The intent will have the following extra values: {@link #EXTRA_AUDIO_PLUG_STATE},
+     * {@link #EXTRA_MAX_CHANNEL_COUNT}, {@link #EXTRA_ENCODINGS}.
+     * <p>It can only be received by explicitly registering for it with
+     * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)}.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_HDMI_AUDIO_PLUG =
+            "android.media.action.HDMI_AUDIO_PLUG";
+
+    /**
+     * Extra used in {@link #ACTION_HDMI_AUDIO_PLUG} to communicate whether HDMI is plugged in
+     * or unplugged.
+     * An integer value of 1 indicates a plugged-in state, 0 is unplugged.
+     */
+    public static final String EXTRA_AUDIO_PLUG_STATE = "android.media.extra.audio_plug_state";
+
+    /**
+     * Extra used in {@link #ACTION_HDMI_AUDIO_PLUG} to define the maximum number of channels
+     * supported by the HDMI device.
+     * The corresponding integer value is only available when the device is plugged in (as expressed
+     * by {@link #EXTRA_AUDIO_PLUG_STATE}).
+     */
+    public static final String EXTRA_MAX_CHANNEL_COUNT = "android.media.extra.max_channel_count";
+
+    /**
+     * Extra used in {@link #ACTION_HDMI_AUDIO_PLUG} to define the audio encodings supported by
+     * the connected HDMI device.
+     * The corresponding array of encoding values is only available when the device is plugged in
+     * (as expressed by {@link #EXTRA_AUDIO_PLUG_STATE}). Encoding values are defined in
+     * {@link AudioFormat} (for instance see {@link AudioFormat#ENCODING_PCM_16BIT}). Use
+     * {@link android.content.Intent#getIntArrayExtra(String)} to retrieve the encoding values.
+     */
+    public static final String EXTRA_ENCODINGS = "android.media.extra.encodings";
+
+    /**
+     * Broadcast Action: An analog audio speaker/headset plugged in or unplugged.
+     *
+     * <p>The intent will have the following extra values:
+     * <ul>
+     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
+     *   <li><em>name</em> - Headset type, human readable string </li>
+     * </ul>
+     * </ul>
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_ANALOG_AUDIO_DOCK_PLUG =
+            "android.media.action.ANALOG_AUDIO_DOCK_PLUG";
+
+    /**
+     * Broadcast Action: A digital audio speaker/headset plugged in or unplugged.
+     *
+     * <p>The intent will have the following extra values:
+     * <ul>
+     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
+     *   <li><em>name</em> - Headset type, human readable string </li>
+     * </ul>
+     * </ul>
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_DIGITAL_AUDIO_DOCK_PLUG =
+            "android.media.action.DIGITAL_AUDIO_DOCK_PLUG";
+
+    /**
+     * Broadcast Action: A USB audio accessory was plugged in or unplugged.
+     *
+     * <p>The intent will have the following extra values:
+     * <ul>
+     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
+     *   <li><em>card</em> - ALSA card number (integer) </li>
+     *   <li><em>device</em> - ALSA device number (integer) </li>
+     * </ul>
+     * </ul>
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_USB_AUDIO_ACCESSORY_PLUG =
+            "android.media.action.USB_AUDIO_ACCESSORY_PLUG";
+
+    /**
+     * Broadcast Action: A USB audio device was plugged in or unplugged.
+     *
+     * <p>The intent will have the following extra values:
+     * <ul>
+     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
+     *   <li><em>card</em> - ALSA card number (integer) </li>
+     *   <li><em>device</em> - ALSA device number (integer) </li>
+     * </ul>
+     * </ul>
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_USB_AUDIO_DEVICE_PLUG =
+            "android.media.action.USB_AUDIO_DEVICE_PLUG";
+
     /** The audio stream for phone calls */
     public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_CALL;
     /** The audio stream for system sounds */
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index d002924..dd14c11 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -544,6 +544,9 @@
         MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = SystemProperties.getInt(
             "ro.config.vc_call_vol_steps",
            MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]);
+        MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = SystemProperties.getInt(
+            "ro.config.music_vol_steps",
+           MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]);
 
         sSoundEffectVolumeDb = context.getResources().getInteger(
                 com.android.internal.R.integer.config_soundEffectVolumeDb);
@@ -599,8 +602,8 @@
                 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
         intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
         intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
-        intentFilter.addAction(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG);
-        intentFilter.addAction(Intent.ACTION_USB_AUDIO_DEVICE_PLUG);
+        intentFilter.addAction(AudioManager.ACTION_USB_AUDIO_ACCESSORY_PLUG);
+        intentFilter.addAction(AudioManager.ACTION_USB_AUDIO_DEVICE_PLUG);
         intentFilter.addAction(Intent.ACTION_SCREEN_ON);
         intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
@@ -1564,6 +1567,9 @@
                 callingPackage) != AppOpsManager.MODE_ALLOWED) {
             return;
         }
+        if (!checkAudioSettingsPermission("setMicrophoneMute()")) {
+            return;
+        }
 
         AudioSystem.muteMicrophone(on);
         // Post a persist microphone msg.
@@ -4363,10 +4369,10 @@
             intent.putExtra("microphone", 0);
         } else if (device == AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET) {
             connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS;
-            intent.setAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
+            intent.setAction(AudioManager.ACTION_ANALOG_AUDIO_DOCK_PLUG);
         } else if (device == AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET) {
             connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS;
-            intent.setAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
+            intent.setAction(AudioManager.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
         } else if (device == AudioSystem.DEVICE_OUT_HDMI) {
             connType = AudioRoutesInfo.MAIN_HDMI;
             configureHdmiPlugIntent(intent, state);
@@ -4452,7 +4458,8 @@
     }
 
     private void configureHdmiPlugIntent(Intent intent, int state) {
-        intent.setAction(Intent.ACTION_HDMI_AUDIO_PLUG);
+        intent.setAction(AudioManager.ACTION_HDMI_AUDIO_PLUG);
+        intent.putExtra(AudioManager.EXTRA_AUDIO_PLUG_STATE, state);
         if (state == 1) {
             ArrayList<AudioPort> ports = new ArrayList<AudioPort>();
             int[] portGeneration = new int[1];
@@ -4476,7 +4483,7 @@
                                 for (int i = 0 ; i < encodingArray.length ; i++) {
                                     encodingArray[i] = encodingList.get(i);
                                 }
-                                intent.putExtra("encodings", encodingArray);
+                                intent.putExtra(AudioManager.EXTRA_ENCODINGS, encodingArray);
                             }
                             // find the maximum supported number of channels
                             int maxChannels = 0;
@@ -4486,7 +4493,7 @@
                                     maxChannels = channelCount;
                                 }
                             }
-                            intent.putExtra("maxChannelCount", maxChannels);
+                            intent.putExtra(AudioManager.EXTRA_MAX_CHANNEL_COUNT, maxChannels);
                         }
                     }
                 }
@@ -4580,7 +4587,7 @@
                         }
                     }
                 }
-            } else if (action.equals(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG)) {
+            } else if (action.equals(AudioManager.ACTION_USB_AUDIO_ACCESSORY_PLUG)) {
                 state = intent.getIntExtra("state", 0);
 
                 int alsaCard = intent.getIntExtra("card", -1);
@@ -4592,7 +4599,7 @@
                 // Playback Device
                 outDevice = AudioSystem.DEVICE_OUT_USB_ACCESSORY;
                 setWiredDeviceConnectionState(outDevice, state, params);
-            } else if (action.equals(Intent.ACTION_USB_AUDIO_DEVICE_PLUG)) {
+            } else if (action.equals(AudioManager.ACTION_USB_AUDIO_DEVICE_PLUG)) {
                 // FIXME Does not yet handle the case where the setting is changed
                 // after device connection.  Ideally we should handle the settings change
                 // in SettingsObserver. Here we should log that a USB device is connected
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 7c3b4fc..9343aa4 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -961,6 +961,10 @@
      * @param context the Context to use when resolving the Uri
      * @param uri the Content URI of the data you want to play
      * @param headers the headers to be sent together with the request for the data
+     *                Note that the cross domain redirection is allowed by default, but that can be
+     *                changed with key/value pairs through the headers parameter with
+     *                "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value
+     *                to disallow or allow cross domain redirection.
      * @throws IllegalStateException if it is called in an invalid state
      */
     public void setDataSource(Context context, Uri uri, Map<String, String> headers)
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index debaf45..338c711 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -25,8 +25,8 @@
 import android.content.ServiceConnection;
 import android.content.pm.ParceledListSlice;
 import android.media.MediaDescription;
+import android.media.session.MediaController;
 import android.media.session.MediaSession;
-import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -67,14 +67,14 @@
     private final ConnectionCallback mCallback;
     private final Bundle mRootHints;
     private final Handler mHandler = new Handler();
-    private final ArrayMap<Uri,Subscription> mSubscriptions =
-            new ArrayMap<Uri, MediaBrowser.Subscription>();
+    private final ArrayMap<String,Subscription> mSubscriptions =
+            new ArrayMap<String, MediaBrowser.Subscription>();
 
     private int mState = CONNECT_STATE_DISCONNECTED;
     private MediaServiceConnection mServiceConnection;
     private IMediaBrowserService mServiceBinder;
     private IMediaBrowserServiceCallbacks mServiceCallbacks;
-    private Uri mRootUri;
+    private String mRootId;
     private MediaSession.Token mMediaSessionToken;
     private Bundle mExtras;
 
@@ -85,7 +85,7 @@
      * @param serviceComponent The component name of the media browse service.
      * @param callback The connection callback.
      * @param rootHints An optional bundle of service-specific arguments to send
-     * to the media browse service when connecting and retrieving the root uri
+     * to the media browse service when connecting and retrieving the root id
      * for browsing, or null if none.  The contents of this bundle may affect
      * the information returned when browsing.
      */
@@ -212,7 +212,7 @@
         mServiceConnection = null;
         mServiceBinder = null;
         mServiceCallbacks = null;
-        mRootUri = null;
+        mRootId = null;
         mMediaSessionToken = null;
     }
 
@@ -235,20 +235,20 @@
     }
 
     /**
-     * Gets the root Uri.
+     * Gets the root id.
      * <p>
-     * Note that the root uri may become invalid or change when when the
+     * Note that the root id may become invalid or change when when the
      * browser is disconnected.
      * </p>
      *
      * @throws IllegalStateException if not connected.
      */
-    public @NonNull Uri getRoot() {
+    public @NonNull String getRoot() {
         if (!isConnected()) {
             throw new IllegalStateException("getSessionToken() called while not connected (state="
                     + getStateLabel(mState) + ")");
         }
-        return mRootUri;
+        return mRootId;
     }
 
     /**
@@ -285,35 +285,35 @@
 
     /**
      * Queries for information about the media items that are contained within
-     * the specified Uri and subscribes to receive updates when they change.
+     * the specified id and subscribes to receive updates when they change.
      * <p>
      * The list of subscriptions is maintained even when not connected and is
      * restored after reconnection.  It is ok to subscribe while not connected
      * but the results will not be returned until the connection completes.
      * </p><p>
-     * If the uri is already subscribed with a different callback then the new
+     * If the id is already subscribed with a different callback then the new
      * callback will replace the previous one.
      * </p>
      *
-     * @param parentUri The uri of the parent media item whose list of children
+     * @param parentId The id of the parent media item whose list of children
      * will be subscribed.
      * @param callback The callback to receive the list of children.
      */
-    public void subscribe(@NonNull Uri parentUri, @NonNull SubscriptionCallback callback) {
+    public void subscribe(@NonNull String parentId, @NonNull SubscriptionCallback callback) {
         // Check arguments.
-        if (parentUri == null) {
-            throw new IllegalArgumentException("parentUri is null");
+        if (parentId == null) {
+            throw new IllegalArgumentException("parentId is null");
         }
         if (callback == null) {
             throw new IllegalArgumentException("callback is null");
         }
 
         // Update or create the subscription.
-        Subscription sub = mSubscriptions.get(parentUri);
+        Subscription sub = mSubscriptions.get(parentId);
         boolean newSubscription = sub == null;
         if (newSubscription) {
-            sub = new Subscription(parentUri);
-            mSubscriptions.put(parentUri, sub);
+            sub = new Subscription(parentId);
+            mSubscriptions.put(parentId, sub);
         }
         sub.callback = callback;
 
@@ -321,42 +321,42 @@
         // connected, the service will be told when we connect.
         if (mState == CONNECT_STATE_CONNECTED && newSubscription) {
             try {
-                mServiceBinder.addSubscription(parentUri, mServiceCallbacks);
+                mServiceBinder.addSubscription(parentId, mServiceCallbacks);
             } catch (RemoteException ex) {
                 // Process is crashing.  We will disconnect, and upon reconnect we will
                 // automatically reregister. So nothing to do here.
-                Log.d(TAG, "addSubscription failed with RemoteException parentUri=" + parentUri);
+                Log.d(TAG, "addSubscription failed with RemoteException parentId=" + parentId);
             }
         }
     }
 
     /**
-     * Unsubscribes for changes to the children of the specified Uri.
+     * Unsubscribes for changes to the children of the specified media id.
      * <p>
      * The query callback will no longer be invoked for results associated with
-     * this Uri once this method returns.
+     * this id once this method returns.
      * </p>
      *
-     * @param parentUri The uri of the parent media item whose list of children
+     * @param parentId The id of the parent media item whose list of children
      * will be unsubscribed.
      */
-    public void unsubscribe(@NonNull Uri parentUri) {
+    public void unsubscribe(@NonNull String parentId) {
         // Check arguments.
-        if (parentUri == null) {
-            throw new IllegalArgumentException("parentUri is null");
+        if (parentId == null) {
+            throw new IllegalArgumentException("parentId is null");
         }
 
         // Remove from our list.
-        final Subscription sub = mSubscriptions.remove(parentUri);
+        final Subscription sub = mSubscriptions.remove(parentId);
 
         // Tell the service if necessary.
         if (mState == CONNECT_STATE_CONNECTED && sub != null) {
             try {
-                mServiceBinder.removeSubscription(parentUri, mServiceCallbacks);
+                mServiceBinder.removeSubscription(parentId, mServiceCallbacks);
             } catch (RemoteException ex) {
                 // Process is crashing.  We will disconnect, and upon reconnect we will
                 // automatically reregister. So nothing to do here.
-                Log.d(TAG, "removeSubscription failed with RemoteException parentUri=" + parentUri);
+                Log.d(TAG, "removeSubscription failed with RemoteException parentId=" + parentId);
             }
         }
     }
@@ -380,7 +380,7 @@
     }
 
     private final void onServiceConnected(final IMediaBrowserServiceCallbacks callback,
-            final Uri root, final MediaSession.Token session, final Bundle extra) {
+            final String root, final MediaSession.Token session, final Bundle extra) {
         mHandler.post(new Runnable() {
             @Override
             public void run() {
@@ -395,7 +395,7 @@
                             + getStateLabel(mState) + "... ignoring");
                     return;
                 }
-                mRootUri = root;
+                mRootId = root;
                 mMediaSessionToken = session;
                 mExtras = extra;
                 mState = CONNECT_STATE_CONNECTED;
@@ -408,13 +408,13 @@
 
                 // we may receive some subscriptions before we are connected, so re-subscribe
                 // everything now
-                for (Uri uri : mSubscriptions.keySet()) {
+                for (String id : mSubscriptions.keySet()) {
                     try {
-                        mServiceBinder.addSubscription(uri, mServiceCallbacks);
+                        mServiceBinder.addSubscription(id, mServiceCallbacks);
                     } catch (RemoteException ex) {
                         // Process is crashing.  We will disconnect, and upon reconnect we will
                         // automatically reregister. So nothing to do here.
-                        Log.d(TAG, "addSubscription failed with RemoteException parentUri=" + uri);
+                        Log.d(TAG, "addSubscription failed with RemoteException parentId=" + id);
                     }
                 }
             }
@@ -448,8 +448,8 @@
         });
     }
 
-    private final void onLoadChildren(final IMediaBrowserServiceCallbacks callback, final Uri uri,
-            final ParceledListSlice list) {
+    private final void onLoadChildren(final IMediaBrowserServiceCallbacks callback,
+            final String parentId, final ParceledListSlice list) {
         mHandler.post(new Runnable() {
             @Override
             public void run() {
@@ -461,24 +461,24 @@
 
                 List<MediaItem> data = list.getList();
                 if (DBG) {
-                    Log.d(TAG, "onLoadChildren for " + mServiceComponent + " uri=" + uri);
+                    Log.d(TAG, "onLoadChildren for " + mServiceComponent + " id=" + parentId);
                 }
                 if (data == null) {
                     data = Collections.emptyList();
                 }
 
                 // Check that the subscription is still subscribed.
-                final Subscription subscription = mSubscriptions.get(uri);
+                final Subscription subscription = mSubscriptions.get(parentId);
                 if (subscription == null) {
                     if (DBG) {
-                        Log.d(TAG, "onLoadChildren for uri that isn't subscribed uri="
-                                + uri);
+                        Log.d(TAG, "onLoadChildren for id that isn't subscribed id="
+                                + parentId);
                     }
                     return;
                 }
 
                 // Tell the app.
-                subscription.callback.onChildrenLoaded(uri, data);
+                subscription.callback.onChildrenLoaded(parentId, data);
             }
         });
     }
@@ -514,7 +514,7 @@
         Log.d(TAG, "  mServiceConnection=" + mServiceConnection);
         Log.d(TAG, "  mServiceBinder=" + mServiceBinder);
         Log.d(TAG, "  mServiceCallbacks=" + mServiceCallbacks);
-        Log.d(TAG, "  mRootUri=" + mRootUri);
+        Log.d(TAG, "  mRootId=" + mRootId);
         Log.d(TAG, "  mMediaSessionToken=" + mMediaSessionToken);
     }
 
@@ -535,7 +535,8 @@
         /**
          * Flag: Indicates that the item is playable.
          * <p>
-         * The Uri of this item may be passed to link android.media.session.MediaController#play(Uri)
+         * The id of this item may be passed to
+         * {@link MediaController.TransportControls#playFromMediaId(String, Bundle)}
          * to start playing it.
          * </p>
          */
@@ -669,18 +670,18 @@
         /**
          * Called when the list of children is loaded or updated.
          */
-        public void onChildrenLoaded(@NonNull Uri parentUri,
+        public void onChildrenLoaded(@NonNull String parentId,
                                      @NonNull List<MediaItem> children) {
         }
 
         /**
-         * Called when the Uri doesn't exist or other errors in subscribing.
+         * Called when the id doesn't exist or other errors in subscribing.
          * <p>
          * If this is called, the subscription remains until {@link MediaBrowser#unsubscribe}
          * called, because some errors may heal themselves.
          * </p>
          */
-        public void onError(@NonNull Uri uri) {
+        public void onError(@NonNull String id) {
         }
     }
 
@@ -783,7 +784,7 @@
          * are the initial data as requested.
          */
         @Override
-        public void onConnect(final Uri root, final MediaSession.Token session,
+        public void onConnect(final String root, final MediaSession.Token session,
                 final Bundle extras) {
             MediaBrowser mediaBrowser = mMediaBrowser.get();
             if (mediaBrowser != null) {
@@ -803,20 +804,20 @@
         }
 
         @Override
-        public void onLoadChildren(final Uri uri, final ParceledListSlice list) {
+        public void onLoadChildren(final String parentId, final ParceledListSlice list) {
             MediaBrowser mediaBrowser = mMediaBrowser.get();
             if (mediaBrowser != null) {
-                mediaBrowser.onLoadChildren(this, uri, list);
+                mediaBrowser.onLoadChildren(this, parentId, list);
             }
         }
     }
 
     private static class Subscription {
-        final Uri uri;
+        final String id;
         SubscriptionCallback callback;
 
-        Subscription(Uri u) {
-            this.uri = u;
+        Subscription(String id) {
+            this.id = id;
         }
     }
 }
diff --git a/media/java/android/media/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java
index 99d3ceb..3a74d93 100644
--- a/media/java/android/media/projection/MediaProjection.java
+++ b/media/java/android/media/projection/MediaProjection.java
@@ -97,12 +97,12 @@
      */
     public VirtualDisplay createVirtualDisplay(@NonNull String name,
             int width, int height, int dpi, boolean isSecure, @Nullable Surface surface,
-            @Nullable VirtualDisplay.Callbacks callbacks, @Nullable Handler handler) {
+            @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
         DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
         int flags = isSecure ? DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE : 0;
         return dm.createVirtualDisplay(this, name, width, height, dpi, surface,
                     flags | DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR |
-                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION, callbacks, handler);
+                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION, callback, handler);
     }
 
     /**
@@ -120,21 +120,21 @@
      * should be rendered, or null if there is none initially.
      * @param flags A combination of virtual display flags. See {@link DisplayManager} for the full
      * list of flags.
-     * @param callbacks Callbacks to call when the virtual display's state
+     * @param callback Callback to call when the virtual display's state
      * changes, or null if none.
      * @param handler The {@link android.os.Handler} on which the callback should be
      * invoked, or null if the callback should be invoked on the calling
      * thread's main {@link android.os.Looper}.
      *
      * @see android.hardware.display.DisplayManager#createVirtualDisplay(
-     * String, int, int, int, int, Surface, VirtualDisplay.Callbacks, Handler)
+     * String, int, int, int, int, Surface, VirtualDisplay.Callback, Handler)
      */
     public VirtualDisplay createVirtualDisplay(@NonNull String name,
             int width, int height, int dpi, int flags, @Nullable Surface surface,
-            @Nullable VirtualDisplay.Callbacks callbacks, @Nullable Handler handler) {
+            @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
         DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
         return dm.createVirtualDisplay(
-                    this, name, width, height, dpi, surface, flags, callbacks, handler);
+                    this, name, width, height, dpi, surface, flags, callback, handler);
     }
 
     /**
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 9641f83..4d4d646 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -47,8 +47,9 @@
  * receive updates from the session, such as metadata and play state changes.
  * <p>
  * A MediaController can be created through {@link MediaSessionManager} if you
- * hold the "android.permission.MEDIA_CONTENT_CONTROL" permission or directly if
- * you have a {@link MediaSession.Token} from the session owner.
+ * hold the "android.permission.MEDIA_CONTENT_CONTROL" permission or are an
+ * enabled notification listener or by getting a {@link MediaSession.Token}
+ * directly from the session owner.
  * <p>
  * MediaController objects are thread-safe.
  */
@@ -612,14 +613,18 @@
 
         /**
          * Request that the player start playback for a specific search query.
+         * An empty or null query should be treated as a request to play any
+         * music.
          *
          * @param query The search query.
-         * @param extras Optional extras that can include extra information about the query.
+         * @param extras Optional extras that can include extra information
+         *            about the query.
          */
         public void playFromSearch(String query, Bundle extras) {
-            if (TextUtils.isEmpty(query)) {
-                throw new IllegalArgumentException(
-                        "You must specify a non-empty search query for playFromSearch.");
+            if (query == null) {
+                // This is to remain compatible with
+                // INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
+                query = "";
             }
             try {
                 mSessionBinder.playFromSearch(query, extras);
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index ae8ce4b..095f885 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -771,7 +771,10 @@
         }
 
         /**
-         * Override to handle requests to begin playback from a search query.
+         * Override to handle requests to begin playback from a search query. An
+         * empty query indicates that the app may play any music. The
+         * implementation should attempt to make a smart choice about what to
+         * play.
          */
         public void onPlayFromSearch(String query, Bundle extras) {
         }
diff --git a/media/java/android/media/tv/TvContentRating.java b/media/java/android/media/tv/TvContentRating.java
index 93b40fb9..d5bf38c 100644
--- a/media/java/android/media/tv/TvContentRating.java
+++ b/media/java/android/media/tv/TvContentRating.java
@@ -300,11 +300,7 @@
  *         <td>TV content rating system for Serbia</td>
  *     </tr>
  *     <tr>
- *         <td>SG_FTV</td>
- *         <td>TV content rating system for Singapore</td>
- *     </tr>
- *     <tr>
- *         <td>SG_PTV</td>
+ *         <td>SG_TV</td>
  *         <td>TV content rating system for Singapore</td>
  *     </tr>
  *     <tr>
@@ -1215,22 +1211,30 @@
  *         <td>Program not suitable for minors under the age of 18</td>
  *     </tr>
  *     <tr>
- *         <td valign="top" rowspan="2">SG_FTV</td>
- *         <td>SG_FTV_PG</td>
- *         <td>Suitable for most but parents should guide their young</td>
+ *         <td valign="top" rowspan="6">SG_TV</td>
+ *         <td>SG_TV_G</td>
+ *         <td>Suitable for all ages</td>
  *     </tr>
  *     <tr>
- *         <td>SG_FTV_PG13</td>
- *         <td>Parental Guidance Strongly Cautioned - Suitable for 13 And Above</td>
+ *         <td>SG_TV_PG</td>
+ *         <td>Suitable for all but parents should guide their young</td>
  *     </tr>
  *     <tr>
- *         <td valign="top" rowspan="2">SG_PTV</td>
- *         <td>SG_PTV_NC16</td>
- *         <td>No Children Under 16</td>
+ *         <td>SG_TV_PG13</td>
+ *         <td>Suitable for persons aged 13 and above but parental guidance is advised for children
+ *         below 13</td>
  *     </tr>
  *     <tr>
- *         <td>SG_PTV_M18</td>
- *         <td>Nobody under age 18 is admitted</td>
+ *         <td>SG_TV_NC16</td>
+ *         <td>Suitable for persons aged 16 and above</td>
+ *     </tr>
+ *     <tr>
+ *         <td>SG_TV_M18</td>
+ *         <td>Suitable for persons aged 18 and above</td>
+ *     </tr>
+ *     <tr>
+ *         <td>SG_TV_R21</td>
+ *         <td>Suitable for adults aged 21 and above</td>
  *     </tr>
  *     <tr>
  *         <td valign="top" rowspan="4">SI_TV</td>
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 7f1c304..b3890d4 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -945,8 +945,8 @@
         /**
          * The comma-separated audio languages of this TV program.
          * <p>
-         * This is used to describe available audio languages included in the program. Use
-         * 3-character language code as specified by ISO 639-2.
+         * This is used to describe available audio languages included in the program. Use either
+         * ISO 639-1 or 639-2/T codes.
          * </p><p>
          * Type: TEXT
          * </p>
diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java
index 00183bb..46b8871 100644
--- a/media/java/android/media/tv/TvInputInfo.java
+++ b/media/java/android/media/tv/TvInputInfo.java
@@ -416,23 +416,22 @@
      * Loads the user-displayed icon for this TV input.
      *
      * @param context Supplies a {@link Context} used to load the icon.
-     * @return a Drawable containing the TV input's icon. If the TV input does not have
-     *         an icon, application icon is returned. If it's unavailable too, system default is
-     *         returned.
+     * @return a Drawable containing the TV input's icon. If the TV input does not have an icon,
+     *         application's icon is returned. If it's unavailable too, {@code null} is returned.
      */
     public Drawable loadIcon(Context context) {
         if (mIconUri == null) {
-            return loadDefaultIcon(context);
+            return loadServiceIcon(context);
         }
         try (InputStream is = context.getContentResolver().openInputStream(mIconUri)) {
             Drawable drawable = Drawable.createFromStream(is, null);
             if (drawable == null) {
-                return loadDefaultIcon(context);
+                return loadServiceIcon(context);
             }
             return drawable;
         } catch (IOException e) {
             Log.w(TAG, "Loading the default icon due to a failure on loading " + mIconUri, e);
-            return loadDefaultIcon(context);
+            return loadServiceIcon(context);
         }
     }
 
@@ -486,7 +485,11 @@
         dest.writeByte(mIsConnectedToHdmiSwitch ? (byte) 1 : 0);
     }
 
-    private Drawable loadDefaultIcon(Context context) {
+    private Drawable loadServiceIcon(Context context) {
+        if (mService.serviceInfo.icon == 0
+                && mService.serviceInfo.applicationInfo.icon == 0) {
+            return null;
+        }
         return mService.serviceInfo.loadIcon(context.getPackageManager());
     }
 
diff --git a/media/java/android/service/media/IMediaBrowserService.aidl b/media/java/android/service/media/IMediaBrowserService.aidl
index 2631ddd..01285ee 100644
--- a/media/java/android/service/media/IMediaBrowserService.aidl
+++ b/media/java/android/service/media/IMediaBrowserService.aidl
@@ -16,6 +16,6 @@
     void connect(String pkg, in Bundle rootHints, IMediaBrowserServiceCallbacks callbacks);
     void disconnect(IMediaBrowserServiceCallbacks callbacks);
 
-    void addSubscription(in Uri uri, IMediaBrowserServiceCallbacks callbacks);
-    void removeSubscription(in Uri uri, IMediaBrowserServiceCallbacks callbacks);
+    void addSubscription(String uri, IMediaBrowserServiceCallbacks callbacks);
+    void removeSubscription(String uri, IMediaBrowserServiceCallbacks callbacks);
 }
\ No newline at end of file
diff --git a/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
index 7702a50b..2a37ada 100644
--- a/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
+++ b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
@@ -5,7 +5,6 @@
 import android.content.pm.ParceledListSlice;
 import android.graphics.Bitmap;
 import android.media.session.MediaSession;
-import android.net.Uri;
 import android.os.Bundle;
 
 /**
@@ -16,12 +15,12 @@
 oneway interface IMediaBrowserServiceCallbacks {
     /**
      * Invoked when the connected has been established.
-     * @param root The root Uri for browsing.
+     * @param root The root media id for browsing.
      * @param session The {@link MediaSession.Token media session token} that can be used to control
      *         the playback of the media app.
      * @param extra Extras returned by the media service.
      */
-    void onConnect(in Uri root, in MediaSession.Token session, in Bundle extras);
+    void onConnect(String root, in MediaSession.Token session, in Bundle extras);
     void onConnectFailed();
-    void onLoadChildren(in Uri uri, in ParceledListSlice list);
+    void onLoadChildren(String mediaId, in ParceledListSlice list);
 }
diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java
index 4d6fd7b..317cb96 100644
--- a/media/java/android/service/media/MediaBrowserService.java
+++ b/media/java/android/service/media/MediaBrowserService.java
@@ -25,12 +25,8 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
 import android.media.browse.MediaBrowser;
-import android.media.browse.MediaBrowser.MediaItem;
 import android.media.session.MediaSession;
-import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -38,18 +34,13 @@
 import android.os.RemoteException;
 import android.service.media.IMediaBrowserService;
 import android.service.media.IMediaBrowserServiceCallbacks;
-import android.service.media.IMediaBrowserService.Stub;
 import android.util.ArrayMap;
 import android.util.Log;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 /**
  * Base class for media browse services.
@@ -96,7 +87,7 @@
         Bundle rootHints;
         IMediaBrowserServiceCallbacks callbacks;
         BrowserRoot root;
-        HashSet<Uri> subscriptions = new HashSet();
+        HashSet<String> subscriptions = new HashSet();
     }
 
     /**
@@ -199,7 +190,7 @@
                         } else {
                             try {
                                 mConnections.put(b, connection);
-                                callbacks.onConnect(connection.root.getRootUri(),
+                                callbacks.onConnect(connection.root.getRootId(),
                                         mSession, connection.root.getExtras());
                             } catch (RemoteException ex) {
                                 Log.w(TAG, "Calling onConnect() failed. Dropping client. "
@@ -229,7 +220,7 @@
 
 
         @Override
-        public void addSubscription(final Uri uri, final IMediaBrowserServiceCallbacks callbacks) {
+        public void addSubscription(final String id, final IMediaBrowserServiceCallbacks callbacks) {
             mHandler.post(new Runnable() {
                     @Override
                     public void run() {
@@ -238,18 +229,18 @@
                         // Get the record for the connection
                         final ConnectionRecord connection = mConnections.get(b);
                         if (connection == null) {
-                            Log.w(TAG, "addSubscription for callback that isn't registered uri="
-                                + uri);
+                            Log.w(TAG, "addSubscription for callback that isn't registered id="
+                                + id);
                             return;
                         }
 
-                        MediaBrowserService.this.addSubscription(uri, connection);
+                        MediaBrowserService.this.addSubscription(id, connection);
                     }
                 });
         }
 
         @Override
-        public void removeSubscription(final Uri uri,
+        public void removeSubscription(final String id,
                 final IMediaBrowserServiceCallbacks callbacks) {
             mHandler.post(new Runnable() {
                 @Override
@@ -258,12 +249,12 @@
 
                     ConnectionRecord connection = mConnections.get(b);
                     if (connection == null) {
-                        Log.w(TAG, "removeSubscription for callback that isn't registered uri="
-                                + uri);
+                        Log.w(TAG, "removeSubscription for callback that isn't registered id="
+                                + id);
                         return;
                     }
-                    if (!connection.subscriptions.remove(uri)) {
-                        Log.w(TAG, "removeSubscription called for " + uri
+                    if (!connection.subscriptions.remove(id)) {
+                        Log.w(TAG, "removeSubscription called for " + id
                                 + " which is not subscribed");
                     }
                 }
@@ -294,7 +285,7 @@
      * <p>
      * The implementation should verify that the client package has
      * permission to access browse media information before returning
-     * the root uri; it should return null if the client is not
+     * the root id; it should return null if the client is not
      * allowed to access this information.
      * </p>
      *
@@ -303,7 +294,7 @@
      * @param clientUid The uid of the application which is requesting
      * access to browse media.
      * @param rootHints An optional bundle of service-specific arguments to send
-     * to the media browse service when connecting and retrieving the root uri
+     * to the media browse service when connecting and retrieving the root id
      * for browsing, or null if none.  The contents of this bundle may affect
      * the information returned when browsing.
      */
@@ -319,11 +310,11 @@
      * from this function, and then {@link Result#sendResult result.sendResult} called when
      * the loading is complete.
      *
-     * @param parentUri The uri of the parent media item whose
+     * @param parentId The id of the parent media item whose
      * children are to be queried.
-     * @return The list of children, or null if the uri is invalid.
+     * @return The list of children, or null if the id is invalid.
      */
-    public abstract void onLoadChildren(@NonNull Uri parentUri,
+    public abstract void onLoadChildren(@NonNull String parentId,
             @NonNull Result<List<MediaBrowser.MediaItem>> result);
 
     /**
@@ -351,23 +342,23 @@
 
     /**
      * Notifies all connected media browsers that the children of
-     * the specified Uri have changed in some way.
+     * the specified parent id have changed in some way.
      * This will cause browsers to fetch subscribed content again.
      *
-     * @param parentUri The uri of the parent media item whose
+     * @param parentId The id of the parent media item whose
      * children changed.
      */
-    public void notifyChildrenChanged(@NonNull final Uri parentUri) {
-        if (parentUri == null) {
-            throw new IllegalArgumentException("parentUri cannot be null in notifyChildrenChanged");
+    public void notifyChildrenChanged(@NonNull final String parentId) {
+        if (parentId == null) {
+            throw new IllegalArgumentException("parentId cannot be null in notifyChildrenChanged");
         }
         mHandler.post(new Runnable() {
             @Override
             public void run() {
                 for (IBinder binder : mConnections.keySet()) {
                     ConnectionRecord connection = mConnections.get(binder);
-                    if (connection.subscriptions.contains(parentUri)) {
-                        performLoadChildren(parentUri, connection);
+                    if (connection.subscriptions.contains(parentId)) {
+                        performLoadChildren(parentId, connection);
                     }
                 }
             }
@@ -395,13 +386,13 @@
     /**
      * Save the subscription and if it is a new subscription send the results.
      */
-    private void addSubscription(Uri uri, ConnectionRecord connection) {
+    private void addSubscription(String id, ConnectionRecord connection) {
         // Save the subscription
-        final boolean added = connection.subscriptions.add(uri);
+        final boolean added = connection.subscriptions.add(id);
 
         // If this is a new subscription, send the results
         if (added) {
-            performLoadChildren(uri, connection);
+            performLoadChildren(id, connection);
         }
     }
 
@@ -410,39 +401,39 @@
      * <p>
      * Callers must make sure that this connection is still connected.
      */
-    private void performLoadChildren(final Uri uri, final ConnectionRecord connection) {
+    private void performLoadChildren(final String parentId, final ConnectionRecord connection) {
         final Result<List<MediaBrowser.MediaItem>> result
- = new Result<List<MediaBrowser.MediaItem>>(
-                uri) {
+                = new Result<List<MediaBrowser.MediaItem>>(parentId) {
             @Override
             void onResultSent(List<MediaBrowser.MediaItem> list) {
                 if (list == null) {
-                    throw new IllegalStateException("onLoadChildren sent null list for uri " + uri);
+                    throw new IllegalStateException("onLoadChildren sent null list for id "
+                            + parentId);
                 }
                 if (mConnections.get(connection.callbacks.asBinder()) != connection) {
                     if (DBG) {
                         Log.d(TAG, "Not sending onLoadChildren result for connection that has"
-                                + " been disconnected. pkg=" + connection.pkg + " uri=" + uri);
+                                + " been disconnected. pkg=" + connection.pkg + " id=" + parentId);
                     }
                     return;
                 }
 
                 final ParceledListSlice<MediaBrowser.MediaItem> pls = new ParceledListSlice(list);
                 try {
-                    connection.callbacks.onLoadChildren(uri, pls);
+                    connection.callbacks.onLoadChildren(parentId, pls);
                 } catch (RemoteException ex) {
                     // The other side is in the process of crashing.
-                    Log.w(TAG, "Calling onLoadChildren() failed for uri=" + uri
+                    Log.w(TAG, "Calling onLoadChildren() failed for id=" + parentId
                             + " package=" + connection.pkg);
                 }
             }
         };
 
-        onLoadChildren(uri, result);
+        onLoadChildren(parentId, result);
 
         if (!result.isDone()) {
             throw new IllegalStateException("onLoadChildren must call detach() or sendResult()"
-                    + " before returning for package=" + connection.pkg + " uri=" + uri);
+                    + " before returning for package=" + connection.pkg + " id=" + parentId);
         }
     }
 
@@ -451,28 +442,28 @@
      * when first connected.
      */
     public static final class BrowserRoot {
-        final private Uri mUri;
+        final private String mRootId;
         final private Bundle mExtras;
 
         /**
          * Constructs a browser root.
-         * @param uri The root Uri for browsing.
+         * @param rootId The root id for browsing.
          * @param extras Any extras about the browser service.
          */
-        public BrowserRoot(@NonNull Uri uri, @Nullable Bundle extras) {
-            if (uri == null) {
-                throw new IllegalArgumentException("The root uri in BrowserRoot cannot be null. " +
+        public BrowserRoot(@NonNull String rootId, @Nullable Bundle extras) {
+            if (rootId == null) {
+                throw new IllegalArgumentException("The root id in BrowserRoot cannot be null. " +
                         "Use null for BrowserRoot instead.");
             }
-            mUri = uri;
+            mRootId = rootId;
             mExtras = extras;
         }
 
         /**
-         * Gets the root uri for browsing.
+         * Gets the root id for browsing.
          */
-        public Uri getRootUri() {
-            return mUri;
+        public String getRootId() {
+            return mRootId;
         }
 
         /**
diff --git a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area_empty.xml b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area_empty.xml
deleted file mode 100644
index 2f4adae..0000000
--- a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area_empty.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License")
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- This is a blank layout to simplify implementation on landscape on phones
-     it is referenced indirectly by keyguard_eca -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="0dip"
-    android:layout_height="0dip"
-    android:orientation="vertical"
-    android:gravity="center"
-    android:layout_gravity="center_horizontal"
-    android:layout_alignParentBottom="true">
-
-</LinearLayout>
diff --git a/packages/Keyguard/res/values-land/alias.xml b/packages/Keyguard/res/values-land/alias.xml
deleted file mode 100644
index 7aac5b4..0000000
--- a/packages/Keyguard/res/values-land/alias.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.xml
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources>
-    <!-- Alias used to reference one of two possible layouts in keyguard.  -->
-    <item type="layout" name="keyguard_eca">@layout/keyguard_emergency_carrier_area_empty</item>
-</resources>
diff --git a/packages/Keyguard/res/values-port/alias.xml b/packages/Keyguard/res/values-port/alias.xml
deleted file mode 100644
index c3ecbb9..0000000
--- a/packages/Keyguard/res/values-port/alias.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.xml
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources>
-    <!-- Alias used to reference one of two possible layouts in keyguard.  -->
-    <item type="layout" name="keyguard_eca">@layout/keyguard_emergency_carrier_area</item>
-</resources>
diff --git a/packages/Keyguard/res/values/alias.xml b/packages/Keyguard/res/values/alias.xml
index e6657a1..09e9591 100644
--- a/packages/Keyguard/res/values/alias.xml
+++ b/packages/Keyguard/res/values/alias.xml
@@ -49,4 +49,6 @@
     <!-- Alias used to reference framework activity duration.  -->
     <item type="integer" name="config_activityDefaultDur">@*android:integer/config_activityDefaultDur</item>
 
+    <!-- Alias used to reference one of two possible layouts in keyguard.  -->
+    <item type="layout" name="keyguard_eca">@layout/keyguard_emergency_carrier_area</item>
 </resources>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
index a0fab42..8898f9e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -128,16 +128,19 @@
                 getResources().getDimensionPixelSize(R.dimen.widget_label_font_size));
     }
 
-    protected void refresh() {
-        AlarmManager.AlarmClockInfo nextAlarm = mLockPatternUtils.getNextAlarm();
-        Patterns.update(mContext, nextAlarm != null);
-
+    public void refreshTime() {
         mDateView.setFormat24Hour(Patterns.dateView);
         mDateView.setFormat12Hour(Patterns.dateView);
 
         mClockView.setFormat12Hour(Patterns.clockView12);
         mClockView.setFormat24Hour(Patterns.clockView24);
+    }
 
+    private void refresh() {
+        AlarmManager.AlarmClockInfo nextAlarm = mLockPatternUtils.getNextAlarm();
+        Patterns.update(mContext, nextAlarm != null);
+
+        refreshTime();
         refreshAlarmStatus(nextAlarm);
     }
 
diff --git a/packages/PrintSpooler/Android.mk b/packages/PrintSpooler/Android.mk
index 3fbd4d8..4948a02 100644
--- a/packages/PrintSpooler/Android.mk
+++ b/packages/PrintSpooler/Android.mk
@@ -19,6 +19,7 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += src/com/android/printspooler/renderer/IPdfRenderer.aidl
 
 LOCAL_PACKAGE_NAME := PrintSpooler
 
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 540a2f3..9efda2f 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -53,6 +53,11 @@
             android:permission="android.permission.BIND_PRINT_SPOOLER_SERVICE">
         </service>
 
+        <service
+            android:name=".renderer.PdfRendererService"
+            android:isolatedProcess="true">
+        </service>
+
         <activity
             android:name=".ui.PrintActivity"
             android:configChanges="orientation|screenSize"
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
index c3ddad9..cd2ccbd 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
@@ -17,24 +17,31 @@
 package com.android.printspooler.model;
 
 import android.app.ActivityManager;
+import android.content.ComponentName;
 import android.content.Context;
-import android.content.res.Configuration;
+import android.content.Intent;
+import android.content.ServiceConnection;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.graphics.Color;
-import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
-import android.graphics.pdf.PdfRenderer;
 import android.os.AsyncTask;
+import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
-import android.print.PrintAttributes.MediaSize;
-import android.print.PrintAttributes.Margins;
+import android.os.RemoteException;
+import android.print.PrintAttributes;
 import android.print.PrintDocumentInfo;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.view.View;
+import com.android.internal.annotations.GuardedBy;
+import com.android.printspooler.renderer.IPdfRenderer;
+import com.android.printspooler.renderer.PdfRendererService;
 import dalvik.system.CloseGuard;
+import libcore.io.IoUtils;
 
+import java.io.FileDescriptor;
 import java.io.IOException;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
@@ -55,9 +62,6 @@
 
     private static final int BYTES_PER_MEGABYTE = 1048576;
 
-    private static final int MILS_PER_INCH = 1000;
-    private static final int POINTS_IN_INCH = 72;
-
     private final CloseGuard mCloseGuard = CloseGuard.get();
 
     private final ArrayMap<Integer, PageContentProvider> mPageContentProviders =
@@ -115,7 +119,6 @@
         if (DEBUG) {
             Log.i(LOG_TAG, "STATE_DESTROYED");
         }
-        throwIfNotClosed();
         doDestroy();
     }
 
@@ -351,15 +354,13 @@
     public static final class RenderSpec {
         final int bitmapWidth;
         final int bitmapHeight;
-        final MediaSize mediaSize;
-        final Margins minMargins;
+        final PrintAttributes printAttributes;
 
         public RenderSpec(int bitmapWidth, int bitmapHeight,
-                MediaSize mediaSize, Margins minMargins) {
+                PrintAttributes printAttributes) {
             this.bitmapWidth = bitmapWidth;
             this.bitmapHeight = bitmapHeight;
-            this.mediaSize = mediaSize;
-            this.minMargins = minMargins;
+            this.printAttributes = printAttributes;
         }
 
         @Override
@@ -380,18 +381,11 @@
             if (bitmapWidth != other.bitmapWidth) {
                 return false;
             }
-            if (mediaSize != null) {
-                if (!mediaSize.equals(other.mediaSize)) {
+            if (printAttributes != null) {
+                if (!printAttributes.equals(other.printAttributes)) {
                     return false;
                 }
-            } else if (other.mediaSize != null) {
-                return false;
-            }
-            if (minMargins != null) {
-                if (!minMargins.equals(other.minMargins)) {
-                    return false;
-                }
-            } else if (other.minMargins != null) {
+            } else if (other.printAttributes != null) {
                 return false;
             }
             return true;
@@ -407,8 +401,7 @@
         public int hashCode() {
             int result = bitmapWidth;
             result = 31 * result + bitmapHeight;
-            result = 31 * result + (mediaSize != null ? mediaSize.hashCode() : 0);
-            result = 31 * result + (minMargins != null ? minMargins.hashCode() : 0);
+            result = 31 * result + (printAttributes != null ? printAttributes.hashCode() : 0);
             return result;
         }
     }
@@ -440,13 +433,11 @@
         }
     }
 
-    private static int pointsFromMils(int mils) {
-        return (int) (((float) mils / MILS_PER_INCH) * POINTS_IN_INCH);
-    }
-
-    private static class AsyncRenderer {
+    private static final class AsyncRenderer implements ServiceConnection {
         private static final int MALFORMED_PDF_FILE_ERROR = -2;
 
+        private final Object mLock = new Object();
+
         private final Context mContext;
 
         private final PageContentLruCache mPageContentCache;
@@ -457,8 +448,8 @@
 
         private int mPageCount = PrintDocumentInfo.PAGE_COUNT_UNKNOWN;
 
-        // Accessed only by the executor thread.
-        private PdfRenderer mRenderer;
+        @GuardedBy("mLock")
+        private IPdfRenderer mRenderer;
 
         public AsyncRenderer(Context context, OnMalformedPdfFileListener malformedPdfFileListener) {
             mContext = context;
@@ -470,6 +461,21 @@
             mPageContentCache = new PageContentLruCache(cacheSizeInBytes);
         }
 
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            synchronized (mLock) {
+                mRenderer = IPdfRenderer.Stub.asInterface(service);
+                mLock.notifyAll();
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            synchronized (mLock) {
+                mRenderer = null;
+            }
+        }
+
         public void open(final ParcelFileDescriptor source, final Runnable callback) {
             // Opening a new document invalidates the cache as it has pages
             // from the last document. We keep the cache even when the document
@@ -479,13 +485,27 @@
 
             new AsyncTask<Void, Void, Integer>() {
                 @Override
+                protected void onPreExecute() {
+                    Intent intent = new Intent(mContext, PdfRendererService.class);
+                    mContext.bindService(intent, AsyncRenderer.this, Context.BIND_AUTO_CREATE);
+                }
+
+                @Override
                 protected Integer doInBackground(Void... params) {
-                    try {
-                        mRenderer = new PdfRenderer(source);
-                        return mRenderer.getPageCount();
-                    } catch (IOException ioe) {
-                        Log.e(LOG_TAG, "Cannot open PDF document");
-                        return MALFORMED_PDF_FILE_ERROR;
+                    synchronized (mLock) {
+                        while (mRenderer == null) {
+                            try {
+                                mLock.wait();
+                            } catch (InterruptedException ie) {
+                                /* ignore */
+                            }
+                        }
+                        try {
+                            return mRenderer.openDocument(source);
+                        } catch (RemoteException re) {
+                            Log.e(LOG_TAG, "Cannot open PDF document");
+                            return MALFORMED_PDF_FILE_ERROR;
+                        }
                     }
                 }
 
@@ -510,7 +530,13 @@
             new AsyncTask<Void, Void, Void>() {
                 @Override
                 protected Void doInBackground(Void... params) {
-                    mRenderer.close();
+                    synchronized (mLock) {
+                        try {
+                            mRenderer.closeDocument();
+                        } catch (RemoteException re) {
+                            /* ignore */
+                        }
+                    }
                     return null;
                 }
 
@@ -525,8 +551,19 @@
         }
 
         public void destroy() {
-            mPageContentCache.invalidate();
-            mPageContentCache.clear();
+            new AsyncTask<Void, Void, Void>() {
+                @Override
+                protected Void doInBackground(Void... params) {
+                    return null;
+                }
+
+                @Override
+                public void onPostExecute(Void result) {
+                    mContext.unbindService(AsyncRenderer.this);
+                    mPageContentCache.invalidate();
+                    mPageContentCache.clear();
+                }
+            }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
         }
 
         public void startPreload(int firstShownPage, int lastShownPage, RenderSpec renderSpec) {
@@ -752,62 +789,30 @@
                     return mRenderedPage;
                 }
 
-                PdfRenderer.Page page = mRenderer.openPage(mPageIndex);
-
-                if (isCancelled()) {
-                    page.close();
-                    return mRenderedPage;
-                }
-
                 Bitmap bitmap = mRenderedPage.content.getBitmap();
 
-                final int srcWidthPts = page.getWidth();
-                final int srcHeightPts = page.getHeight();
+                ParcelFileDescriptor[] pipe = null;
+                try {
+                    pipe = ParcelFileDescriptor.createPipe();
+                    ParcelFileDescriptor source = pipe[0];
+                    ParcelFileDescriptor destination = pipe[1];
 
-                final int dstWidthPts = pointsFromMils(mRenderSpec.mediaSize.getWidthMils());
-                final int dstHeightPts = pointsFromMils(mRenderSpec.mediaSize.getHeightMils());
+                    mRenderer.renderPage(mPageIndex, bitmap.getWidth(), bitmap.getHeight(),
+                            mRenderSpec.printAttributes, destination);
 
-                final boolean scaleContent = mRenderer.shouldScaleForPrinting();
-                final boolean contentLandscape = !mRenderSpec.mediaSize.isPortrait();
+                    // We passed the file descriptor to the other side which took
+                    // ownership, so close our copy for the write to complete.
+                    destination.close();
 
-                final float displayScale;
-                Matrix matrix = new Matrix();
-
-                if (scaleContent) {
-                    displayScale = Math.min((float) bitmap.getWidth() / srcWidthPts,
-                            (float) bitmap.getHeight() / srcHeightPts);
-                } else {
-                    if (contentLandscape) {
-                        displayScale = (float) bitmap.getHeight() / dstHeightPts;
-                    } else {
-                        displayScale = (float) bitmap.getWidth() / dstWidthPts;
-                    }
+                    BitmapFactory.Options options = new BitmapFactory.Options();
+                    options.inBitmap = bitmap;
+                    BitmapFactory.decodeFileDescriptor(source.getFileDescriptor(), null, options);
+                } catch (IOException|RemoteException e) {
+                    Log.e(LOG_TAG, "Error rendering page:" + mPageIndex, e);
+                } finally {
+                    IoUtils.closeQuietly(pipe[0]);
+                    IoUtils.closeQuietly(pipe[1]);
                 }
-                matrix.postScale(displayScale, displayScale);
-
-                Configuration configuration = mContext.getResources().getConfiguration();
-                if (configuration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
-                    matrix.postTranslate(bitmap.getWidth() - srcWidthPts * displayScale, 0);
-                }
-
-                final int paddingLeftPts = pointsFromMils(mRenderSpec.minMargins.getLeftMils());
-                final int paddingTopPts = pointsFromMils(mRenderSpec.minMargins.getTopMils());
-                final int paddingRightPts = pointsFromMils(mRenderSpec.minMargins.getRightMils());
-                final int paddingBottomPts = pointsFromMils(mRenderSpec.minMargins.getBottomMils());
-
-                Rect clip = new Rect();
-                clip.left = (int) (paddingLeftPts * displayScale);
-                clip.top = (int) (paddingTopPts * displayScale);
-                clip.right = (int) (bitmap.getWidth() - paddingRightPts * displayScale);
-                clip.bottom = (int) (bitmap.getHeight() - paddingBottomPts * displayScale);
-
-                if (DEBUG) {
-                    Log.i(LOG_TAG, "Rendering page:" + mPageIndex + " of " + mPageCount);
-                }
-
-                page.render(bitmap, clip, matrix, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
-
-                page.close();
 
                 return mRenderedPage;
             }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfRenderer.aidl b/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfRenderer.aidl
new file mode 100644
index 0000000..1fba2b1
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfRenderer.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.renderer;
+
+import android.graphics.Rect;
+import android.os.ParcelFileDescriptor;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+
+/**
+ * Interface for communication with a remote pdf renderer.
+ */
+interface IPdfRenderer {
+    int openDocument(in ParcelFileDescriptor source);
+    oneway void renderPage(int pageIndex, int bitmapWidth, int bitmapHeight,
+        in PrintAttributes attributes, in ParcelFileDescriptor destination);
+    oneway void closeDocument();
+    oneway void writePages(in PageRange[] pages);
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfRendererService.java b/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfRendererService.java
new file mode 100644
index 0000000..a4c6932
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfRendererService.java
@@ -0,0 +1,198 @@
+/*
+ * 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.renderer;
+
+import android.app.Service;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.pdf.PdfRenderer;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.Margins;
+import android.util.Log;
+import android.view.View;
+import libcore.io.IoUtils;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Service for rendering PDF documents in an isolated process.
+ */
+public final class PdfRendererService extends Service {
+    private static final String LOG_TAG = "PdfRendererService";
+    private static final boolean DEBUG = false;
+
+    private static final int MILS_PER_INCH = 1000;
+    private static final int POINTS_IN_INCH = 72;
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return new PdfRendererImpl();
+    }
+
+    private final class PdfRendererImpl extends IPdfRenderer.Stub {
+        private final Object mLock = new Object();
+
+        private Bitmap mBitmap;
+        private PdfRenderer mRenderer;
+
+        @Override
+        public int openDocument(ParcelFileDescriptor source) throws RemoteException {
+            synchronized (mLock) {
+                throwIfOpened();
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "openDocument()");
+                }
+                try {
+                    mRenderer = new PdfRenderer(source);
+                    return mRenderer.getPageCount();
+                } catch (IOException ioe) {
+                    throw new RemoteException("Cannot open file");
+                }
+            }
+        }
+
+        @Override
+        public void renderPage(int pageIndex, int bitmapWidth, int bitmapHeight,
+                PrintAttributes attributes, ParcelFileDescriptor destination) {
+            FileOutputStream out = null;
+            synchronized (mLock) {
+                try {
+                    throwIfNotOpened();
+
+                    PdfRenderer.Page page = mRenderer.openPage(pageIndex);
+
+                    final int srcWidthPts = page.getWidth();
+                    final int srcHeightPts = page.getHeight();
+
+                    final int dstWidthPts = pointsFromMils(
+                            attributes.getMediaSize().getWidthMils());
+                    final int dstHeightPts = pointsFromMils(
+                            attributes.getMediaSize().getHeightMils());
+
+                    final boolean scaleContent = mRenderer.shouldScaleForPrinting();
+                    final boolean contentLandscape = !attributes.getMediaSize().isPortrait();
+
+                    final float displayScale;
+                    Matrix matrix = new Matrix();
+
+                    if (scaleContent) {
+                        displayScale = Math.min((float) bitmapWidth / srcWidthPts,
+                                (float) bitmapHeight / srcHeightPts);
+                    } else {
+                        if (contentLandscape) {
+                            displayScale = (float) bitmapHeight / dstHeightPts;
+                        } else {
+                            displayScale = (float) bitmapWidth / dstWidthPts;
+                        }
+                    }
+                    matrix.postScale(displayScale, displayScale);
+
+                    Configuration configuration = PdfRendererService.this.getResources()
+                            .getConfiguration();
+                    if (configuration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
+                        matrix.postTranslate(bitmapWidth - srcWidthPts * displayScale, 0);
+                    }
+
+                    Margins minMargins = attributes.getMinMargins();
+                    final int paddingLeftPts = pointsFromMils(minMargins.getLeftMils());
+                    final int paddingTopPts = pointsFromMils(minMargins.getTopMils());
+                    final int paddingRightPts = pointsFromMils(minMargins.getRightMils());
+                    final int paddingBottomPts = pointsFromMils(minMargins.getBottomMils());
+
+                    Rect clip = new Rect();
+                    clip.left = (int) (paddingLeftPts * displayScale);
+                    clip.top = (int) (paddingTopPts * displayScale);
+                    clip.right = (int) (bitmapWidth - paddingRightPts * displayScale);
+                    clip.bottom = (int) (bitmapHeight - paddingBottomPts * displayScale);
+
+                    if (DEBUG) {
+                        Log.i(LOG_TAG, "Rendering page:" + pageIndex);
+                    }
+
+                    Bitmap bitmap = getBitmapForSize(bitmapWidth, bitmapHeight);
+                    page.render(bitmap, clip, matrix, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
+
+                    page.close();
+
+                    out = new FileOutputStream(destination.getFileDescriptor());
+                    bitmap.compress(Bitmap.CompressFormat.PNG, 0, out);
+                } finally {
+                    IoUtils.closeQuietly(out);
+                    IoUtils.closeQuietly(destination);
+                }
+            }
+        }
+
+        @Override
+        public void closeDocument() {
+            synchronized (mLock) {
+                throwIfNotOpened();
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "openDocument()");
+                }
+                mRenderer.close();
+                mRenderer = null;
+            }
+        }
+
+        @Override
+        public void writePages(PageRange[] pages) {
+            synchronized (mLock) {
+                throwIfNotOpened();
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "writePages()");
+                }
+                // TODO: Implement dropping undesired pages.
+            }
+        }
+
+        private Bitmap getBitmapForSize(int width, int height) {
+            if (mBitmap != null) {
+                if (mBitmap.getWidth() == width && mBitmap.getHeight() == height) {
+                    return mBitmap;
+                }
+                mBitmap.recycle();
+            }
+            mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+            return mBitmap;
+        }
+
+        private void throwIfOpened() {
+            if (mRenderer != null) {
+                throw new IllegalStateException("Already opened");
+            }
+        }
+
+        private void throwIfNotOpened() {
+            if (mRenderer == null) {
+                throw new IllegalStateException("Not opened");
+            }
+        }
+    }
+
+    private static int pointsFromMils(int mils) {
+        return (int) (((float) mils / MILS_PER_INCH) * POINTS_IN_INCH);
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 01c9746..022e0d0 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -319,6 +319,7 @@
 
             mProgressMessageController.cancel();
             mPrinterRegistry.setTrackedPrinter(null);
+            mPrintPreviewController.destroy();
             mSpoolerProvider.destroy();
             mPrintedDocument.finish();
             mPrintedDocument.destroy();
@@ -2185,4 +2186,4 @@
             updateOptionsUi();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java
index 4a23ec4..ddf637e 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java
@@ -191,6 +191,9 @@
     }
 
     public void destroy() {
+        if (mPageAdapter.isOpened()) {
+            mPageAdapter.close(null);
+        }
         mPageAdapter.destroy();
     }
 
diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java b/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java
index 8365373..76ff167 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java
@@ -20,6 +20,7 @@
 import android.graphics.Canvas;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.ColorDrawable;
+import android.print.PrintAttributes;
 import android.print.PrintAttributes.MediaSize;
 import android.print.PrintAttributes.Margins;
 import android.util.AttributeSet;
@@ -38,13 +39,12 @@
 public class PageContentView extends View
         implements PageContentRepository.OnPageContentAvailableCallback {
 
+    private final PrintAttributes mAttributes = new PrintAttributes.Builder().build();
+
     private final ColorDrawable mEmptyState;
 
     private PageContentProvider mProvider;
 
-    private MediaSize mMediaSize;
-    private Margins mMinMargins;
-
     private boolean mContentRequested;
 
     public PageContentView(Context context, AttributeSet attrs) {
@@ -83,15 +83,17 @@
     }
 
     public void init(PageContentProvider provider, MediaSize mediaSize, Margins minMargins) {
-        if (mProvider == provider
-                && ((mMediaSize == null) ? mediaSize == null : mMediaSize.equals(mediaSize))
-                && ((mMinMargins == null) ? minMargins == null : mMinMargins.equals(minMargins))) {
+        if (mProvider == null ? provider == null : mProvider.equals(provider)
+                && ((mAttributes.getMediaSize() == null)
+                        ? mediaSize == null : mAttributes.getMediaSize().equals(mediaSize))
+                && ((mAttributes.getMinMargins() == null)
+                        ? minMargins == null : mAttributes.getMinMargins().equals(minMargins))) {
             return;
         }
 
         mProvider = provider;
-        mMediaSize = mediaSize;
-        mMinMargins = minMargins;
+        mAttributes.setMediaSize(mediaSize);
+        mAttributes.setMinMargins(minMargins);
         mContentRequested = false;
 
         // If there is no provider we want immediately to switch to
@@ -106,8 +108,7 @@
     private void requestPageContentIfNeeded() {
         if (getWidth() > 0 && getHeight() > 0 && !mContentRequested && mProvider != null) {
             mContentRequested = true;
-            mProvider.getPageContent(new RenderSpec(getWidth(), getHeight(), mMediaSize,
-                    mMinMargins), this);
+            mProvider.getPageContent(new RenderSpec(getWidth(), getHeight(), mAttributes), this);
         }
     }
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index fd5e6fe..17593fe 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -70,7 +70,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 109;
+    private static final int DATABASE_VERSION = 110;
 
     private Context mContext;
     private int mUserHandle;
@@ -1749,6 +1749,27 @@
             upgradeVersion = 109;
         }
 
+        if (upgradeVersion < 110) {
+            // The SIP_CALL_OPTIONS value SIP_ASK_EACH_TIME is being deprecated.
+            // If the SIP_CALL_OPTIONS setting is set to SIP_ASK_EACH_TIME, default to
+            // SIP_ADDRESS_ONLY.
+            db.beginTransaction();
+            SQLiteStatement stmt = null;
+            try {
+                stmt = db.compileStatement("UPDATE system SET value = ? " +
+                        "WHERE name = ? AND value = ?;");
+                stmt.bindString(1, Settings.System.SIP_ADDRESS_ONLY);
+                stmt.bindString(2, Settings.System.SIP_CALL_OPTIONS);
+                stmt.bindString(3, Settings.System.SIP_ASK_ME_EACH_TIME);
+                stmt.execute();
+                db.setTransactionSuccessful();
+            } finally {
+                db.endTransaction();
+                if (stmt != null) stmt.close();
+            }
+            upgradeVersion = 110;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
diff --git a/packages/SystemUI/res/drawable/notification_material_bg_dim.xml b/packages/SystemUI/res/drawable/notification_material_bg_dim.xml
index b04394d..6581942 100644
--- a/packages/SystemUI/res/drawable/notification_material_bg_dim.xml
+++ b/packages/SystemUI/res/drawable/notification_material_bg_dim.xml
@@ -14,7 +14,11 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <solid android:color="@color/notification_material_background_dimmed_color" />
-    <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
-</shape>
+<ripple xmlns:android="http://schemas.android.com/apk/res/android">
+    <item>
+        <shape>
+            <solid android:color="@color/notification_material_background_dimmed_color" />
+            <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
+        </shape>
+    </item>
+</ripple>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index f9e7852..7ad3a89 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -64,7 +64,10 @@
         <FrameLayout android:id="@+id/system_icons_container"
             android:layout_width="wrap_content"
             android:layout_height="@dimen/status_bar_height"
-            android:layout_gravity="center_vertical" />
+            android:layout_gravity="center_vertical"
+            >
+            <include layout="@layout/system_icons" />
+        </FrameLayout>
         <TextView android:id="@+id/battery_level"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index f3a62b8..6da811f 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -90,7 +90,10 @@
     <color name="notification_material_background_media_default_color">#ff424242</color>
 
     <!-- The color of the ripples on the untinted notifications -->
-    <color name="notification_ripple_untinted_color">#20000000</color>
+    <color name="notification_ripple_untinted_color">#28000000</color>
+
+    <!-- The color of the ripples on the low priority notifications -->
+    <color name="notification_ripple_color_low_priority">#30000000</color>
 
     <!-- The color of the ripples on the tinted notifications -->
     <color name="notification_ripple_tinted_color">#30ffffff</color>
diff --git a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
index 7f5ed6a..714b0a8 100644
--- a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
@@ -112,17 +112,23 @@
             return;
         }
 
-        userManager.removeUser(currentUser.id);
+        boolean marked = userManager.markGuestForDeletion(currentUser.id);
+        if (!marked) {
+            Log.w(TAG, "Couldn't mark the guest for deletion for user " + userId);
+            return;
+        }
         UserInfo newGuest = userManager.createGuest(context, currentUser.name);
 
         try {
             if (newGuest == null) {
                 Log.e(TAG, "Could not create new guest, switching back to owner");
                 ActivityManagerNative.getDefault().switchUser(UserHandle.USER_OWNER);
+                userManager.removeUser(currentUser.id);
                 WindowManagerGlobal.getWindowManagerService().lockNow(null /* options */);
                 return;
             }
             ActivityManagerNative.getDefault().switchUser(newGuest.id);
+            userManager.removeUser(currentUser.id);
         } catch (RemoteException e) {
             Log.e(TAG, "Couldn't wipe session because ActivityManager or WindowManager is dead");
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 500bf45..e6984b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -88,6 +88,9 @@
             = new PathInterpolator(0.6f, 0, 0.5f, 1);
     private static final Interpolator ACTIVATE_INVERSE_ALPHA_INTERPOLATOR
             = new PathInterpolator(0, 0, 0.5f, 1);
+    private final int mTintedRippleColor;
+    private final int mLowPriorityRippleColor;
+    private final int mNormalRippleColor;
 
     private boolean mDimmed;
     private boolean mDark;
@@ -153,6 +156,12 @@
         mNormalColor = getResources().getColor(R.color.notification_material_background_color);
         mLowPriorityColor = getResources().getColor(
                 R.color.notification_material_background_low_priority_color);
+        mTintedRippleColor = context.getResources().getColor(
+                R.color.notification_ripple_tinted_color);
+        mLowPriorityRippleColor = context.getResources().getColor(
+                R.color.notification_ripple_color_low_priority);
+        mNormalRippleColor = context.getResources().getColor(
+                R.color.notification_ripple_untinted_color);
     }
 
     @Override
@@ -191,6 +200,16 @@
         }
     }
 
+    @Override
+    protected void drawableStateChanged() {
+        super.drawableStateChanged();
+        if (mDimmed) {
+            mBackgroundDimmed.setState(getDrawableState());
+        } else {
+            mBackgroundNormal.setState(getDrawableState());
+        }
+    }
+
     private boolean handleTouchEventDimmed(MotionEvent event) {
         int action = event.getActionMasked();
         switch (action) {
@@ -372,12 +391,15 @@
 
     private void updateBackgroundTint() {
         int color = getBackgroundColor();
+        int rippleColor = getRippleColor();
         if (color == mNormalColor) {
             // We don't need to tint a normal notification
             color = 0;
         }
         mBackgroundDimmed.setTint(color);
         mBackgroundNormal.setTint(color);
+        mBackgroundDimmed.setRippleColor(rippleColor);
+        mBackgroundNormal.setRippleColor(rippleColor);
     }
 
     private void fadeBackground() {
@@ -618,6 +640,18 @@
         }
     }
 
+    private int getRippleColor() {
+        if (mBgTint != 0) {
+            return mTintedRippleColor;
+        } else if (mShowingLegacyBackground) {
+            return mTintedRippleColor;
+        } else if (mIsBelowSpeedBump) {
+            return mLowPriorityRippleColor;
+        } else {
+            return mNormalRippleColor;
+        }
+    }
+
     /**
      * When we draw the appear animation, we render the view in a bitmap and render this bitmap
      * as a shader of a rect. This call creates the Bitmap and switches the drawing mode,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 3f631f7..ce29407 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -365,6 +365,24 @@
                     Notification n = sbn.getNotification();
                     boolean isUpdate = mNotificationData.get(sbn.getKey()) != null
                             || isHeadsUp(sbn.getKey());
+
+                    // Ignore children of notifications that have a summary, since we're not
+                    // going to show them anyway. This is true also when the summary is canceled,
+                    // because children are automatically canceled by NoMan in that case.
+                    if (n.isGroupChild() &&
+                            mNotificationData.isGroupWithSummary(sbn.getGroupKey())) {
+                        if (DEBUG) {
+                            Log.d(TAG, "Ignoring group child due to existing summary: " + sbn);
+                        }
+
+                        // Remove existing notification to avoid stale data.
+                        if (isUpdate) {
+                            removeNotification(sbn.getKey(), rankingMap);
+                        } else {
+                            mNotificationData.updateRanking(rankingMap);
+                        }
+                        return;
+                    }
                     if (isUpdate) {
                         updateNotification(sbn, rankingMap);
                     } else {
@@ -736,15 +754,20 @@
             public boolean onLongPress(View v, int x, int y) {
                 dismissPopups();
 
-                if (v.getWindowToken() == null) return false;
+                if (v.getWindowToken() == null) {
+                    Log.e(TAG, "Trying to show notification guts, but not attached to window");
+                    return false;
+                }
 
                 // Assume we are a status_bar_notification_row
                 final NotificationGuts guts = (NotificationGuts) v.findViewById(
                         R.id.notification_guts);
-                if (guts == null) return false;
 
                 // Already showing?
-                if (guts.getVisibility() == View.VISIBLE) return false;
+                if (guts.getVisibility() == View.VISIBLE) {
+                    Log.e(TAG, "Trying to show notification guts, but already visible");
+                    return false;
+                }
 
                 guts.setVisibility(View.VISIBLE);
                 final double horz = Math.max(guts.getWidth() - x, x);
@@ -768,6 +791,8 @@
             final NotificationGuts v = mNotificationGutsExposed;
             mNotificationGutsExposed = null;
 
+            if (v.getWindowToken() == null) return;
+
             final int x = (v.getLeft() + v.getRight()) / 2;
             final int y = (v.getTop() + v.getActualHeight() / 2);
             final Animator a = ViewAnimationUtils.createCircularReveal(v,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/MirrorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/MirrorView.java
deleted file mode 100644
index 8b0df06..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/MirrorView.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.view.View;
-
-/**
- * A view that mirrors the visual contents of another one. Should be used for animation purposes
- * only, as this view doesn't have any input handling.
- */
-public class MirrorView extends View {
-
-    private View mView;
-    private int mFixedWidth;
-    private int mFixedHeight;
-
-    public MirrorView(Context context) {
-        super(context);
-    }
-
-    public void setMirroredView(View v, int width, int height) {
-        mView = v;
-        mFixedWidth = width;
-        mFixedHeight = height;
-        requestLayout();
-        invalidate();
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        if (mView != null) {
-            setMeasuredDimension(mFixedWidth, mFixedHeight);
-        } else {
-            setMeasuredDimension(0, 0);
-        }
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        if (mView != null) {
-            mView.draw(canvas);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
index ad274b0..5db680a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
@@ -35,15 +35,9 @@
     private Drawable mBackground;
     private int mClipTopAmount;
     private int mActualHeight;
-    private final int mTintedRippleColor;
-    private final int mNormalRippleColor;
 
     public NotificationBackgroundView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mTintedRippleColor = context.getResources().getColor(
-                R.color.notification_ripple_tinted_color);
-        mNormalRippleColor = context.getResources().getColor(
-                R.color.notification_ripple_untinted_color);
     }
 
     @Override
@@ -103,17 +97,10 @@
     }
 
     public void setTint(int tintColor) {
-        int rippleColor;
         if (tintColor != 0) {
             mBackground.setColorFilter(tintColor, PorterDuff.Mode.SRC_ATOP);
-            rippleColor = mTintedRippleColor;
         } else {
             mBackground.clearColorFilter();
-            rippleColor = mNormalRippleColor;
-        }
-        if (mBackground instanceof RippleDrawable) {
-            RippleDrawable ripple = (RippleDrawable) mBackground;
-            ripple.setColor(ColorStateList.valueOf(rippleColor));
         }
         invalidate();
     }
@@ -138,4 +125,15 @@
         // Prevents this view from creating a layer when alpha is animating.
         return false;
     }
+
+    public void setState(int[] drawableState) {
+        mBackground.setState(drawableState);
+    }
+
+    public void setRippleColor(int color) {
+        if (mBackground instanceof RippleDrawable) {
+            RippleDrawable ripple = (RippleDrawable) mBackground;
+            ripple.setColor(ColorStateList.valueOf(color));
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 7e37336..454041c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -89,6 +89,7 @@
 
     private final ArrayMap<String, Entry> mEntries = new ArrayMap<>();
     private final ArrayList<Entry> mSortedAndFiltered = new ArrayList<>();
+    private ArraySet<String> mGroupsWithSummaries = new ArraySet<>();
 
     private RankingMap mRankingMap;
     private final Ranking mTmpRanking = new Ranking();
@@ -183,8 +184,8 @@
     // anything changed, and this class should call back the UI so it updates itself.
     public void filterAndSort() {
         mSortedAndFiltered.clear();
+        mGroupsWithSummaries.clear();
 
-        ArraySet<String> groupsWithSummaries = null;
         final int N = mEntries.size();
         for (int i = 0; i < N; i++) {
             Entry entry = mEntries.valueAt(i);
@@ -195,22 +196,19 @@
             }
 
             if (sbn.getNotification().isGroupSummary()) {
-                if (groupsWithSummaries == null) {
-                    groupsWithSummaries = new ArraySet<>();
-                }
-                groupsWithSummaries.add(sbn.getGroupKey());
+                mGroupsWithSummaries.add(sbn.getGroupKey());
             }
             mSortedAndFiltered.add(entry);
         }
 
         // Second pass: Filter out group children with summary.
-        if (groupsWithSummaries != null) {
+        if (!mGroupsWithSummaries.isEmpty()) {
             final int M = mSortedAndFiltered.size();
             for (int i = M - 1; i >= 0; i--) {
                 Entry ent = mSortedAndFiltered.get(i);
                 StatusBarNotification sbn = ent.notification;
                 if (sbn.getNotification().isGroupChild() &&
-                        groupsWithSummaries.contains(sbn.getGroupKey())) {
+                        mGroupsWithSummaries.contains(sbn.getGroupKey())) {
                     mSortedAndFiltered.remove(i);
                 }
             }
@@ -219,6 +217,10 @@
         Collections.sort(mSortedAndFiltered, mRankingComparator);
     }
 
+    public boolean isGroupWithSummary(String groupKey) {
+        return mGroupsWithSummaries.contains(groupKey);
+    }
+
     private boolean shouldFilterOut(StatusBarNotification sbn) {
         if (!(mEnvironment.isDeviceProvisioned() ||
                 showNotificationEvenIfUnprovisioned(sbn))) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 3bb403d..0fb2192 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -87,7 +87,7 @@
     private final NavTransitionListener mTransitionListener = new NavTransitionListener();
 
     private OnVerticalChangedListener mOnVerticalChangedListener;
-    private boolean mIsLtr;
+    private boolean mIsLayoutRtl;
 
     private class NavTransitionListener implements TransitionListener {
         private boolean mBackTransitioning;
@@ -394,7 +394,7 @@
 
         getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
 
-        updateLTROrder();
+        updateRTLOrder();
     }
 
     public boolean isVertical() {
@@ -460,17 +460,17 @@
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
-        updateLTROrder();
+        updateRTLOrder();
     }
 
     /**
      * In landscape, the LinearLayout is not auto mirrored since it is vertical. Therefore we
      * have to do it manually
      */
-    private void updateLTROrder() {
-        boolean isLtr = getResources().getConfiguration()
+    private void updateRTLOrder() {
+        boolean isLayoutRtl = getResources().getConfiguration()
                 .getLayoutDirection() == LAYOUT_DIRECTION_RTL;
-        if (mIsLtr != isLtr) {
+        if (mIsLayoutRtl != isLayoutRtl) {
 
             // We swap all children of the 90 and 270 degree layouts, since they are vertical
             View rotation90 = mRotatedViews[Surface.ROTATION_90];
@@ -480,7 +480,7 @@
             if (rotation90 != rotation270) {
                 swapChildrenOrderIfVertical(rotation270.findViewById(R.id.nav_buttons));
             }
-            mIsLtr = isLtr;
+            mIsLayoutRtl = isLayoutRtl;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index d3c3f56..91a8b22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -28,21 +28,20 @@
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
-import android.widget.LinearLayout;
 import android.widget.TextView;
+
+import com.android.keyguard.KeyguardStatusView;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.statusbar.ExpandableView;
 import com.android.systemui.statusbar.FlingAnimationUtils;
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
-import com.android.systemui.statusbar.MirrorView;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
@@ -67,11 +66,10 @@
     private KeyguardStatusBarView mKeyguardStatusBar;
     private View mQsContainer;
     private QSPanel mQsPanel;
-    private View mKeyguardStatusView;
+    private KeyguardStatusView mKeyguardStatusView;
     private ObservableScrollView mScrollView;
     private TextView mClockView;
     private View mReserveNotificationSpace;
-    private MirrorView mSystemIconsCopy;
     private View mQsNavbarScrim;
     private View mNotificationContainerParent;
     private NotificationStackScrollLayout mNotificationStackScroller;
@@ -165,7 +163,6 @@
 
     public NotificationPanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mSystemIconsCopy = new MirrorView(context);
     }
 
     public void setStatusBar(PhoneStatusBar bar) {
@@ -178,7 +175,7 @@
         mHeader = (StatusBarHeaderView) findViewById(R.id.header);
         mHeader.setOnClickListener(this);
         mKeyguardStatusBar = (KeyguardStatusBarView) findViewById(R.id.keyguard_header);
-        mKeyguardStatusView = findViewById(R.id.keyguard_status_view);
+        mKeyguardStatusView = (KeyguardStatusView) findViewById(R.id.keyguard_status_view);
         mQsContainer = findViewById(R.id.quick_settings_container);
         mQsPanel = (QSPanel) findViewById(R.id.quick_settings_panel);
         mClockView = (TextView) findViewById(R.id.clock_view);
@@ -1168,43 +1165,6 @@
     }
 
     @Override
-    public void setVisibility(int visibility) {
-        int oldVisibility = getVisibility();
-        super.setVisibility(visibility);
-        if (visibility != oldVisibility) {
-            reparentStatusIcons(visibility == VISIBLE);
-        }
-    }
-
-    /**
-     * When the notification panel gets expanded, we need to move the status icons in the header
-     * card.
-     */
-    private void reparentStatusIcons(boolean toHeader) {
-        if (mStatusBar == null) {
-            return;
-        }
-        LinearLayout systemIcons = mStatusBar.getSystemIcons();
-        ViewGroup parent = ((ViewGroup) systemIcons.getParent());
-        if (toHeader) {
-            int index = parent.indexOfChild(systemIcons);
-            parent.removeView(systemIcons);
-            mSystemIconsCopy.setMirroredView(
-                    systemIcons, systemIcons.getWidth(), systemIcons.getHeight());
-            parent.addView(mSystemIconsCopy, index);
-            mHeader.attachSystemIcons(systemIcons);
-        } else {
-            ViewGroup newParent = mStatusBar.getSystemIconArea();
-            int index = newParent.indexOfChild(mSystemIconsCopy);
-            parent.removeView(systemIcons);
-            mHeader.onSystemIconsDetached();
-            mSystemIconsCopy.setMirroredView(null, 0, 0);
-            newParent.removeView(mSystemIconsCopy);
-            newParent.addView(systemIcons, index);
-        }
-    }
-
-    @Override
     protected boolean isScrolledToBottom() {
         if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
             return true;
@@ -1790,4 +1750,8 @@
             mHeader.updateEverything();
         }
     };
+
+    public void onScreenTurnedOn() {
+        mKeyguardStatusView.refreshTime();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
index 53361dc..b842a6b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
@@ -87,7 +87,9 @@
 
     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
-        if (!mTouchEnabled) {
+        boolean isEndGuesture = (ev.getAction() == MotionEvent.ACTION_UP
+                || ev.getAction() == MotionEvent.ACTION_CANCEL);
+        if (!mTouchEnabled && !isEndGuesture) {
             return false;
         }
         return super.dispatchTouchEvent(ev);
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 e818d23..6127811 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -720,6 +720,8 @@
         abortAnimations();
         if (mTracking) {
             onTrackingStopped(true /* expands */); // The panel is expanded after this call.
+        }
+        if (mExpanding) {
             notifyExpandingFinished();
         }
         setVisibility(VISIBLE);
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 8c7dad9..ad775cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -779,10 +779,14 @@
                 (SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
         final SignalClusterView signalClusterKeyguard =
                 (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
+        final SignalClusterView signalClusterQs =
+                (SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
         mNetworkController.addSignalCluster(signalCluster);
         mNetworkController.addSignalCluster(signalClusterKeyguard);
+        mNetworkController.addSignalCluster(signalClusterQs);
         signalCluster.setNetworkController(mNetworkController);
         signalClusterKeyguard.setNetworkController(mNetworkController);
+        signalClusterQs.setNetworkController(mNetworkController);
         final boolean isAPhone = mNetworkController.hasVoiceCallingFeature();
         if (isAPhone) {
             mNetworkController.addEmergencyLabelView(mHeader);
@@ -3813,6 +3817,7 @@
 
     public void onScreenTurnedOn() {
         mStackScroller.setAnimationsEnabled(true);
+        mNotificationPanel.onScreenTurnedOn();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index b6792f5..eeb97e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -39,6 +39,7 @@
 import android.widget.TextView;
 
 import com.android.keyguard.KeyguardStatusView;
+import com.android.systemui.BatteryMeterView;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSPanel;
@@ -67,7 +68,6 @@
     private TextView mDateCollapsed;
     private TextView mDateExpanded;
     private LinearLayout mSystemIcons;
-    private View mStatusIcons;
     private View mSignalCluster;
     private View mSettingsButton;
     private View mQsDetailHeader;
@@ -149,6 +149,8 @@
         mBatteryLevel = (TextView) findViewById(R.id.battery_level);
         mAlarmStatus = (TextView) findViewById(R.id.alarm_status);
         mAlarmStatus.setOnClickListener(this);
+        mSignalCluster = findViewById(R.id.signal_cluster);
+        mSystemIcons = (LinearLayout) findViewById(R.id.system_icons);
         loadDimens();
         updateVisibilities();
         updateClockScale();
@@ -259,6 +261,7 @@
 
     public void setBatteryController(BatteryController batteryController) {
         mBatteryController = batteryController;
+        ((BatteryMeterView) findViewById(R.id.battery)).setBatteryController(batteryController);
     }
 
     public void setNextAlarmController(NextAlarmController nextAlarmController) {
@@ -476,36 +479,6 @@
         invalidateOutline();
     }
 
-    public void attachSystemIcons(LinearLayout systemIcons) {
-        mSystemIconsContainer.addView(systemIcons);
-        mStatusIcons = systemIcons.findViewById(R.id.statusIcons);
-        mSignalCluster = systemIcons.findViewById(R.id.signal_cluster);
-        mSystemIcons = systemIcons;
-        updateVisibilities();
-        if (mStatusIcons != null) {
-            mStatusIcons.setVisibility(View.GONE);
-        }
-    }
-
-    public void onSystemIconsDetached() {
-        if (mSignalClusterDetached) {
-            reattachSignalCluster();
-            mSignalClusterDetached = false;
-        }
-        if (mStatusIcons != null) {
-            mStatusIcons.setVisibility(View.VISIBLE);
-        }
-        if (mSignalCluster != null) {
-            mSignalCluster.setVisibility(View.VISIBLE);
-            mSignalCluster.setAlpha(1f);
-            mSignalCluster.setTranslationX(0f);
-            mSignalCluster.setTranslationY(0f);
-        }
-        mStatusIcons = null;
-        mSignalCluster = null;
-        mSystemIcons = null;
-    }
-
     public void setUserInfoController(UserInfoController userInfoController) {
         userInfoController.addListener(new UserInfoController.OnUserInfoChangedListener() {
             @Override
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 e1fd779..1811d8d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -42,6 +42,7 @@
     private DragDownHelper mDragDownHelper;
     private NotificationStackScrollLayout mStackScrollLayout;
     private NotificationPanelView mNotificationPanel;
+    private View mBrightnessMirror;
 
     PhoneStatusBar mService;
 
@@ -72,6 +73,7 @@
                 R.id.notification_stack_scroller);
         mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);
         mDragDownHelper = new DragDownHelper(getContext(), this, mStackScrollLayout, mService);
+        mBrightnessMirror = findViewById(R.id.brightness_mirror);
 
         // We really need to be able to animate while window animations are going on
         // so that activities may be started asynchronously from panel animations
@@ -106,6 +108,19 @@
     }
 
     @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        if (mBrightnessMirror != null && mBrightnessMirror.getVisibility() == VISIBLE) {
+            // Disallow new pointers while the brightness mirror is visible. This is so that you
+            // can't touch anything other than the brightness slider while the mirror is showing
+            // and the rest of the panel is transparent.
+            if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
+                return false;
+            }
+        }
+        return super.dispatchTouchEvent(ev);
+    }
+
+    @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         boolean intercept = false;
         if (mNotificationPanel.isFullyExpanded()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 82e7f5d..148b00c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -580,7 +580,7 @@
             }
             float childTop = slidingChild.getTranslationY();
             float top = childTop + slidingChild.getClipTopAmount();
-            float bottom = top + slidingChild.getActualHeight();
+            float bottom = childTop + slidingChild.getActualHeight();
 
             // Allow the full width of this view to prevent gesture conflict on Keyguard (phone and
             // camera affordance).
@@ -1530,7 +1530,7 @@
                 return position;
             }
             if (child.getVisibility() != View.GONE) {
-                position += child.getHeight();
+                position += getIntrinsicHeight(child);
                 if (i < getChildCount()-1) {
                     position += mPaddingBetweenElements;
                 }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 4e2f52c..5d13fed 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -42,6 +42,7 @@
 import android.database.ContentObserver;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.hardware.display.DisplayManager;
 import android.hardware.input.InputManager;
 import android.net.Uri;
@@ -162,6 +163,8 @@
     private final List<AccessibilityServiceInfo> mEnabledServicesForFeedbackTempList =
             new ArrayList<>();
 
+    private final Region mTempRegion = new Region();
+
     private final Rect mTempRect = new Rect();
 
     private final Point mTempPoint = new Point();
@@ -2161,6 +2164,7 @@
                 throws RemoteException {
             final int resolvedWindowId;
             IAccessibilityInteractionConnection connection = null;
+            Region partialInteractiveRegion = mTempRegion;
             synchronized (mLock) {
                 // We treat calls from a profile as if made by its parent as profiles
                 // share the accessibility state of the parent. The call below
@@ -2182,13 +2186,17 @@
                         return false;
                     }
                 }
+                if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
+                        resolvedWindowId, partialInteractiveRegion)) {
+                    partialInteractiveRegion = null;
+                }
             }
             final int interrogatingPid = Binder.getCallingPid();
             final long identityToken = Binder.clearCallingIdentity();
             MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             try {
-                connection.findAccessibilityNodeInfosByViewId(accessibilityNodeId,
-                        viewIdResName, interactionId, callback, mFetchFlags, interrogatingPid,
+                connection.findAccessibilityNodeInfosByViewId(accessibilityNodeId, viewIdResName,
+                        partialInteractiveRegion, interactionId, callback, mFetchFlags, interrogatingPid,
                         interrogatingTid, spec);
                 return true;
             } catch (RemoteException re) {
@@ -2208,6 +2216,7 @@
                 throws RemoteException {
             final int resolvedWindowId;
             IAccessibilityInteractionConnection connection = null;
+            Region partialInteractiveRegion = mTempRegion;
             synchronized (mLock) {
                 // We treat calls from a profile as if made by its parent as profiles
                 // share the accessibility state of the parent. The call below
@@ -2229,14 +2238,18 @@
                         return false;
                     }
                 }
+                if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
+                        resolvedWindowId, partialInteractiveRegion)) {
+                    partialInteractiveRegion = null;
+                }
             }
             final int interrogatingPid = Binder.getCallingPid();
             final long identityToken = Binder.clearCallingIdentity();
             MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             try {
                 connection.findAccessibilityNodeInfosByText(accessibilityNodeId, text,
-                        interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid,
-                        spec);
+                        partialInteractiveRegion, interactionId, callback, mFetchFlags, interrogatingPid,
+                        interrogatingTid, spec);
                 return true;
             } catch (RemoteException re) {
                 if (DEBUG) {
@@ -2255,6 +2268,7 @@
                 long interrogatingTid) throws RemoteException {
             final int resolvedWindowId;
             IAccessibilityInteractionConnection connection = null;
+            Region partialInteractiveRegion = mTempRegion;
             synchronized (mLock) {
                 // We treat calls from a profile as if made by its parent as profiles
                 // share the accessibility state of the parent. The call below
@@ -2276,14 +2290,18 @@
                         return false;
                     }
                 }
+                if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
+                        resolvedWindowId, partialInteractiveRegion)) {
+                    partialInteractiveRegion = null;
+                }
             }
             final int interrogatingPid = Binder.getCallingPid();
             final long identityToken = Binder.clearCallingIdentity();
             MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             try {
                 connection.findAccessibilityNodeInfoByAccessibilityId(accessibilityNodeId,
-                        interactionId, callback, mFetchFlags | flags, interrogatingPid,
-                        interrogatingTid, spec);
+                        partialInteractiveRegion, interactionId, callback, mFetchFlags | flags,
+                        interrogatingPid, interrogatingTid, spec);
                 return true;
             } catch (RemoteException re) {
                 if (DEBUG) {
@@ -2302,6 +2320,7 @@
                 throws RemoteException {
             final int resolvedWindowId;
             IAccessibilityInteractionConnection connection = null;
+            Region partialInteractiveRegion = mTempRegion;
             synchronized (mLock) {
                 // We treat calls from a profile as if made by its parent as profiles
                 // share the accessibility state of the parent. The call below
@@ -2324,13 +2343,17 @@
                         return false;
                     }
                 }
+                if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
+                        resolvedWindowId, partialInteractiveRegion)) {
+                    partialInteractiveRegion = null;
+                }
             }
             final int interrogatingPid = Binder.getCallingPid();
             final long identityToken = Binder.clearCallingIdentity();
             MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             try {
-                connection.findFocus(accessibilityNodeId, focusType, interactionId, callback,
-                        mFetchFlags, interrogatingPid, interrogatingTid, spec);
+                connection.findFocus(accessibilityNodeId, focusType, partialInteractiveRegion, interactionId,
+                        callback, mFetchFlags, interrogatingPid, interrogatingTid, spec);
                 return true;
             } catch (RemoteException re) {
                 if (DEBUG) {
@@ -2349,6 +2372,7 @@
                 throws RemoteException {
             final int resolvedWindowId;
             IAccessibilityInteractionConnection connection = null;
+            Region partialInteractiveRegion = mTempRegion;
             synchronized (mLock) {
                 // We treat calls from a profile as if made by its parent as profiles
                 // share the accessibility state of the parent. The call below
@@ -2370,13 +2394,17 @@
                         return false;
                     }
                 }
+                if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
+                        resolvedWindowId, partialInteractiveRegion)) {
+                    partialInteractiveRegion = null;
+                }
             }
             final int interrogatingPid = Binder.getCallingPid();
             final long identityToken = Binder.clearCallingIdentity();
             MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             try {
-                connection.focusSearch(accessibilityNodeId, direction, interactionId, callback,
-                        mFetchFlags, interrogatingPid, interrogatingTid, spec);
+                connection.focusSearch(accessibilityNodeId, direction, partialInteractiveRegion, interactionId,
+                        callback, mFetchFlags, interrogatingPid, interrogatingTid, spec);
                 return true;
             } catch (RemoteException re) {
                 if (DEBUG) {
@@ -3288,6 +3316,42 @@
             }
         }
 
+        public boolean computePartialInteractiveRegionForWindowLocked(int windowId,
+                Region outRegion) {
+            if (mWindows == null) {
+                return false;
+            }
+
+            // Windows are ordered in z order so start from the botton and find
+            // the window of interest. After that all windows that cover it should
+            // be subtracted from the resulting region. Note that for accessibility
+            // we are returning only interactive windows.
+            Region windowInteractiveRegion = null;
+            boolean windowInteractiveRegionChanged = false;
+
+            final int windowCount = mWindows.size();
+            for (int i = windowCount - 1; i >= 0; i--) {
+                AccessibilityWindowInfo currentWindow = mWindows.get(i);
+                if (windowInteractiveRegion == null) {
+                    if (currentWindow.getId() == windowId) {
+                        Rect currentWindowBounds = mTempRect;
+                        currentWindow.getBoundsInScreen(currentWindowBounds);
+                        outRegion.set(currentWindowBounds);
+                        windowInteractiveRegion = outRegion;
+                        continue;
+                    }
+                } else {
+                    Rect currentWindowBounds = mTempRect;
+                    currentWindow.getBoundsInScreen(currentWindowBounds);
+                    if (windowInteractiveRegion.op(currentWindowBounds, Region.Op.DIFFERENCE)) {
+                        windowInteractiveRegionChanged = true;
+                    }
+                }
+            }
+
+            return windowInteractiveRegionChanged;
+        }
+
         public void updateEventSourceLocked(AccessibilityEvent event) {
             if ((event.getEventType() & RETRIEVAL_ALLOWING_EVENT_TYPES) == 0) {
                 event.setSource(null);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 0919f77..3bab1bf 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -967,6 +967,17 @@
     }
 
     @Override
+    public Network getNetworkForType(int networkType) {
+        enforceAccessPermission();
+        final int uid = Binder.getCallingUid();
+        if (isNetworkBlocked(networkType, uid)) {
+            return null;
+        }
+        NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+        return (nai == null) ? null : nai.network;
+    }
+
+    @Override
     public Network[] getAllNetworks() {
         enforceAccessPermission();
         final ArrayList<Network> result = new ArrayList();
@@ -1724,7 +1735,7 @@
         pw.println();
 
         synchronized (this) {
-            pw.println("NetworkTranstionWakeLock is currently " +
+            pw.println("NetworkTransitionWakeLock is currently " +
                     (mNetTransitionWakeLock.isHeld() ? "" : "not ") + "held.");
             pw.println("It was last requested for "+mNetTransitionWakeLockCausedBy);
         }
@@ -4805,7 +4816,8 @@
             result.setType(networkType);
             return result;
         } else {
-            NetworkInfo result = new NetworkInfo(networkType);
+            NetworkInfo result = new NetworkInfo(
+                    networkType, 0, ConnectivityManager.getNetworkTypeName(networkType), "");
             result.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
             return result;
         }
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 92f5170..adfbb16 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -116,7 +116,7 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             // Update keystore settings for profiles which use the same password as their parent
-            if (Intent.ACTION_USER_STARTED.equals(intent.getAction())) {
+            if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) {
                 final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                 final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
                 final UserInfo parentInfo = um.getProfileParent(userHandle);
@@ -319,17 +319,18 @@
         String dataSystemDirectory =
                 android.os.Environment.getDataDirectory().getAbsolutePath() +
                 SYSTEM_DIRECTORY;
+        userId = getUserParentOrSelfId(userId);
         if (userId == 0) {
             // Leave it in the same place for user 0
             return dataSystemDirectory + LOCK_PATTERN_FILE;
         } else {
-            userId = getUserParentOrSelfId(userId);
             return  new File(Environment.getUserSystemDirectory(userId), LOCK_PATTERN_FILE)
                     .getAbsolutePath();
         }
     }
 
     private String getLockPasswordFilename(int userId) {
+        userId = getUserParentOrSelfId(userId);
         String dataSystemDirectory =
                 android.os.Environment.getDataDirectory().getAbsolutePath() +
                 SYSTEM_DIRECTORY;
@@ -337,7 +338,6 @@
             // Leave it in the same place for user 0
             return dataSystemDirectory + LOCK_PASSWORD_FILE;
         } else {
-            userId = getUserParentOrSelfId(userId);
             return new File(Environment.getUserSystemDirectory(userId), LOCK_PASSWORD_FILE)
                     .getAbsolutePath();
         }
@@ -510,13 +510,18 @@
 
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         try {
-            File file = new File(getLockPasswordFilename(userId));
-            if (file.exists()) {
-                file.delete();
-            }
-            file = new File(getLockPatternFilename(userId));
-            if (file.exists()) {
-                file.delete();
+            final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
+            final UserInfo parentInfo = um.getProfileParent(userId);
+            if (parentInfo == null) {
+                // This user owns its lock settings files - safe to delete them
+                File file = new File(getLockPasswordFilename(userId));
+                if (file.exists()) {
+                    file.delete();
+                }
+                file = new File(getLockPatternFilename(userId));
+                if (file.exists()) {
+                    file.delete();
+                }
             }
 
             db.beginTransaction();
diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java
index df54c7f..2830b5e 100644
--- a/services/core/java/com/android/server/MmsServiceBroker.java
+++ b/services/core/java/com/android/server/MmsServiceBroker.java
@@ -29,10 +29,12 @@
 import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.telephony.TelephonyManager;
 import android.util.Slog;
 
@@ -228,21 +230,8 @@
         }
 
         @Override
-        public boolean getCarrierConfigBoolean(long subId, String name, boolean defaultValue)
-                throws RemoteException {
-            return getServiceGuarded().getCarrierConfigBoolean(subId, name, defaultValue);
-        }
-
-        @Override
-        public int getCarrierConfigInt(long subId, String name, int defaultValue)
-                throws RemoteException {
-            return getServiceGuarded().getCarrierConfigInt(subId, name, defaultValue);
-        }
-
-        @Override
-        public String getCarrierConfigString(long subId, String name, String defaultValue)
-                throws RemoteException {
-            return getServiceGuarded().getCarrierConfigString(subId, name, defaultValue);
+        public Bundle getCarrierConfigValues(long subId) throws RemoteException {
+            return getServiceGuarded().getCarrierConfigValues(subId);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index f9b65b8..1318f66 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -44,6 +44,7 @@
 import android.net.InterfaceConfiguration;
 import android.net.IpPrefix;
 import android.net.LinkAddress;
+import android.net.Network;
 import android.net.NetworkStats;
 import android.net.NetworkUtils;
 import android.net.RouteInfo;
@@ -1200,10 +1201,12 @@
     }
 
     @Override
-    public void setDnsForwarders(String[] dns) {
+    public void setDnsForwarders(Network network, String[] dns) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
-        final Command cmd = new Command("tether", "dns", "set");
+        int netId = (network != null) ? network.netId : ConnectivityManager.NETID_UNSET;
+        final Command cmd = new Command("tether", "dns", "set", netId);
+
         for (String s : dns) {
             cmd.appendArg(NetworkUtils.numericToInetAddress(s).getHostAddress());
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c2c86ff..a3a5709 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1107,7 +1107,12 @@
 
     final ActivityThread mSystemThread;
 
+    // Holds the current foreground user's id
     int mCurrentUserId = 0;
+    // Holds the target user's id during a user switch
+    int mTargetUserId = UserHandle.USER_NULL;
+    // If there are multiple profiles for the current user, their ids are here
+    // Currently only the primary user can have managed profiles
     int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
 
     /**
@@ -2898,9 +2903,11 @@
             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
+        long startTime = SystemClock.elapsedRealtime();
         ProcessRecord app;
         if (!isolated) {
             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
+            checkTime(startTime, "startProcess: after getProcessRecord");
         } else {
             // If this is an isolated process, it can't re-use an existing process.
             app = null;
@@ -2922,14 +2929,17 @@
                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
                 // If this is a new package in the process, add the package to the list
                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
+                checkTime(startTime, "startProcess: done, added package to proc");
                 return app;
             }
 
             // An application record is attached to a previous process,
             // clean it up now.
             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
+            checkTime(startTime, "startProcess: bad proc running, killing");
             Process.killProcessGroup(app.info.uid, app.pid);
             handleAppDiedLocked(app, true, true);
+            checkTime(startTime, "startProcess: done killing old proc");
         }
 
         String hostingNameStr = hostingName != null
@@ -2965,6 +2975,7 @@
         }
 
         if (app == null) {
+            checkTime(startTime, "startProcess: creating new process record");
             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
             app.crashHandler = crashHandler;
             if (app == null) {
@@ -2976,9 +2987,11 @@
             if (isolated) {
                 mIsolatedProcesses.put(app.uid, app);
             }
+            checkTime(startTime, "startProcess: done creating new process record");
         } else {
             // If this is a new package in the process, add the package to the list
             app.addPackage(info.packageName, info.versionCode, mProcessStats);
+            checkTime(startTime, "startProcess: added package to existing proc");
         }
 
         // If the system is not ready yet, then hold off on starting this
@@ -2990,11 +3003,14 @@
                 mProcessesOnHold.add(app);
             }
             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
+            checkTime(startTime, "startProcess: returning with proc on hold");
             return app;
         }
 
+        checkTime(startTime, "startProcess: stepping in to startProcess");
         startProcessLocked(
                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
+        checkTime(startTime, "startProcess: done starting proc!");
         return (app.pid != 0) ? app : null;
     }
 
@@ -3010,11 +3026,14 @@
 
     private final void startProcessLocked(ProcessRecord app, String hostingType,
             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
+        long startTime = SystemClock.elapsedRealtime();
         if (app.pid > 0 && app.pid != MY_PID) {
+            checkTime(startTime, "startProcess: removing from pids map");
             synchronized (mPidsSelfLocked) {
                 mPidsSelfLocked.remove(app.pid);
                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
             }
+            checkTime(startTime, "startProcess: done removing from pids map");
             app.setPid(0);
         }
 
@@ -3022,7 +3041,9 @@
                 "startProcessLocked removing on hold: " + app);
         mProcessesOnHold.remove(app);
 
+        checkTime(startTime, "startProcess: starting to update cpu stats");
         updateCpuStats();
+        checkTime(startTime, "startProcess: done updating cpu stats");
 
         try {
             int uid = app.uid;
@@ -3032,10 +3053,12 @@
             if (!app.isolated) {
                 int[] permGids = null;
                 try {
+                    checkTime(startTime, "startProcess: getting gids from package manager");
                     final PackageManager pm = mContext.getPackageManager();
                     permGids = pm.getPackageGids(app.info.packageName);
 
                     if (Environment.isExternalStorageEmulated()) {
+                        checkTime(startTime, "startProcess: checking external storage perm");
                         if (pm.checkPermission(
                                 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
                                 app.info.packageName) == PERMISSION_GRANTED) {
@@ -3061,6 +3084,7 @@
                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
             }
+            checkTime(startTime, "startProcess: building args");
             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
                         && mTopComponent != null
@@ -3104,14 +3128,17 @@
             // the PID of the new process, or else throw a RuntimeException.
             boolean isActivityProcess = (entryPoint == null);
             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
+            checkTime(startTime, "startProcess: asking zygote to start proc");
             Process.ProcessStartResult startResult = Process.start(entryPoint,
                     app.processName, uid, uid, gids, debugFlags, mountExternal,
                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
+            checkTime(startTime, "startProcess: returned from zygote!");
 
             if (app.isolated) {
                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
             }
             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
+            checkTime(startTime, "startProcess: done updating battery stats");
 
             EventLog.writeEvent(EventLogTags.AM_PROC_START,
                     UserHandle.getUserId(uid), startResult.pid, uid,
@@ -3122,6 +3149,7 @@
                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
             }
 
+            checkTime(startTime, "startProcess: building log message");
             StringBuilder buf = mStringBuilder;
             buf.setLength(0);
             buf.append("Start proc ");
@@ -3159,6 +3187,7 @@
             app.usingWrapper = startResult.usingWrapper;
             app.removed = false;
             app.killedByAm = false;
+            checkTime(startTime, "startProcess: starting to update pids map");
             synchronized (mPidsSelfLocked) {
                 this.mPidsSelfLocked.put(startResult.pid, app);
                 if (isActivityProcess) {
@@ -3168,6 +3197,7 @@
                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
                 }
             }
+            checkTime(startTime, "startProcess: done updating pids map");
         } catch (RuntimeException e) {
             // XXX do better error recovery.
             app.setPid(0);
@@ -10272,13 +10302,13 @@
                 if (r == null) {
                     return false;
                 }
-                if (r.changeWindowTranslucency(true)) {
-                    mWindowManager.setAppFullscreen(token, true);
+                final boolean translucentChanged = r.changeWindowTranslucency(true);
+                if (translucentChanged) {
                     r.task.stack.releaseBackgroundResources();
                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
-                    return true;
                 }
-                return false;
+                mWindowManager.setAppFullscreen(token, true);
+                return translucentChanged;
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -10299,15 +10329,13 @@
                     ActivityRecord under = r.task.mActivities.get(index - 1);
                     under.returningOptions = options;
                 }
-                if (r.changeWindowTranslucency(false)) {
+                final boolean translucentChanged = r.changeWindowTranslucency(false);
+                if (translucentChanged) {
                     r.task.stack.convertToTranslucent(r);
-                    mWindowManager.setAppFullscreen(token, false);
                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
-                    return true;
-                } else {
-                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
-                    return false;
                 }
+                mWindowManager.setAppFullscreen(token, false);
+                return translucentChanged;
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -17937,6 +17965,7 @@
                 return false;
             }
             userName = userInfo.name;
+            mTargetUserId = userId;
         }
         mHandler.removeMessages(START_USER_SWITCH_MSG);
         mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
@@ -18004,6 +18033,7 @@
 
                 if (foreground) {
                     mCurrentUserId = userId;
+                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
                     updateCurrentProfileIdsLocked();
                     mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
                     // Once the internal notion of the active user has switched, we lock the device
@@ -18371,7 +18401,7 @@
 
     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
         if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
-        if (mCurrentUserId == userId) {
+        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
             return ActivityManager.USER_OP_IS_CURRENT;
         }
 
@@ -18511,12 +18541,13 @@
             throw new SecurityException(msg);
         }
         synchronized (this) {
-            return getUserManagerLocked().getUserInfo(mCurrentUserId);
+            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
+            return getUserManagerLocked().getUserInfo(userId);
         }
     }
 
     int getCurrentUserIdLocked() {
-        return mCurrentUserId;
+        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 6545134..6bc1c9c 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1729,16 +1729,19 @@
                         | (baseIntent.getFlags()&flagsOfInterest);
                 intent.setFlags(launchFlags);
                 inTask.setIntent(r);
+                addingToTask = true;
 
-            // If the task is not empty, then we are going to add the new activity on top
-            // of the task, so it can not be launching as a new task.
+            // If the task is not empty and the caller is asking to start it as the root
+            // of a new task, then we don't actually want to start this on the task.  We
+            // will bring the task to the front, and possibly give it a new intent.
             } else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
-                ActivityOptions.abort(options);
-                throw new IllegalStateException("Caller has inTask " + inTask
-                        + " but target is a new task");
+                addingToTask = false;
+
+            } else {
+                addingToTask = true;
             }
+
             reuseTask = inTask;
-            addingToTask = true;
         } else {
             inTask = null;
         }
@@ -1979,7 +1982,7 @@
                 sourceRecord.task : null;
 
         // Should this be considered a new task?
-        if (r.resultTo == null && !addingToTask
+        if (r.resultTo == null && inTask == null && !addingToTask
                 && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
             if (isLockTaskModeViolation(reuseTask)) {
                 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
@@ -2092,6 +2095,13 @@
                 }
             }
 
+            if (!addingToTask) {
+                // We don't actually want to have this activity added to the task, so just
+                // stop here but still tell the caller that we consumed the intent.
+                ActivityOptions.abort(options);
+                return ActivityManager.START_TASK_TO_FRONT;
+            }
+
             r.setTask(inTask, null);
             if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
                     + " in explicit task " + r.task);
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 1fd114c..7c303ff 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -31,6 +31,7 @@
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
+import android.net.Network;
 import android.net.NetworkInfo;
 import android.net.NetworkUtils;
 import android.net.RouteInfo;
@@ -56,6 +57,7 @@
 import java.net.InetAddress;
 import java.net.Inet4Address;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -742,7 +744,7 @@
         static final int CMD_IP_FORWARDING_ENABLE_ERROR  =  7;
         // notification from the master SM that it had trouble disabling IP Forwarding
         static final int CMD_IP_FORWARDING_DISABLE_ERROR =  8;
-        // notification from the master SM that it had trouble staring tethering
+        // notification from the master SM that it had trouble starting tethering
         static final int CMD_START_TETHERING_ERROR       =  9;
         // notification from the master SM that it had trouble stopping tethering
         static final int CMD_STOP_TETHERING_ERROR        = 10;
@@ -1235,12 +1237,6 @@
                         return false;
                     }
                 }
-                try {
-                    mNMService.setDnsForwarders(mDefaultDnsServers);
-                } catch (Exception e) {
-                    transitionTo(mSetDnsForwardersErrorState);
-                    return false;
-                }
                 return true;
             }
             protected boolean turnOffMasterTetherSettings() {
@@ -1348,8 +1344,17 @@
                             }
                         }
                         try {
-                            mNMService.setDnsForwarders(dnsServers);
+                            Network network = getConnectivityManager().getNetworkForType(upType);
+                            if (network == null) {
+                                Log.e(TAG, "No Network for upstream type " + upType + "!");
+                            }
+                            if (VDBG) {
+                                Log.d(TAG, "Setting DNS forwarders: Network=" + network +
+                                       ", dnsServers=" + Arrays.toString(dnsServers));
+                            }
+                            mNMService.setDnsForwarders(network, dnsServers);
                         } catch (Exception e) {
+                            Log.e(TAG, "Setting DNS forwarders failed!");
                             transitionTo(mSetDnsForwardersErrorState);
                         }
                     }
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index e31f177..e609701 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -29,7 +29,7 @@
 import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
 import android.hardware.display.IDisplayManager;
 import android.hardware.display.IDisplayManagerCallback;
-import android.hardware.display.IVirtualDisplayCallbacks;
+import android.hardware.display.IVirtualDisplayCallback;
 import android.hardware.display.WifiDisplayStatus;
 import android.hardware.input.InputManagerInternal;
 import android.media.projection.IMediaProjection;
@@ -491,7 +491,7 @@
         }
     }
 
-    private int createVirtualDisplayInternal(IVirtualDisplayCallbacks callbacks,
+    private int createVirtualDisplayInternal(IVirtualDisplayCallback callback,
             IMediaProjection projection, int callingUid, String packageName,
             String name, int width, int height, int densityDpi, Surface surface, int flags) {
         synchronized (mSyncRoot) {
@@ -502,7 +502,7 @@
             }
 
             DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
-                    callbacks, projection, callingUid, packageName,
+                    callback, projection, callingUid, packageName,
                     name, width, height, densityDpi, surface, flags);
             if (device == null) {
                 return -1;
@@ -517,7 +517,7 @@
             // Something weird happened and the logical display was not created.
             Slog.w(TAG, "Rejecting request to create virtual display "
                     + "because the logical display was not created.");
-            mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callbacks.asBinder());
+            mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder());
             handleDisplayDeviceRemovedLocked(device);
         }
         return -1;
@@ -1251,14 +1251,14 @@
         }
 
         @Override // Binder call
-        public int createVirtualDisplay(IVirtualDisplayCallbacks callbacks,
+        public int createVirtualDisplay(IVirtualDisplayCallback callback,
                 IMediaProjection projection, String packageName, String name,
                 int width, int height, int densityDpi, Surface surface, int flags) {
             final int callingUid = Binder.getCallingUid();
             if (!validatePackageName(callingUid, packageName)) {
                 throw new SecurityException("packageName must match the calling uid");
             }
-            if (callbacks == null) {
+            if (callback == null) {
                 throw new IllegalArgumentException("appToken must not be null");
             }
             if (TextUtils.isEmpty(name)) {
@@ -1306,7 +1306,7 @@
 
             final long token = Binder.clearCallingIdentity();
             try {
-                return createVirtualDisplayInternal(callbacks, projection, callingUid,
+                return createVirtualDisplayInternal(callback, projection, callingUid,
                         packageName, name, width, height, densityDpi, surface, flags);
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -1314,31 +1314,31 @@
         }
 
         @Override // Binder call
-        public void resizeVirtualDisplay(IVirtualDisplayCallbacks callbacks,
+        public void resizeVirtualDisplay(IVirtualDisplayCallback callback,
                 int width, int height, int densityDpi) {
             final long token = Binder.clearCallingIdentity();
             try {
-                resizeVirtualDisplayInternal(callbacks.asBinder(), width, height, densityDpi);
+                resizeVirtualDisplayInternal(callback.asBinder(), width, height, densityDpi);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override // Binder call
-        public void setVirtualDisplaySurface(IVirtualDisplayCallbacks callbacks, Surface surface) {
+        public void setVirtualDisplaySurface(IVirtualDisplayCallback callback, Surface surface) {
             final long token = Binder.clearCallingIdentity();
             try {
-                setVirtualDisplaySurfaceInternal(callbacks.asBinder(), surface);
+                setVirtualDisplaySurfaceInternal(callback.asBinder(), surface);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override // Binder call
-        public void releaseVirtualDisplay(IVirtualDisplayCallbacks callbacks) {
+        public void releaseVirtualDisplay(IVirtualDisplayCallback callback) {
             final long token = Binder.clearCallingIdentity();
             try {
-                releaseVirtualDisplayInternal(callbacks.asBinder());
+                releaseVirtualDisplayInternal(callback.asBinder());
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index e39f0b1..f6399a3 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -18,7 +18,7 @@
 
 import android.content.Context;
 import android.hardware.display.DisplayManager;
-import android.hardware.display.IVirtualDisplayCallbacks;
+import android.hardware.display.IVirtualDisplayCallback;
 import android.media.projection.IMediaProjection;
 import android.media.projection.IMediaProjectionCallback;
 import android.os.Handler;
@@ -55,15 +55,15 @@
         mHandler = handler;
     }
 
-    public DisplayDevice createVirtualDisplayLocked(IVirtualDisplayCallbacks callbacks,
+    public DisplayDevice createVirtualDisplayLocked(IVirtualDisplayCallback callback,
             IMediaProjection projection, int ownerUid, String ownerPackageName,
             String name, int width, int height, int densityDpi, Surface surface, int flags) {
         boolean secure = (flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0;
-        IBinder appToken = callbacks.asBinder();
+        IBinder appToken = callback.asBinder();
         IBinder displayToken = SurfaceControl.createDisplay(name, secure);
         VirtualDisplayDevice device = new VirtualDisplayDevice(displayToken, appToken,
                 ownerUid, ownerPackageName, name, width, height, densityDpi, surface, flags,
-                new Callbacks(callbacks, mHandler));
+                new Callback(callback, mHandler));
 
         mVirtualDisplayDevices.put(appToken, device);
 
@@ -139,7 +139,7 @@
         final String mOwnerPackageName;
         final String mName;
         private final int mFlags;
-        private final Callbacks mCallbacks;
+        private final Callback mCallback;
 
         private int mWidth;
         private int mHeight;
@@ -153,7 +153,7 @@
         public VirtualDisplayDevice(IBinder displayToken, IBinder appToken,
                 int ownerUid, String ownerPackageName,
                 String name, int width, int height, int densityDpi, Surface surface, int flags,
-                Callbacks callbacks) {
+                Callback callback) {
             super(VirtualDisplayAdapter.this, displayToken);
             mAppToken = appToken;
             mOwnerUid = ownerUid;
@@ -164,7 +164,7 @@
             mDensityDpi = densityDpi;
             mSurface = surface;
             mFlags = flags;
-            mCallbacks = callbacks;
+            mCallback = callback;
             mDisplayState = Display.STATE_UNKNOWN;
             mPendingChanges |= PENDING_SURFACE_CHANGE;
         }
@@ -184,7 +184,7 @@
                 mSurface = null;
             }
             SurfaceControl.destroyDisplay(getDisplayTokenLocked());
-            mCallbacks.dispatchDisplayStopped();
+            mCallback.dispatchDisplayStopped();
         }
 
         @Override
@@ -192,9 +192,9 @@
             if (state != mDisplayState) {
                 mDisplayState = state;
                 if (state == Display.STATE_OFF) {
-                    mCallbacks.dispatchDisplayPaused();
+                    mCallback.dispatchDisplayPaused();
                 } else {
-                    mCallbacks.dispatchDisplayResumed();
+                    mCallback.dispatchDisplayResumed();
                 }
             }
         }
@@ -287,16 +287,16 @@
         }
     }
 
-    private static class Callbacks extends Handler {
+    private static class Callback extends Handler {
         private static final int MSG_ON_DISPLAY_PAUSED = 0;
         private static final int MSG_ON_DISPLAY_RESUMED = 1;
         private static final int MSG_ON_DISPLAY_STOPPED = 2;
 
-        private final IVirtualDisplayCallbacks mCallbacks;
+        private final IVirtualDisplayCallback mCallback;
 
-        public Callbacks(IVirtualDisplayCallbacks callbacks, Handler handler) {
+        public Callback(IVirtualDisplayCallback callback, Handler handler) {
             super(handler.getLooper());
-            mCallbacks = callbacks;
+            mCallback = callback;
         }
 
         @Override
@@ -304,13 +304,13 @@
             try {
                 switch (msg.what) {
                     case MSG_ON_DISPLAY_PAUSED:
-                        mCallbacks.onDisplayPaused();
+                        mCallback.onPaused();
                         break;
                     case MSG_ON_DISPLAY_RESUMED:
-                        mCallbacks.onDisplayResumed();
+                        mCallback.onResumed();
                         break;
                     case MSG_ON_DISPLAY_STOPPED:
-                        mCallbacks.onDisplayStopped();
+                        mCallback.onStopped();
                         break;
                 }
             } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 753ae39..2ef9828 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -22,6 +22,7 @@
 import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
 import com.android.internal.location.ProviderProperties;
 import com.android.internal.location.ProviderRequest;
+import com.android.internal.R;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 
@@ -76,6 +77,7 @@
 import android.util.Log;
 import android.util.NtpTrustedTime;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -138,7 +140,7 @@
     private static final int LOCATION_HAS_BEARING = 8;
     private static final int LOCATION_HAS_ACCURACY = 16;
 
-// IMPORTANT - the GPS_DELETE_* symbols here must match constants in gps.h
+    // IMPORTANT - the GPS_DELETE_* symbols here must match constants in gps.h
     private static final int GPS_DELETE_EPHEMERIS = 0x0001;
     private static final int GPS_DELETE_ALMANAC = 0x0002;
     private static final int GPS_DELETE_POSITION = 0x0004;
@@ -367,6 +369,10 @@
     // Alarms
     private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
     private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT";
+
+    // SIM/Carrier info.
+    private final static String SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED";
+
     private final PowerManager mPowerManager;
     private final AlarmManager mAlarmManager;
     private final PendingIntent mWakeupIntent;
@@ -443,7 +449,7 @@
         return mGpsNavigationMessageProvider;
     }
 
-    private final BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() {
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
 
@@ -477,6 +483,19 @@
                     || Intent.ACTION_SCREEN_OFF.equals(action)
                     || Intent.ACTION_SCREEN_ON.equals(action)) {
                 updateLowPowerMode();
+            } else if (action.equals(SIM_STATE_CHANGED)) {
+                TelephonyManager phone = (TelephonyManager)
+                        mContext.getSystemService(Context.TELEPHONY_SERVICE);
+                int simState = phone.getSimState();
+                Log.d(TAG, "SIM STATE CHANGED to " + simState);
+                String mccMnc = phone.getSimOperator();
+                if (simState == TelephonyManager.SIM_STATE_READY &&
+                    !TextUtils.isEmpty(mccMnc)) {
+                    Log.d(TAG, "SIM STATE is ready, SIM MCC/MNC is " + mccMnc);
+                    synchronized (mLock) {
+                        reloadGpsProperties(context, mProperties);
+                    }
+                }
             }
         }
     };
@@ -514,37 +533,73 @@
         return native_is_supported();
     }
 
-    private boolean loadPropertiesFile(String filename) {
-        mProperties = new Properties();
+    private void reloadGpsProperties(Context context, Properties properties) {
+        Log.d(TAG, "Reset GPS properties, previous size = " + properties.size());
+        loadPropertiesFromResource(context, properties);
+        boolean isPropertiesLoadedFromFile = false;
+        final String gpsHardware = SystemProperties.get("ro.hardware.gps");
+        if (!TextUtils.isEmpty(gpsHardware)) {
+            final String propFilename =
+                    PROPERTIES_FILE_PREFIX + "." + gpsHardware + PROPERTIES_FILE_SUFFIX;
+            isPropertiesLoadedFromFile =
+                    loadPropertiesFromFile(propFilename, properties);
+        }
+        if (!isPropertiesLoadedFromFile) {
+            loadPropertiesFromFile(DEFAULT_PROPERTIES_FILE, properties);
+        }
+        Log.d(TAG, "GPS properties reloaded, size = " + properties.size());
+
+        // TODO: we should get rid of C2K specific setting.
+        setSuplHostPort(properties.getProperty("SUPL_HOST"),
+                        properties.getProperty("SUPL_PORT"));
+        mC2KServerHost = properties.getProperty("C2K_HOST");
+        String portString = properties.getProperty("C2K_PORT");
+        if (mC2KServerHost != null && portString != null) {
+            try {
+                mC2KServerPort = Integer.parseInt(portString);
+            } catch (NumberFormatException e) {
+                Log.e(TAG, "unable to parse C2K_PORT: " + portString);
+            }
+        }
+
+        try {
+            // Convert properties to string contents and send it to HAL.
+            ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
+            properties.store(baos, null);
+            native_configuration_update(baos.toString());
+            Log.d(TAG, "final config = " + baos.toString());
+        } catch (IOException ex) {
+            Log.w(TAG, "failed to dump properties contents");
+        }
+    }
+
+    private void loadPropertiesFromResource(Context context,
+                                            Properties properties) {
+        String[] configValues = context.getResources().getStringArray(
+                com.android.internal.R.array.config_gpsParameters);
+        for (String item : configValues) {
+            Log.d(TAG, "GpsParamsResource: " + item);
+            String[] split = item.split("=");
+            if (split.length == 2) {
+                properties.setProperty(split[0].trim().toUpperCase(), split[1]);
+            } else {
+                Log.w(TAG, "malformed contents: " + item);
+            }
+        }
+    }
+
+    private boolean loadPropertiesFromFile(String filename,
+                                           Properties properties) {
         try {
             File file = new File(filename);
             FileInputStream stream = null;
             try {
                 stream = new FileInputStream(file);
-                mProperties.load(stream);
+                properties.load(stream);
             } finally {
                 IoUtils.closeQuietly(stream);
             }
 
-            mSuplServerHost = mProperties.getProperty("SUPL_HOST");
-            String portString = mProperties.getProperty("SUPL_PORT");
-            if (mSuplServerHost != null && portString != null) {
-                try {
-                    mSuplServerPort = Integer.parseInt(portString);
-                } catch (NumberFormatException e) {
-                    Log.e(TAG, "unable to parse SUPL_PORT: " + portString);
-                }
-            }
-
-            mC2KServerHost = mProperties.getProperty("C2K_HOST");
-            portString = mProperties.getProperty("C2K_PORT");
-            if (mC2KServerHost != null && portString != null) {
-                try {
-                    mC2KServerPort = Integer.parseInt(portString);
-                } catch (NumberFormatException e) {
-                    Log.e(TAG, "unable to parse C2K_PORT: " + portString);
-                }
-            }
         } catch (IOException e) {
             Log.w(TAG, "Could not open GPS configuration file " + filename);
             return false;
@@ -580,16 +635,9 @@
         mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
                 BatteryStats.SERVICE_NAME));
 
-        boolean propertiesLoaded = false;
-        final String gpsHardware = SystemProperties.get("ro.hardware.gps");
-        if (!TextUtils.isEmpty(gpsHardware)) {
-            final String propFilename = PROPERTIES_FILE_PREFIX + "." + gpsHardware + PROPERTIES_FILE_SUFFIX;
-            propertiesLoaded = loadPropertiesFile(propFilename);
-        }
-
-        if (!propertiesLoaded) {
-            loadPropertiesFile(DEFAULT_PROPERTIES_FILE);
-        }
+        // Load GPS configuration.
+        mProperties = new Properties();
+        reloadGpsProperties(mContext, mProperties);
 
         // construct handler, listen for events
         mHandler = new ProviderHandler(looper);
@@ -625,7 +673,7 @@
         intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
         intentFilter.addDataScheme("sms");
         intentFilter.addDataAuthority("localhost","7275");
-        mContext.registerReceiver(mBroadcastReciever, intentFilter, null, mHandler);
+        mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, mHandler);
 
         intentFilter = new IntentFilter();
         intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
@@ -634,7 +682,7 @@
         } catch (IntentFilter.MalformedMimeTypeException e) {
             Log.w(TAG, "Malformed SUPL init mime type");
         }
-        mContext.registerReceiver(mBroadcastReciever, intentFilter, null, mHandler);
+        mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, mHandler);
 
         intentFilter = new IntentFilter();
         intentFilter.addAction(ALARM_WAKEUP);
@@ -643,7 +691,9 @@
         intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
         intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
         intentFilter.addAction(Intent.ACTION_SCREEN_ON);
-        mContext.registerReceiver(mBroadcastReciever, intentFilter, null, mHandler);
+        intentFilter = new IntentFilter();
+        intentFilter.addAction(SIM_STATE_CHANGED);
+        mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, mHandler);
     }
 
     /**
@@ -844,6 +894,19 @@
         sendMessage(ENABLE, 1, null);
     }
 
+    private void setSuplHostPort(String hostString, String portString) {
+        if (hostString != null) {
+            mSuplServerHost = hostString;
+        }
+        if (portString != null) {
+            try {
+                mSuplServerPort = Integer.parseInt(portString);
+            } catch (NumberFormatException e) {
+                Log.e(TAG, "unable to parse SUPL_PORT: " + portString);
+            }
+        }
+    }
+
     private void handleEnable() {
         if (DEBUG) Log.d(TAG, "handleEnable");
 
@@ -2055,5 +2118,8 @@
     private static native boolean native_is_navigation_message_supported();
     private native boolean native_start_navigation_message_collection();
     private native boolean native_stop_navigation_message_collection();
+
+    // GNSS Configuration
+    private static native void native_configuration_update(String configData);
 }
 
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 0da2cfa..b936130d 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -231,7 +231,7 @@
      * @param direction The direction to adjust volume in.
      */
     public void adjustVolume(int direction, int flags, String packageName, int uid) {
-        if (isPlaybackActive(false)) {
+        if (isPlaybackActive(false) || hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)) {
             flags &= ~AudioManager.FLAG_PLAY_SOUND;
         }
         if (direction > 1) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 5aa0294..9554afa 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3035,115 +3035,125 @@
                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
                     : null;
             if (prefs != null && prefs.size() > 0) {
-                // First figure out how good the original match set is.
-                // We will only allow preferred activities that came
-                // from the same match quality.
-                int match = 0;
+                boolean changed = false;
+                try {
+                    // First figure out how good the original match set is.
+                    // We will only allow preferred activities that came
+                    // from the same match quality.
+                    int match = 0;
 
-                if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
+                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
 
-                final int N = query.size();
-                for (int j=0; j<N; j++) {
-                    final ResolveInfo ri = query.get(j);
-                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
-                            + ": 0x" + Integer.toHexString(match));
-                    if (ri.match > match) {
-                        match = ri.match;
-                    }
-                }
-
-                if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
-                        + Integer.toHexString(match));
-
-                match &= IntentFilter.MATCH_CATEGORY_MASK;
-                final int M = prefs.size();
-                for (int i=0; i<M; i++) {
-                    final PreferredActivity pa = prefs.get(i);
-                    if (DEBUG_PREFERRED || debug) {
-                        Slog.v(TAG, "Checking PreferredActivity ds="
-                                + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
-                                + "\n  component=" + pa.mPref.mComponent);
-                        pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
-                    }
-                    if (pa.mPref.mMatch != match) {
-                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
-                                + Integer.toHexString(pa.mPref.mMatch));
-                        continue;
-                    }
-                    // If it's not an "always" type preferred activity and that's what we're
-                    // looking for, skip it.
-                    if (always && !pa.mPref.mAlways) {
-                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
-                        continue;
-                    }
-                    final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
-                            flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
-                    if (DEBUG_PREFERRED || debug) {
-                        Slog.v(TAG, "Found preferred activity:");
-                        if (ai != null) {
-                            ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
-                        } else {
-                            Slog.v(TAG, "  null");
-                        }
-                    }
-                    if (ai == null) {
-                        // This previously registered preferred activity
-                        // component is no longer known.  Most likely an update
-                        // to the app was installed and in the new version this
-                        // component no longer exists.  Clean it up by removing
-                        // it from the preferred activities list, and skip it.
-                        Slog.w(TAG, "Removing dangling preferred activity: "
-                                + pa.mPref.mComponent);
-                        pir.removeFilter(pa);
-                        continue;
-                    }
+                    final int N = query.size();
                     for (int j=0; j<N; j++) {
                         final ResolveInfo ri = query.get(j);
-                        if (!ri.activityInfo.applicationInfo.packageName
-                                .equals(ai.applicationInfo.packageName)) {
+                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
+                                + ": 0x" + Integer.toHexString(match));
+                        if (ri.match > match) {
+                            match = ri.match;
+                        }
+                    }
+
+                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
+                            + Integer.toHexString(match));
+
+                    match &= IntentFilter.MATCH_CATEGORY_MASK;
+                    final int M = prefs.size();
+                    for (int i=0; i<M; i++) {
+                        final PreferredActivity pa = prefs.get(i);
+                        if (DEBUG_PREFERRED || debug) {
+                            Slog.v(TAG, "Checking PreferredActivity ds="
+                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
+                                    + "\n  component=" + pa.mPref.mComponent);
+                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
+                        }
+                        if (pa.mPref.mMatch != match) {
+                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
+                                    + Integer.toHexString(pa.mPref.mMatch));
                             continue;
                         }
-                        if (!ri.activityInfo.name.equals(ai.name)) {
+                        // If it's not an "always" type preferred activity and that's what we're
+                        // looking for, skip it.
+                        if (always && !pa.mPref.mAlways) {
+                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
                             continue;
                         }
-
-                        if (removeMatches) {
-                            pir.removeFilter(pa);
-                            if (DEBUG_PREFERRED) {
-                                Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
+                        final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
+                                flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
+                        if (DEBUG_PREFERRED || debug) {
+                            Slog.v(TAG, "Found preferred activity:");
+                            if (ai != null) {
+                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
+                            } else {
+                                Slog.v(TAG, "  null");
                             }
-                            break;
                         }
-
-                        // Okay we found a previously set preferred or last chosen app.
-                        // If the result set is different from when this
-                        // was created, we need to clear it and re-ask the
-                        // user their preference, if we're looking for an "always" type entry.
-                        if (always && !pa.mPref.sameSet(query, priority)) {
-                            Slog.i(TAG, "Result set changed, dropping preferred activity for "
-                                    + intent + " type " + resolvedType);
-                            if (DEBUG_PREFERRED) {
-                                Slog.v(TAG, "Removing preferred activity since set changed "
-                                        + pa.mPref.mComponent);
-                            }
+                        if (ai == null) {
+                            // This previously registered preferred activity
+                            // component is no longer known.  Most likely an update
+                            // to the app was installed and in the new version this
+                            // component no longer exists.  Clean it up by removing
+                            // it from the preferred activities list, and skip it.
+                            Slog.w(TAG, "Removing dangling preferred activity: "
+                                    + pa.mPref.mComponent);
                             pir.removeFilter(pa);
-                            // Re-add the filter as a "last chosen" entry (!always)
-                            PreferredActivity lastChosen = new PreferredActivity(
-                                    pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
-                            pir.addFilter(lastChosen);
-                            mSettings.writePackageRestrictionsLPr(userId);
-                            return null;
+                            changed = true;
+                            continue;
                         }
+                        for (int j=0; j<N; j++) {
+                            final ResolveInfo ri = query.get(j);
+                            if (!ri.activityInfo.applicationInfo.packageName
+                                    .equals(ai.applicationInfo.packageName)) {
+                                continue;
+                            }
+                            if (!ri.activityInfo.name.equals(ai.name)) {
+                                continue;
+                            }
 
-                        // Yay! Either the set matched or we're looking for the last chosen
-                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
-                                + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
+                            if (removeMatches) {
+                                pir.removeFilter(pa);
+                                changed = true;
+                                if (DEBUG_PREFERRED) {
+                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
+                                }
+                                break;
+                            }
+
+                            // Okay we found a previously set preferred or last chosen app.
+                            // If the result set is different from when this
+                            // was created, we need to clear it and re-ask the
+                            // user their preference, if we're looking for an "always" type entry.
+                            if (always && !pa.mPref.sameSet(query, priority)) {
+                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
+                                        + intent + " type " + resolvedType);
+                                if (DEBUG_PREFERRED) {
+                                    Slog.v(TAG, "Removing preferred activity since set changed "
+                                            + pa.mPref.mComponent);
+                                }
+                                pir.removeFilter(pa);
+                                // Re-add the filter as a "last chosen" entry (!always)
+                                PreferredActivity lastChosen = new PreferredActivity(
+                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
+                                pir.addFilter(lastChosen);
+                                changed = true;
+                                return null;
+                            }
+
+                            // Yay! Either the set matched or we're looking for the last chosen
+                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
+                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
+                            return ri;
+                        }
+                    }
+                } finally {
+                    if (changed) {
+                        if (DEBUG_PREFERRED) {
+                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
+                        }
                         mSettings.writePackageRestrictionsLPr(userId);
-                        return ri;
                     }
                 }
             }
-            mSettings.writePackageRestrictionsLPr(userId);
         }
         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
         return null;
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 2929939..4a2cece 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -519,7 +519,7 @@
         for (int i = 0; i < totalUserCount; i++) {
             UserInfo user = mUsers.valueAt(i);
             if (!mRemovingUserIds.get(user.id)
-                    && !user.isGuest()) {
+                    && !user.isGuest() && !user.partial) {
                 aliveUserCount++;
             }
         }
@@ -1180,6 +1180,47 @@
     }
 
     /**
+     * Mark this guest user for deletion to allow us to create another guest
+     * and switch to that user before actually removing this guest.
+     * @param userHandle the userid of the current guest
+     * @return whether the user could be marked for deletion
+     */
+    public boolean markGuestForDeletion(int userHandle) {
+        checkManageUsersPermission("Only the system can remove users");
+        if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
+                UserManager.DISALLOW_REMOVE_USER, false)) {
+            Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled.");
+            return false;
+        }
+
+        long ident = Binder.clearCallingIdentity();
+        try {
+            final UserInfo user;
+            synchronized (mPackagesLock) {
+                user = mUsers.get(userHandle);
+                if (userHandle == 0 || user == null || mRemovingUserIds.get(userHandle)) {
+                    return false;
+                }
+                if (!user.isGuest()) {
+                    return false;
+                }
+                // Set this to a partially created user, so that the user will be purged
+                // on next startup, in case the runtime stops now before stopping and
+                // removing the user completely.
+                user.partial = true;
+                // Mark it as disabled, so that it isn't returned any more when
+                // profiles are queried.
+                user.flags |= UserInfo.FLAG_DISABLED;
+                user.flags &= ~UserInfo.FLAG_GUEST;
+                writeUserLocked(user);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+        return true;
+    }
+
+    /**
      * Removes a user and all data directories created for that user. This method should be called
      * after the user's processes have been terminated.
      * @param userHandle the user's id
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 61ad7aa..fa1c0ff 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -457,7 +457,7 @@
                 availableBounds.set(0, 0, screenWidth, screenHeight);
 
                 Region nonMagnifiedBounds = mTempRegion4;
-                nonMagnifiedBounds.set(0,  0,  0,  0);
+                nonMagnifiedBounds.set(0, 0, 0, 0);
 
                 SparseArray<WindowState> visibleWindows = mTempWindowStates;
                 visibleWindows.clear();
@@ -566,7 +566,7 @@
             public void setMagnifiedRegionBorderShownLocked(boolean shown, boolean animate) {
                 if (shown) {
                     mFullRedrawNeeded = true;
-                    mOldMagnifiedBounds.set(0,  0,  0,  0);
+                    mOldMagnifiedBounds.set(0, 0, 0, 0);
                 }
                 mWindow.setShown(shown, animate);
             }
@@ -614,19 +614,15 @@
             private final class ViewportWindow {
                 private static final String SURFACE_TITLE = "Magnification Overlay";
 
-                private static final String PROPERTY_NAME_ALPHA = "alpha";
-
-                private static final int MIN_ALPHA = 0;
-                private static final int MAX_ALPHA = 255;
-
                 private final Region mBounds = new Region();
                 private final Rect mDirtyRect = new Rect();
                 private final Paint mPaint = new Paint();
 
-                private final ValueAnimator mShowHideFrameAnimator;
                 private final SurfaceControl mSurfaceControl;
                 private final Surface mSurface = new Surface();
 
+                private final AnimationController mAnimationController;
+
                 private boolean mShown;
                 private int mAlpha;
 
@@ -651,6 +647,9 @@
                     mSurfaceControl.setPosition(0, 0);
                     mSurface.copyFrom(mSurfaceControl);
 
+                    mAnimationController = new AnimationController(context,
+                            mWindowManagerService.mH.getLooper());
+
                     TypedValue typedValue = new TypedValue();
                     context.getTheme().resolveAttribute(R.attr.colorActivatedHighlight,
                             typedValue, true);
@@ -660,14 +659,6 @@
                     mPaint.setStrokeWidth(mBorderWidth);
                     mPaint.setColor(borderColor);
 
-                    Interpolator interpolator = new DecelerateInterpolator(2.5f);
-                    final long longAnimationDuration = context.getResources().getInteger(
-                            com.android.internal.R.integer.config_longAnimTime);
-
-                    mShowHideFrameAnimator = ObjectAnimator.ofInt(this, PROPERTY_NAME_ALPHA,
-                            MIN_ALPHA, MAX_ALPHA);
-                    mShowHideFrameAnimator.setInterpolator(interpolator);
-                    mShowHideFrameAnimator.setDuration(longAnimationDuration);
                     mInvalidated = true;
                 }
 
@@ -677,24 +668,7 @@
                             return;
                         }
                         mShown = shown;
-                        if (animate) {
-                            if (mShowHideFrameAnimator.isRunning()) {
-                                mShowHideFrameAnimator.reverse();
-                            } else {
-                                if (shown) {
-                                    mShowHideFrameAnimator.start();
-                                } else {
-                                    mShowHideFrameAnimator.reverse();
-                                }
-                            }
-                        } else {
-                            mShowHideFrameAnimator.cancel();
-                            if (shown) {
-                                setAlpha(MAX_ALPHA);
-                            } else {
-                                setAlpha(MIN_ALPHA);
-                            }
-                        }
+                        mAnimationController.onFrameShownStateChanged(shown, animate);
                         if (DEBUG_VIEWPORT_WINDOW) {
                             Slog.i(LOG_TAG, "ViewportWindow shown: " + mShown);
                         }
@@ -801,6 +775,64 @@
                     mSurfaceControl.release();
                     mSurface.release();
                 }
+
+                private final class AnimationController extends Handler {
+                    private static final String PROPERTY_NAME_ALPHA = "alpha";
+
+                    private static final int MIN_ALPHA = 0;
+                    private static final int MAX_ALPHA = 255;
+
+                    private static final int MSG_FRAME_SHOWN_STATE_CHANGED = 1;
+
+                    private final ValueAnimator mShowHideFrameAnimator;
+
+                    public AnimationController(Context context, Looper looper) {
+                        super(looper);
+                        mShowHideFrameAnimator = ObjectAnimator.ofInt(ViewportWindow.this,
+                                PROPERTY_NAME_ALPHA, MIN_ALPHA, MAX_ALPHA);
+
+                        Interpolator interpolator = new DecelerateInterpolator(2.5f);
+                        final long longAnimationDuration = context.getResources().getInteger(
+                                com.android.internal.R.integer.config_longAnimTime);
+
+                        mShowHideFrameAnimator.setInterpolator(interpolator);
+                        mShowHideFrameAnimator.setDuration(longAnimationDuration);
+                    }
+
+                    public void onFrameShownStateChanged(boolean shown, boolean animate) {
+                        obtainMessage(MSG_FRAME_SHOWN_STATE_CHANGED,
+                                shown ? 1 : 0, animate ? 1 : 0).sendToTarget();
+                    }
+
+                    @Override
+                    public void handleMessage(Message message) {
+                        switch (message.what) {
+                            case MSG_FRAME_SHOWN_STATE_CHANGED: {
+                                final boolean shown = message.arg1 == 1;
+                                final boolean animate = message.arg2 == 1;
+
+                                if (animate) {
+                                    if (mShowHideFrameAnimator.isRunning()) {
+                                        mShowHideFrameAnimator.reverse();
+                                    } else {
+                                        if (shown) {
+                                            mShowHideFrameAnimator.start();
+                                        } else {
+                                            mShowHideFrameAnimator.reverse();
+                                        }
+                                    }
+                                } else {
+                                    mShowHideFrameAnimator.cancel();
+                                    if (shown) {
+                                        setAlpha(MAX_ALPHA);
+                                    } else {
+                                        setAlpha(MIN_ALPHA);
+                                    }
+                                }
+                            } break;
+                        }
+                    }
+                }
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c70cb22..08343d8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4306,11 +4306,7 @@
         AppWindowToken atoken = findAppWindowToken(token);
         if (atoken != null) {
             atoken.appFullscreen = toOpaque;
-            // When making translucent, wait until windows below have been drawn.
-            if (toOpaque) {
-                // Making opaque so do it now.
-                setWindowOpaque(token, true);
-            }
+            setWindowOpaque(token, toOpaque);
             requestTraversal();
         }
     }
@@ -11402,7 +11398,8 @@
                 final WindowList windows = getDefaultWindowListLocked();
                 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
                     final WindowState win = windows.get(winNdx);
-                    if (win.mHasSurface && win.mAppToken != null) {
+                    if (win.mHasSurface
+                            && (win.mAppToken != null || mPolicy.isForceHiding(win.mAttrs))) {
                         win.mWinAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
                         // Force add to mResizingWindows.
                         win.mLastContentInsets.set(-1, -1, -1, -1);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 4b7dd08..3d4be12 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -524,6 +524,7 @@
         private boolean mShown = false;
         private int mLayerStack;
         private boolean mIsOpaque;
+        private float mDsdx, mDtdx, mDsdy, mDtdy;
         private final String mName;
 
         public SurfaceTrace(SurfaceSession s,
@@ -619,6 +620,19 @@
         }
 
         @Override
+        public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
+            if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) {
+                Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy +
+                        "): OLD:" + this + ". Called by " + Debug.getCallers(3));
+                mDsdx = dsdx;
+                mDtdx = dtdx;
+                mDsdy = dsdy;
+                mDtdy = dtdy;
+            }
+            super.setMatrix(dsdx, dtdx, dsdy, dtdy);
+        }
+
+        @Override
         public void hide() {
             if (mShown) {
                 Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by " + Debug.getCallers(3));
@@ -665,7 +679,8 @@
                     + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
                     + " " + mSize.x + "x" + mSize.y
                     + " crop=" + mWindowCrop.toShortString()
-                    + " opaque=" + mIsOpaque;
+                    + " opaque=" + mIsOpaque
+                    + " (" + mDsdx + "," + mDtdx + "," + mDsdy + "," + mDtdy + ")";
         }
     }
 
@@ -1068,6 +1083,14 @@
                     mShownAlpha *= appTransformation.getAlpha();
                     if (appTransformation.hasClipRect()) {
                         mClipRect.set(appTransformation.getClipRect());
+                        if (mWin.mHScale > 0) {
+                            mClipRect.left /= mWin.mHScale;
+                            mClipRect.right /= mWin.mHScale;
+                        }
+                        if (mWin.mVScale > 0) {
+                            mClipRect.top /= mWin.mVScale;
+                            mClipRect.bottom /= mWin.mVScale;
+                        }
                         mHasClipRect = true;
                     }
                 }
@@ -1418,10 +1441,10 @@
             w.mLastVScale = w.mVScale;
             if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
                     "alpha=" + mShownAlpha + " layer=" + mAnimLayer
-                    + " matrix=[" + (mDsDx*w.mHScale)
-                    + "," + (mDtDx*w.mVScale)
-                    + "][" + (mDsDy*w.mHScale)
-                    + "," + (mDtDy*w.mVScale) + "]", null);
+                    + " matrix=[" + mDsDx + "*" + w.mHScale
+                    + "," + mDtDx + "*" + w.mVScale
+                    + "][" + mDsDy + "*" + w.mHScale
+                    + "," + mDtDy + "*" + w.mVScale + "]", null);
             if (mSurfaceControl != null) {
                 try {
                     mSurfaceAlpha = mShownAlpha;
diff --git a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
index c398908..6958087 100644
--- a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
@@ -65,6 +65,7 @@
 static const GpsGeofencingInterface* sGpsGeofencingInterface = NULL;
 static const GpsMeasurementInterface* sGpsMeasurementInterface = NULL;
 static const GpsNavigationMessageInterface* sGpsNavigationMessageInterface = NULL;
+static const GnssConfigurationInterface* sGnssConfigurationInterface = NULL;
 
 // temporary storage for GPS callbacks
 static GpsSvStatus  sGpsSvStatus;
@@ -502,6 +503,9 @@
         sGpsNavigationMessageInterface =
             (const GpsNavigationMessageInterface*)sGpsInterface->get_extension(
                     GPS_NAVIGATION_MESSAGE_INTERFACE);
+        sGnssConfigurationInterface =
+            (const GnssConfigurationInterface*)sGpsInterface->get_extension(
+                    GNSS_CONFIGURATION_INTERFACE);
     }
 }
 
@@ -901,55 +905,57 @@
 
     if (flags & GPS_CLOCK_HAS_LEAP_SECOND) {
         jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setLeapSecond", "(S)V");
-        env->CallObjectMethod(gpsClockObject, setterMethod, clock->leap_second);
+        env->CallVoidMethod(gpsClockObject, setterMethod, clock->leap_second);
    }
 
    jmethodID typeSetterMethod = env->GetMethodID(gpsClockClass, "setType", "(B)V");
-   env->CallObjectMethod(gpsClockObject, typeSetterMethod, clock->type);
+   env->CallVoidMethod(gpsClockObject, typeSetterMethod, clock->type);
 
     jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setTimeInNs", longSignature);
-    env->CallObjectMethod(gpsClockObject, setterMethod, clock->time_ns);
+    env->CallVoidMethod(gpsClockObject, setterMethod, clock->time_ns);
 
     if (flags & GPS_CLOCK_HAS_TIME_UNCERTAINTY) {
         jmethodID setterMethod =
                 env->GetMethodID(gpsClockClass, "setTimeUncertaintyInNs", doubleSignature);
-        env->CallObjectMethod(gpsClockObject, setterMethod, clock->time_uncertainty_ns);
+        env->CallVoidMethod(gpsClockObject, setterMethod, clock->time_uncertainty_ns);
     }
 
     if (flags & GPS_CLOCK_HAS_FULL_BIAS) {
         jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setFullBiasInNs", longSignature);
-        env->CallObjectMethod(gpsClockObject, setterMethod, clock->full_bias_ns);
+        env->CallVoidMethod(gpsClockObject, setterMethod, clock->full_bias_ns);
     }
 
     if (flags & GPS_CLOCK_HAS_BIAS) {
         jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setBiasInNs", doubleSignature);
-        env->CallObjectMethod(gpsClockObject, setterMethod, clock->bias_ns);
+        env->CallVoidMethod(gpsClockObject, setterMethod, clock->bias_ns);
     }
 
     if (flags & GPS_CLOCK_HAS_BIAS_UNCERTAINTY) {
         jmethodID setterMethod =
                 env->GetMethodID(gpsClockClass, "setBiasUncertaintyInNs", doubleSignature);
-        env->CallObjectMethod(gpsClockObject, setterMethod, clock->bias_uncertainty_ns);
+        env->CallVoidMethod(gpsClockObject, setterMethod, clock->bias_uncertainty_ns);
     }
 
     if (flags & GPS_CLOCK_HAS_DRIFT) {
         jmethodID setterMethod =
                 env->GetMethodID(gpsClockClass, "setDriftInNsPerSec", doubleSignature);
-        env->CallObjectMethod(gpsClockObject, setterMethod, clock->drift_nsps);
+        env->CallVoidMethod(gpsClockObject, setterMethod, clock->drift_nsps);
     }
 
     if (flags & GPS_CLOCK_HAS_DRIFT_UNCERTAINTY) {
         jmethodID setterMethod =
                 env->GetMethodID(gpsClockClass, "setDriftUncertaintyInNsPerSec", doubleSignature);
-        env->CallObjectMethod(gpsClockObject, setterMethod, clock->drift_uncertainty_nsps);
+        env->CallVoidMethod(gpsClockObject, setterMethod, clock->drift_uncertainty_nsps);
     }
 
+    env->DeleteLocalRef(gpsClockClass);
     return gpsClockObject;
 }
 
 static jobject translate_gps_measurement(JNIEnv* env, GpsMeasurement* measurement) {
     const char* byteSignature = "(B)V";
     const char* shortSignature = "(S)V";
+    const char* intSignature = "(I)V";
     const char* longSignature = "(J)V";
     const char* floatSignature = "(F)V";
     const char* doubleSignature = "(D)V";
@@ -961,21 +967,21 @@
     GpsMeasurementFlags flags = measurement->flags;
 
     jmethodID prnSetterMethod = env->GetMethodID(gpsMeasurementClass, "setPrn", byteSignature);
-    env->CallObjectMethod(gpsMeasurementObject, prnSetterMethod, measurement->prn);
+    env->CallVoidMethod(gpsMeasurementObject, prnSetterMethod, measurement->prn);
 
     jmethodID timeOffsetSetterMethod =
             env->GetMethodID(gpsMeasurementClass, "setTimeOffsetInNs", doubleSignature);
-    env->CallObjectMethod(
+    env->CallVoidMethod(
             gpsMeasurementObject,
             timeOffsetSetterMethod,
             measurement->time_offset_ns);
 
     jmethodID stateSetterMethod = env->GetMethodID(gpsMeasurementClass, "setState", shortSignature);
-    env->CallObjectMethod(gpsMeasurementObject, stateSetterMethod, measurement->state);
+    env->CallVoidMethod(gpsMeasurementObject, stateSetterMethod, measurement->state);
 
     jmethodID receivedGpsTowSetterMethod =
             env->GetMethodID(gpsMeasurementClass, "setReceivedGpsTowInNs", longSignature);
-    env->CallObjectMethod(
+    env->CallVoidMethod(
             gpsMeasurementObject,
             receivedGpsTowSetterMethod,
             measurement->received_gps_tow_ns);
@@ -991,13 +997,13 @@
 
     jmethodID cn0SetterMethod =
             env->GetMethodID(gpsMeasurementClass, "setCn0InDbHz", doubleSignature);
-    env->CallObjectMethod(gpsMeasurementObject, cn0SetterMethod, measurement->c_n0_dbhz);
+    env->CallVoidMethod(gpsMeasurementObject, cn0SetterMethod, measurement->c_n0_dbhz);
 
     jmethodID pseudorangeRateSetterMethod = env->GetMethodID(
             gpsMeasurementClass,
             "setPseudorangeRateInMetersPerSec",
             doubleSignature);
-    env->CallObjectMethod(
+    env->CallVoidMethod(
             gpsMeasurementObject,
             pseudorangeRateSetterMethod,
             measurement->pseudorange_rate_mps);
@@ -1006,14 +1012,14 @@
             gpsMeasurementClass,
             "setPseudorangeRateUncertaintyInMetersPerSec",
             doubleSignature);
-    env->CallObjectMethod(
+    env->CallVoidMethod(
             gpsMeasurementObject,
             pseudorangeRateUncertaintySetterMethod,
             measurement->pseudorange_rate_uncertainty_mps);
 
     jmethodID accumulatedDeltaRangeStateSetterMethod =
             env->GetMethodID(gpsMeasurementClass, "setAccumulatedDeltaRangeState", shortSignature);
-    env->CallObjectMethod(
+    env->CallVoidMethod(
             gpsMeasurementObject,
             accumulatedDeltaRangeStateSetterMethod,
             measurement->accumulated_delta_range_state);
@@ -1039,7 +1045,7 @@
     if (flags & GPS_MEASUREMENT_HAS_PSEUDORANGE) {
         jmethodID setterMethod =
                 env->GetMethodID(gpsMeasurementClass, "setPseudorangeInMeters", doubleSignature);
-        env->CallObjectMethod(gpsMeasurementObject, setterMethod, measurement->pseudorange_m);
+        env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->pseudorange_m);
     }
 
     if (flags & GPS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY) {
@@ -1047,7 +1053,7 @@
                 gpsMeasurementClass,
                 "setPseudorangeUncertaintyInMeters",
                 doubleSignature);
-        env->CallObjectMethod(
+        env->CallVoidMethod(
                 gpsMeasurementObject,
                 setterMethod,
                 measurement->pseudorange_uncertainty_m);
@@ -1056,7 +1062,7 @@
     if (flags & GPS_MEASUREMENT_HAS_CODE_PHASE) {
         jmethodID setterMethod =
                 env->GetMethodID(gpsMeasurementClass, "setCodePhaseInChips", doubleSignature);
-        env->CallObjectMethod(gpsMeasurementObject, setterMethod, measurement->code_phase_chips);
+        env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->code_phase_chips);
     }
 
     if (flags & GPS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY) {
@@ -1064,7 +1070,7 @@
                 gpsMeasurementClass,
                 "setCodePhaseUncertaintyInChips",
                 doubleSignature);
-        env->CallObjectMethod(
+        env->CallVoidMethod(
                 gpsMeasurementObject,
                 setterMethod,
                 measurement->code_phase_uncertainty_chips);
@@ -1073,7 +1079,7 @@
     if (flags & GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY) {
         jmethodID setterMethod =
                 env->GetMethodID(gpsMeasurementClass, "setCarrierFrequencyInHz", floatSignature);
-        env->CallObjectMethod(
+        env->CallVoidMethod(
                 gpsMeasurementObject,
                 setterMethod,
                 measurement->carrier_frequency_hz);
@@ -1082,13 +1088,13 @@
     if (flags & GPS_MEASUREMENT_HAS_CARRIER_CYCLES) {
         jmethodID setterMethod =
                 env->GetMethodID(gpsMeasurementClass, "setCarrierCycles", longSignature);
-        env->CallObjectMethod(gpsMeasurementObject, setterMethod, measurement->carrier_cycles);
+        env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->carrier_cycles);
     }
 
     if (flags & GPS_MEASUREMENT_HAS_CARRIER_PHASE) {
         jmethodID setterMethod =
                 env->GetMethodID(gpsMeasurementClass, "setCarrierPhase", doubleSignature);
-        env->CallObjectMethod(gpsMeasurementObject, setterMethod, measurement->carrier_phase);
+        env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->carrier_phase);
     }
 
     if (flags & GPS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY) {
@@ -1096,7 +1102,7 @@
                 gpsMeasurementClass,
                 "setCarrierPhaseUncertainty",
                 doubleSignature);
-        env->CallObjectMethod(
+        env->CallVoidMethod(
                 gpsMeasurementObject,
                 setterMethod,
                 measurement->carrier_phase_uncertainty);
@@ -1104,18 +1110,18 @@
 
     jmethodID lossOfLockSetterMethod =
             env->GetMethodID(gpsMeasurementClass, "setLossOfLock", byteSignature);
-    env->CallObjectMethod(gpsMeasurementObject, lossOfLockSetterMethod, measurement->loss_of_lock);
+    env->CallVoidMethod(gpsMeasurementObject, lossOfLockSetterMethod, measurement->loss_of_lock);
 
     if (flags & GPS_MEASUREMENT_HAS_BIT_NUMBER) {
         jmethodID setterMethod =
-                env->GetMethodID(gpsMeasurementClass, "setBitNumber", shortSignature);
-        env->CallObjectMethod(gpsMeasurementObject, setterMethod, measurement->bit_number);
+                env->GetMethodID(gpsMeasurementClass, "setBitNumber", intSignature);
+        env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->bit_number);
     }
 
     if (flags & GPS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT) {
         jmethodID setterMethod =
                 env->GetMethodID(gpsMeasurementClass, "setTimeFromLastBitInMs", shortSignature);
-        env->CallObjectMethod(
+        env->CallVoidMethod(
                 gpsMeasurementObject,
                 setterMethod,
                 measurement->time_from_last_bit_ms);
@@ -1124,7 +1130,7 @@
     if (flags & GPS_MEASUREMENT_HAS_DOPPLER_SHIFT) {
         jmethodID setterMethod =
                 env->GetMethodID(gpsMeasurementClass, "setDopplerShiftInHz", doubleSignature);
-        env->CallObjectMethod(gpsMeasurementObject, setterMethod, measurement->doppler_shift_hz);
+        env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->doppler_shift_hz);
     }
 
     if (flags & GPS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY) {
@@ -1132,7 +1138,7 @@
                 gpsMeasurementClass,
                 "setDopplerShiftUncertaintyInHz",
                 doubleSignature);
-        env->CallObjectMethod(
+        env->CallVoidMethod(
                 gpsMeasurementObject,
                 setterMethod,
                 measurement->doppler_shift_uncertainty_hz);
@@ -1140,7 +1146,7 @@
 
     jmethodID multipathIndicatorSetterMethod =
             env->GetMethodID(gpsMeasurementClass, "setMultipathIndicator", byteSignature);
-    env->CallObjectMethod(
+    env->CallVoidMethod(
             gpsMeasurementObject,
             multipathIndicatorSetterMethod,
             measurement->multipath_indicator);
@@ -1148,19 +1154,19 @@
     if (flags & GPS_MEASUREMENT_HAS_SNR) {
         jmethodID setterMethod =
                 env->GetMethodID(gpsMeasurementClass, "setSnrInDb", doubleSignature);
-        env->CallObjectMethod(gpsMeasurementObject, setterMethod, measurement->snr_db);
+        env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->snr_db);
     }
 
     if (flags & GPS_MEASUREMENT_HAS_ELEVATION) {
         jmethodID setterMethod =
                 env->GetMethodID(gpsMeasurementClass, "setElevationInDeg", doubleSignature);
-        env->CallObjectMethod(gpsMeasurementObject, setterMethod, measurement->elevation_deg);
+        env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->elevation_deg);
     }
 
     if (flags & GPS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY) {
         jmethodID setterMethod =
                 env->GetMethodID(gpsMeasurementClass, "setElevationUncertaintyInDeg", doubleSignature);
-        env->CallObjectMethod(
+        env->CallVoidMethod(
                 gpsMeasurementObject,
                 setterMethod,
                 measurement->elevation_uncertainty_deg);
@@ -1169,7 +1175,7 @@
     if (flags & GPS_MEASUREMENT_HAS_AZIMUTH) {
         jmethodID setterMethod =
                 env->GetMethodID(gpsMeasurementClass, "setAzimuthInDeg", doubleSignature);
-        env->CallObjectMethod(gpsMeasurementObject, setterMethod, measurement->azimuth_deg);
+        env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->azimuth_deg);
     }
 
     if (flags & GPS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY) {
@@ -1177,14 +1183,14 @@
                 gpsMeasurementClass,
                 "setAzimuthUncertaintyInDeg",
                 doubleSignature);
-        env->CallObjectMethod(
+        env->CallVoidMethod(
                 gpsMeasurementObject,
                 setterMethod,
                 measurement->azimuth_uncertainty_deg);
     }
 
     jmethodID usedInFixSetterMethod = env->GetMethodID(gpsMeasurementClass, "setUsedInFix", "(Z)V");
-    env->CallObjectMethod(
+    env->CallVoidMethod(
             gpsMeasurementObject,
             usedInFixSetterMethod,
             (flags & GPS_MEASUREMENT_HAS_USED_IN_FIX) && measurement->used_in_fix);
@@ -1240,6 +1246,11 @@
 
         env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData, gpsMeasurementsEvent);
         checkAndClearExceptionFromCallback(env, __FUNCTION__);
+
+        env->DeleteLocalRef(gpsClock);
+        env->DeleteLocalRef(measurementArray);
+        env->DeleteLocalRef(gpsMeasurementsEventClass);
+        env->DeleteLocalRef(gpsMeasurementsEvent);
     } else {
         ALOGE("Invalid GpsData size found in gps_measurement_callback, size=%d", data->size);
     }
@@ -1318,6 +1329,8 @@
     jmethodID setDataMethod = env->GetMethodID(navigationMessageClass, "setData", "([B)V");
     env->CallVoidMethod(navigationMessageObject, setDataMethod, dataArray);
 
+    env->DeleteLocalRef(navigationMessageClass);
+    env->DeleteLocalRef(dataArray);
     return navigationMessageObject;
 }
 
@@ -1344,6 +1357,10 @@
 
         env->CallVoidMethod(mCallbacksObj, method_reportNavigationMessages, navigationMessageEvent);
         checkAndClearExceptionFromCallback(env, __FUNCTION__);
+
+        env->DeleteLocalRef(navigationMessage);
+        env->DeleteLocalRef(navigationMessageEventClass);
+        env->DeleteLocalRef(navigationMessageEvent);
     } else {
         ALOGE("Invalid GpsNavigationMessage size found: %d", message->size);
     }
@@ -1392,6 +1409,20 @@
     return JNI_TRUE;
 }
 
+static void android_location_GpsLocationProvider_configuration_update(JNIEnv* env, jobject obj,
+        jstring config_content)
+{
+    if (!sGnssConfigurationInterface) {
+        ALOGE("no GPS configuration interface in configuraiton_update");
+        return;
+    }
+    const char *data = env->GetStringUTFChars(config_content, NULL);
+    ALOGD("GPS configuration:\n %s", data);
+    sGnssConfigurationInterface->configuration_update(
+            data, env->GetStringUTFLength(config_content));
+    env->ReleaseStringUTFChars(config_content, data);
+}
+
 static JNINativeMethod sMethods[] = {
      /* name, signature, funcPtr */
     {"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native},
@@ -1479,6 +1510,9 @@
     {"native_stop_navigation_message_collection",
             "()Z",
             (void*) android_location_GpsLocationProvider_stop_navigation_message_collection},
+    {"native_configuration_update",
+            "(Ljava/lang/String;)V",
+            (void*)android_location_GpsLocationProvider_configuration_update},
 };
 
 int register_android_server_location_GpsLocationProvider(JNIEnv* env)
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index c078cb2..c63eb18 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -30,6 +30,7 @@
 import android.database.ContentObserver;
 import android.hardware.usb.UsbAccessory;
 import android.hardware.usb.UsbManager;
+import android.media.AudioManager;
 import android.os.FileUtils;
 import android.os.Handler;
 import android.os.Looper;
@@ -587,7 +588,7 @@
                     UsbManager.USB_FUNCTION_AUDIO_SOURCE);
             if (enabled != mAudioSourceEnabled) {
                 // send a sticky broadcast containing current USB state
-                Intent intent = new Intent(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG);
+                Intent intent = new Intent(AudioManager.ACTION_USB_AUDIO_ACCESSORY_PLUG);
                 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                 intent.putExtra("state", (enabled ? 1 : 0));
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index 5860fc7..06febb3 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -25,6 +25,7 @@
 import android.hardware.usb.UsbDevice;
 import android.hardware.usb.UsbEndpoint;
 import android.hardware.usb.UsbInterface;
+import android.media.AudioManager;
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
@@ -124,7 +125,7 @@
     private void sendDeviceNotification(int card, int device, boolean enabled,
             boolean hasPlayback, boolean hasCapture, boolean hasMIDI) {
         // send a sticky broadcast containing current USB state
-        Intent intent = new Intent(Intent.ACTION_USB_AUDIO_DEVICE_PLUG);
+        Intent intent = new Intent(AudioManager.ACTION_USB_AUDIO_DEVICE_PLUG);
         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
         intent.putExtra("state", enabled ? 1 : 0);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 45fa9234..7c7b732 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -39,6 +39,7 @@
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.RemoteException;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.voice.IVoiceInteractionService;
@@ -412,6 +413,9 @@
                 final int callingPid = Binder.getCallingPid();
                 final int callingUid = Binder.getCallingUid();
                 final long caller = Binder.clearCallingIdentity();
+                if (!SystemProperties.getBoolean("persist.test.voice_interaction", false)) {
+                    throw new SecurityException("Voice interaction not supported");
+                }
                 try {
                     return mImpl.startVoiceActivityLocked(callingPid, callingUid, token,
                             intent, resolvedType);
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index d93c282..88e5bd6 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -100,6 +100,7 @@
     public long contactIdOrZero;
     public boolean needUpdate;
     public Uri contactRefUri;
+    public String lookupKey;
 
     /**
      * Contact display photo URI.  If a contact has no display photo but a thumbnail, it'll be
@@ -231,6 +232,12 @@
                     // the in-call UI, for example.)
                 }
 
+                // Contact lookupKey
+                columnIndex = cursor.getColumnIndex(PhoneLookup.LOOKUP_KEY);
+                if (columnIndex != -1) {
+                    info.lookupKey = cursor.getString(columnIndex);
+                }
+
                 // Display photo URI.
                 columnIndex = cursor.getColumnIndex(PhoneLookup.PHOTO_URI);
                 if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) {
diff --git a/telephony/java/com/android/internal/telephony/IMms.aidl b/telephony/java/com/android/internal/telephony/IMms.aidl
index cbcef25..2aeb42f 100644
--- a/telephony/java/com/android/internal/telephony/IMms.aidl
+++ b/telephony/java/com/android/internal/telephony/IMms.aidl
@@ -19,6 +19,7 @@
 import android.app.PendingIntent;
 import android.content.ContentValues;
 import android.net.Uri;
+import android.os.Bundle;
 
 /**
  * Service interface to handle MMS API requests
@@ -78,33 +79,11 @@
     void updateMmsDownloadStatus(int messageRef, in byte[] pdu);
 
     /**
-     * Get carrier-dependent configuration value as boolean. For example, if multipart SMS
-     * is supported.
+     * Get carrier-dependent configuration values.
      *
      * @param subId the SIM id
-     * @param name the configuration name
-     * @param defaultValue the default value if fail to find the name
      */
-    boolean getCarrierConfigBoolean(long subId, String name, boolean defaultValue);
-
-    /**
-     * Get carrier-dependent configuration value as int. For example, the MMS message size limit.
-     *
-     * @param subId the SIM id
-     * @param name the configuration name
-     * @param defaultValue the default value if fail to find the name
-     */
-    int getCarrierConfigInt(long subId, String name, int defaultValue);
-
-    /**
-     * Get carrier-dependent configuration value as String. For example, extra HTTP headers for
-     * MMS request.
-     *
-     * @param subId the SIM id
-     * @param name the configuration name
-     * @param defaultValue the default value if fail to find the name
-     */
-    String getCarrierConfigString(long subId, String name, String defaultValue);
+    Bundle getCarrierConfigValues(long subId);
 
     /**
      * Import a text message into system's SMS store
diff --git a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/BrowserListFragment.java b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/BrowserListFragment.java
index 64602d52..8cc9b97 100644
--- a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/BrowserListFragment.java
+++ b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/BrowserListFragment.java
@@ -47,12 +47,12 @@
 
     // For args
     public static final String ARG_COMPONENT = "component";
-    public static final String ARG_URI = "uri";
+    public static final String ARG_ID = "uri";
 
     private Adapter mAdapter;
     private List<Item> mItems = new ArrayList();
     private ComponentName mComponent;
-    private Uri mUri;
+    private String mNodeId;
     private MediaBrowser mBrowser;
 
     private static class Item {
@@ -76,7 +76,7 @@
         // Get our arguments
         final Bundle args = getArguments();
         mComponent = args.getParcelable(ARG_COMPONENT);
-        mUri = args.getParcelable(ARG_URI);
+        mNodeId = args.getString(ARG_ID);
 
         // A hint about who we are, so the service can customize the results if it wants to.
         final Bundle rootHints = new Bundle();
@@ -108,7 +108,7 @@
 
         final Bundle args = new Bundle();
         args.putParcelable(BrowserListFragment.ARG_COMPONENT, mComponent);
-        args.putParcelable(BrowserListFragment.ARG_URI, item.media.getDescription().getIconUri());
+        args.putParcelable(BrowserListFragment.ARG_ID, item.media.getDescription().getIconUri());
         fragment.setArguments(args);
 
         getFragmentManager().beginTransaction()
@@ -124,14 +124,14 @@
         @Override
         public void onConnected() {
             Log.d(TAG, "mConnectionCallbacks.onConnected");
-            if (mUri == null) {
-                mUri = mBrowser.getRoot();
+            if (mNodeId == null) {
+                mNodeId = mBrowser.getRoot();
             }
-            mBrowser.subscribe(mUri, new MediaBrowser.SubscriptionCallback() {
+            mBrowser.subscribe(mNodeId, new MediaBrowser.SubscriptionCallback() {
                     @Override
-                    public void onChildrenLoaded(Uri parentUri,
+                public void onChildrenLoaded(String parentId,
                             List<MediaBrowser.MediaItem> children) {
-                        Log.d(TAG, "onChildrenLoaded parentUri=" + parentUri
+                    Log.d(TAG, "onChildrenLoaded parentId=" + parentId
                                 + " children= " + children);
                         mItems.clear();
                         final int N = children.size();
@@ -142,8 +142,8 @@
                     }
 
                     @Override
-                    public void onError(Uri parentUri) {
-                        Log.d(TAG, "onError parentUri=" + parentUri);
+                public void onError(String parentId) {
+                    Log.d(TAG, "onError parentId=" + parentId);
                     }
                 });
         }
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/BrowserService.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/BrowserService.java
index 845db6c..a216a32 100644
--- a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/BrowserService.java
+++ b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/BrowserService.java
@@ -118,11 +118,11 @@
 
     @Override
     public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
-        return new BrowserRoot(BROWSE_URI, null);
+        return new BrowserRoot(BROWSE_URI.toString(), null);
     }
 
     @Override
-    public void onLoadChildren(final Uri parentUri,
+    public void onLoadChildren(final String parentId,
             final Result<List<MediaBrowser.MediaItem>> result) {
         new Handler().postDelayed(new Runnable() {
                 public void run() {
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 397d700..a752686 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -18,7 +18,6 @@
 
 import android.net.wifi.BatchedScanResult;
 import android.net.wifi.BatchedScanSettings;
-import android.net.wifi.WifiAdapter;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.ScanSettings;
@@ -40,9 +39,9 @@
  */
 interface IWifiManager
 {
-    List<WifiAdapter> getAdaptors();
+    int getSupportedFeatures();
 
-    WifiActivityEnergyInfo reportActivityInfo(in WifiAdapter adapter);
+    WifiActivityEnergyInfo reportActivityInfo();
 
     List<WifiConfiguration> getConfiguredNetworks();
 
diff --git a/wifi/java/android/net/wifi/WifiAdapter.aidl b/wifi/java/android/net/wifi/WifiAdapter.aidl
deleted file mode 100644
index 0bb5dd7..0000000
--- a/wifi/java/android/net/wifi/WifiAdapter.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-parcelable WifiAdapter;
diff --git a/wifi/java/android/net/wifi/WifiAdapter.java b/wifi/java/android/net/wifi/WifiAdapter.java
deleted file mode 100644
index 0b12dea..0000000
--- a/wifi/java/android/net/wifi/WifiAdapter.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * Represents local wifi adapter. Different devices have different kinds of
- * wifi adapters; each with different capabilities. Use this class to find out
- * which capabilites are supported by the wifi adapter on the device.
- */
-public class WifiAdapter implements Parcelable {
-    private static final String TAG = "WifiAdapter";
-
-    /* Keep this list in sync with wifi_hal.h */
-    /** @hide */
-    public static final int WIFI_FEATURE_INFRA            = 0x0001;  // Basic infrastructure mode
-    /** @hide */
-    public static final int WIFI_FEATURE_INFRA_5G         = 0x0002;  // Support for 5 GHz Band
-    /** @hide */
-    public static final int WIFI_FEATURE_PASSPOINT        = 0x0004;  // Support for GAS/ANQP
-    /** @hide */
-    public static final int WIFI_FEATURE_P2P              = 0x0008;  // Wifi-Direct
-    /** @hide */
-    public static final int WIFI_FEATURE_MOBILE_HOTSPOT   = 0x0010;  // Soft AP
-    /** @hide */
-    public static final int WIFI_FEATURE_SCANNER          = 0x0020;  // WifiScanner APIs
-    /** @hide */
-    public static final int WIFI_FEATURE_NAN              = 0x0040;  // Neighbor Awareness Networking
-    /** @hide */
-    public static final int WIFI_FEATURE_D2D_RTT          = 0x0080;  // Device-to-device RTT
-    /** @hide */
-    public static final int WIFI_FEATURE_D2AP_RTT         = 0x0100;  // Device-to-AP RTT
-    /** @hide */
-    public static final int WIFI_FEATURE_BATCH_SCAN       = 0x0200;  // Batched Scan (deprecated)
-    /** @hide */
-    public static final int WIFI_FEATURE_PNO              = 0x0400;  // Preferred network offload
-    /** @hide */
-    public static final int WIFI_FEATURE_ADDITIONAL_STA   = 0x0800;  // Support for two STAs
-    /** @hide */
-    public static final int WIFI_FEATURE_TDLS             = 0x1000;  // Tunnel directed link setup
-    /** @hide */
-    public static final int WIFI_FEATURE_TDLS_OFFCHANNEL  = 0x2000;  // Support for TDLS off channel
-    /** @hide */
-    public static final int WIFI_FEATURE_EPR              = 0x4000;  // Enhanced power reporting
-
-    private static final int CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS = 30;
-    /** @hide */
-    public static final int ACTIVITY_ENERGY_INFO_CACHED = 0;
-    /** @hide */
-    public static final int ACTIVITY_ENERGY_INFO_REFRESHED = 1;
-
-    private String name;
-    private int    supportedFeatures;
-
-    // Make the API consistent with BlueTooth Adaptor, allowing WifiService to be accessed
-    // Directly from the adapter
-    /** @hide */
-    public IWifiManager mService = null;
-
-    /** @hide */
-    public WifiAdapter(String name, int supportedFeatures) {
-        this.name = name;
-        this.supportedFeatures = supportedFeatures;
-    }
-
-    /**
-     * @return name of the adapter
-     */
-    public String getName() {
-        return name;
-    }
-
-    private int getSupportedFeatures() {
-        return supportedFeatures;
-    }
-
-    private boolean isFeatureSupported(int feature) {
-        return (supportedFeatures & feature) == feature;
-    }
-
-    /**
-     * @return true if this adapter supports 5 GHz band
-     */
-    public boolean is5GHzBandSupported() {
-        return isFeatureSupported(WIFI_FEATURE_INFRA_5G);
-    }
-
-    /**
-     * @return true if this adapter supports passpoint
-     */
-    public boolean isPasspointSupported() {
-        return isFeatureSupported(WIFI_FEATURE_PASSPOINT);
-    }
-
-    /**
-     * @return true if this adapter supports WifiP2pManager (Wi-Fi Direct)
-     */
-    public boolean isP2pSupported() {
-        return isFeatureSupported(WIFI_FEATURE_P2P);
-    }
-
-    /**
-     * @return true if this adapter supports portable Wi-Fi hotspot
-     */
-    public boolean isPortableHotspotSupported() {
-        return isFeatureSupported(WIFI_FEATURE_MOBILE_HOTSPOT);
-    }
-
-    /**
-     * @return true if this adapter supports WifiScanner APIs
-     */
-    public boolean isWifiScannerSupported() {
-        return isFeatureSupported(WIFI_FEATURE_SCANNER);
-    }
-
-    /**
-     * @return true if this adapter supports Neighbour Awareness Network APIs
-     * @hide
-     */
-    public boolean isNanSupported() {
-        return isFeatureSupported(WIFI_FEATURE_NAN);
-    }
-
-    /**
-     * @return true if this adapter supports Device-to-device RTT
-     */
-    public boolean isDeviceToDeviceRttSupported() {
-        return isFeatureSupported(WIFI_FEATURE_D2D_RTT);
-    }
-
-    /**
-     * @return true if this adapter supports Device-to-AP RTT
-     */
-    public boolean isDeviceToApRttSupported() {
-        return isFeatureSupported(WIFI_FEATURE_D2AP_RTT);
-    }
-
-    /**
-     * @return true if this adapter supports offloaded connectivity scan
-     */
-    public boolean isPreferredNetworkOffloadSupported() {
-        return isFeatureSupported(WIFI_FEATURE_PNO);
-    }
-
-    /**
-     * @return true if this adapter supports multiple simultaneous connections
-     * @hide
-     */
-    public boolean isAdditionalStaSupported() {
-        return isFeatureSupported(WIFI_FEATURE_ADDITIONAL_STA);
-    }
-
-    /**
-     * @return true if this adapter supports Tunnel Directed Link Setup
-     */
-    public boolean isTdlsSupported() {
-        return isFeatureSupported(WIFI_FEATURE_TDLS);
-    }
-
-    /**
-     * @return true if this adapter supports Off Channel Tunnel Directed Link Setup
-     */
-    public boolean isOffChannelTdlsSupported() {
-        return isFeatureSupported(WIFI_FEATURE_TDLS_OFFCHANNEL);
-    }
-
-    /**
-     * @return true if this adapter supports advanced power/performance counters
-     */
-    public boolean isEnhancedPowerReportingSupported() {
-        return isFeatureSupported(WIFI_FEATURE_EPR);
-    }
-
-
-    /**
-     * Return the record of {@link WifiActivityEnergyInfo} object that
-     * has the activity and energy info. This can be used to ascertain what
-     * the controller has been up to, since the last sample.
-     * @param updateType Type of info, cached vs refreshed.
-     *
-     * @return a record with {@link WifiActivityEnergyInfo} or null if
-     * report is unavailable or unsupported
-     * @hide
-     */
-    public WifiActivityEnergyInfo getControllerActivityEnergyInfo(int updateType) {
-        if (mService == null) return null;
-        try {
-            WifiActivityEnergyInfo record;
-            if (!isEnhancedPowerReportingSupported()) {
-                return null;
-            }
-            synchronized(this) {
-                record = mService.reportActivityInfo(this);
-                if (record.isValid()) {
-                    return record;
-                } else {
-                    return null;
-                }
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "getControllerActivityEnergyInfo: " + e);
-        }
-        return null;
-    }
-
-    /* Parcelable implementation */
-    /**
-     * Implement the Parcelable interface
-     * {@hide}
-     */
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * Implement the Parcelable interface
-     * {@hide}
-     */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(name);
-        dest.writeInt(supportedFeatures);
-    }
-
-    /**
-     * Implement the Parcelable interface
-     * {@hide}
-     */
-    public static final Creator<WifiAdapter> CREATOR =
-            new Creator<WifiAdapter>() {
-                public WifiAdapter createFromParcel(Parcel in) {
-                    WifiAdapter adaptor = new WifiAdapter(in.readString(), in.readInt());
-                    return adaptor;
-                }
-
-                public WifiAdapter[] newArray(int size) {
-                    return new WifiAdapter[size];
-                }
-            };
-}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 4a4da22..74f2f65 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -576,22 +576,6 @@
     }
 
     /**
-     * Retrieve all wifi adapters available on this device
-     * @return list of adapters
-     */
-    public List<WifiAdapter> getAdapters() {
-        try {
-            List<WifiAdapter> adapterList = mService.getAdaptors();
-            for (WifiAdapter a : adapterList) {
-                a.mService = mService;
-            }
-            return adapterList;
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /**
      * Return a list of all the networks configured in the supplicant.
      * Not all fields of WifiConfiguration are returned. Only the following
      * fields are filled in:
@@ -824,6 +808,182 @@
         }
     }
 
+    /* Keep this list in sync with wifi_hal.h */
+    /** @hide */
+    public static final int WIFI_FEATURE_INFRA            = 0x0001;  // Basic infrastructure mode
+    /** @hide */
+    public static final int WIFI_FEATURE_INFRA_5G         = 0x0002;  // Support for 5 GHz Band
+    /** @hide */
+    public static final int WIFI_FEATURE_PASSPOINT        = 0x0004;  // Support for GAS/ANQP
+    /** @hide */
+    public static final int WIFI_FEATURE_P2P              = 0x0008;  // Wifi-Direct
+    /** @hide */
+    public static final int WIFI_FEATURE_MOBILE_HOTSPOT   = 0x0010;  // Soft AP
+    /** @hide */
+    public static final int WIFI_FEATURE_SCANNER          = 0x0020;  // WifiScanner APIs
+    /** @hide */
+    public static final int WIFI_FEATURE_NAN              = 0x0040;  // Neighbor Awareness Networking
+    /** @hide */
+    public static final int WIFI_FEATURE_D2D_RTT          = 0x0080;  // Device-to-device RTT
+    /** @hide */
+    public static final int WIFI_FEATURE_D2AP_RTT         = 0x0100;  // Device-to-AP RTT
+    /** @hide */
+    public static final int WIFI_FEATURE_BATCH_SCAN       = 0x0200;  // Batched Scan (deprecated)
+    /** @hide */
+    public static final int WIFI_FEATURE_PNO              = 0x0400;  // Preferred network offload
+    /** @hide */
+    public static final int WIFI_FEATURE_ADDITIONAL_STA   = 0x0800;  // Support for two STAs
+    /** @hide */
+    public static final int WIFI_FEATURE_TDLS             = 0x1000;  // Tunnel directed link setup
+    /** @hide */
+    public static final int WIFI_FEATURE_TDLS_OFFCHANNEL  = 0x2000;  // Support for TDLS off channel
+    /** @hide */
+    public static final int WIFI_FEATURE_EPR              = 0x4000;  // Enhanced power reporting
+
+    private int getSupportedFeatures() {
+        try {
+            return mService.getSupportedFeatures();
+        } catch (RemoteException e) {
+            return 0;
+        }
+    }
+
+    private boolean isFeatureSupported(int feature) {
+        return (getSupportedFeatures() & feature) == feature;
+    }
+    /**
+     * @return true if this adapter supports 5 GHz band
+     */
+    public boolean is5GHzBandSupported() {
+        return isFeatureSupported(WIFI_FEATURE_INFRA_5G);
+    }
+
+    /**
+     * @return true if this adapter supports passpoint
+     * @hide
+     */
+    public boolean isPasspointSupported() {
+        return isFeatureSupported(WIFI_FEATURE_PASSPOINT);
+    }
+
+    /**
+     * @return true if this adapter supports WifiP2pManager (Wi-Fi Direct)
+     */
+    public boolean isP2pSupported() {
+        return isFeatureSupported(WIFI_FEATURE_P2P);
+    }
+
+    /**
+     * @return true if this adapter supports portable Wi-Fi hotspot
+     * @hide
+     */
+    @SystemApi
+    public boolean isPortableHotspotSupported() {
+        return isFeatureSupported(WIFI_FEATURE_MOBILE_HOTSPOT);
+    }
+
+    /**
+     * @return true if this adapter supports WifiScanner APIs
+     * @hide
+     */
+    @SystemApi
+    public boolean isWifiScannerSupported() {
+        return isFeatureSupported(WIFI_FEATURE_SCANNER);
+    }
+
+    /**
+     * @return true if this adapter supports Neighbour Awareness Network APIs
+     * @hide
+     */
+    public boolean isNanSupported() {
+        return isFeatureSupported(WIFI_FEATURE_NAN);
+    }
+
+    /**
+     * @return true if this adapter supports Device-to-device RTT
+     * @hide
+     */
+    @SystemApi
+    public boolean isDeviceToDeviceRttSupported() {
+        return isFeatureSupported(WIFI_FEATURE_D2D_RTT);
+    }
+
+    /**
+     * @return true if this adapter supports Device-to-AP RTT
+     */
+    @SystemApi
+    public boolean isDeviceToApRttSupported() {
+        return isFeatureSupported(WIFI_FEATURE_D2AP_RTT);
+    }
+
+    /**
+     * @return true if this adapter supports offloaded connectivity scan
+     */
+    public boolean isPreferredNetworkOffloadSupported() {
+        return isFeatureSupported(WIFI_FEATURE_PNO);
+    }
+
+    /**
+     * @return true if this adapter supports multiple simultaneous connections
+     * @hide
+     */
+    public boolean isAdditionalStaSupported() {
+        return isFeatureSupported(WIFI_FEATURE_ADDITIONAL_STA);
+    }
+
+    /**
+     * @return true if this adapter supports Tunnel Directed Link Setup
+     */
+    public boolean isTdlsSupported() {
+        return isFeatureSupported(WIFI_FEATURE_TDLS);
+    }
+
+    /**
+     * @return true if this adapter supports Off Channel Tunnel Directed Link Setup
+     * @hide
+     */
+    public boolean isOffChannelTdlsSupported() {
+        return isFeatureSupported(WIFI_FEATURE_TDLS_OFFCHANNEL);
+    }
+
+    /**
+     * @return true if this adapter supports advanced power/performance counters
+     */
+    public boolean isEnhancedPowerReportingSupported() {
+        return isFeatureSupported(WIFI_FEATURE_EPR);
+    }
+
+    /**
+     * Return the record of {@link WifiActivityEnergyInfo} object that
+     * has the activity and energy info. This can be used to ascertain what
+     * the controller has been up to, since the last sample.
+     * @param updateType Type of info, cached vs refreshed.
+     *
+     * @return a record with {@link WifiActivityEnergyInfo} or null if
+     * report is unavailable or unsupported
+     * @hide
+     */
+    public WifiActivityEnergyInfo getControllerActivityEnergyInfo(int updateType) {
+        if (mService == null) return null;
+        try {
+            WifiActivityEnergyInfo record;
+            if (!isEnhancedPowerReportingSupported()) {
+                return null;
+            }
+            synchronized(this) {
+                record = mService.reportActivityInfo();
+                if (record.isValid()) {
+                    return record;
+                } else {
+                    return null;
+                }
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "getControllerActivityEnergyInfo: " + e);
+        }
+        return null;
+    }
+
     /**
      * Request a scan for access points. Returns immediately. The availability
      * of the results is made known later by means of an asynchronous event sent
@@ -1457,12 +1617,14 @@
     /**
      * Passed with {@link ActionListener#onFailure}.
      * Indicates that the operation failed due to an internal error.
+     * @hide
      */
     public static final int ERROR                       = 0;
 
     /**
      * Passed with {@link ActionListener#onFailure}.
      * Indicates that the operation is already in progress
+     * @hide
      */
     public static final int IN_PROGRESS                 = 1;
 
@@ -1470,6 +1632,7 @@
      * Passed with {@link ActionListener#onFailure}.
      * Indicates that the operation failed because the framework is busy and
      * unable to service the request
+     * @hide
      */
     public static final int BUSY                        = 2;
 
@@ -1488,18 +1651,21 @@
     /**
      * Passed with {@link ActionListener#onFailure}.
      * Indicates that the operation failed due to invalid inputs
+     * @hide
      */
     public static final int INVALID_ARGS                = 8;
 
     /**
      * Passed with {@link ActionListener#onFailure}.
      * Indicates that the operation failed due to user permissions.
-     *
      * @hide
      */
     public static final int NOT_AUTHORIZED              = 9;
 
-    /** Interface for callback invocation on an application action */
+    /**
+     * Interface for callback invocation on an application action
+     * @hide
+     */
     public interface ActionListener {
         /** The operation succeeded */
         public void onSuccess();
@@ -1512,19 +1678,21 @@
     }
 
     /** Interface for callback invocation on a start WPS action */
-    public interface WpsListener {
+    public static abstract class WpsCallback {
         /** WPS start succeeded */
-        public void onStartSuccess(String pin);
+        public abstract void onStarted(String pin);
 
         /** WPS operation completed succesfully */
-        public void onCompletion();
+        public abstract void onSucceeded();
 
         /**
          * WPS operation failed
          * @param reason The reason for failure could be one of
-         * {@link #IN_PROGRESS}, {@link #WPS_OVERLAP_ERROR},{@link #ERROR} or {@link #BUSY}
+         * {@link #WPS_TKIP_ONLY_PROHIBITED}, {@link #WPS_OVERLAP_ERROR},
+         * {@link #WPS_WEP_PROHIBITED}, {@link #WPS_TIMED_OUT} or {@link #WPS_AUTH_FAILURE}
+         * and some generic errors.
          */
-        public void onFailure(int reason);
+        public abstract void onFailed(int reason);
     }
 
     /** Interface for callback invocation on a TX packet count poll action {@hide} */
@@ -1576,7 +1744,6 @@
                 case WifiManager.CONNECT_NETWORK_FAILED:
                 case WifiManager.FORGET_NETWORK_FAILED:
                 case WifiManager.SAVE_NETWORK_FAILED:
-                case WifiManager.CANCEL_WPS_FAILED:
                 case WifiManager.DISABLE_NETWORK_FAILED:
                     if (listener != null) {
                         ((ActionListener) listener).onFailure(message.arg1);
@@ -1586,7 +1753,6 @@
                 case WifiManager.CONNECT_NETWORK_SUCCEEDED:
                 case WifiManager.FORGET_NETWORK_SUCCEEDED:
                 case WifiManager.SAVE_NETWORK_SUCCEEDED:
-                case WifiManager.CANCEL_WPS_SUCCEDED:
                 case WifiManager.DISABLE_NETWORK_SUCCEEDED:
                     if (listener != null) {
                         ((ActionListener) listener).onSuccess();
@@ -1595,7 +1761,7 @@
                 case WifiManager.START_WPS_SUCCEEDED:
                     if (listener != null) {
                         WpsResult result = (WpsResult) message.obj;
-                        ((WpsListener) listener).onStartSuccess(result.pin);
+                        ((WpsCallback) listener).onStarted(result.pin);
                         //Listener needs to stay until completion or failure
                         synchronized(sListenerMapLock) {
                             sListenerMap.put(message.arg2, listener);
@@ -1604,12 +1770,22 @@
                     break;
                 case WifiManager.WPS_COMPLETED:
                     if (listener != null) {
-                        ((WpsListener) listener).onCompletion();
+                        ((WpsCallback) listener).onSucceeded();
                     }
                     break;
                 case WifiManager.WPS_FAILED:
                     if (listener != null) {
-                        ((WpsListener) listener).onFailure(message.arg1);
+                        ((WpsCallback) listener).onFailed(message.arg1);
+                    }
+                    break;
+                case WifiManager.CANCEL_WPS_SUCCEDED:
+                    if (listener != null) {
+                        ((WpsCallback) listener).onSucceeded();
+                    }
+                    break;
+                case WifiManager.CANCEL_WPS_FAILED:
+                    if (listener != null) {
+                        ((WpsCallback) listener).onFailed(message.arg1);
                     }
                     break;
                 case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED:
@@ -1794,7 +1970,7 @@
      * @throws IllegalStateException if the WifiManager instance needs to be
      * initialized again
      */
-    public void startWps(WpsInfo config, WpsListener listener) {
+    public void startWps(WpsInfo config, WpsCallback listener) {
         if (config == null) throw new IllegalArgumentException("config cannot be null");
         validateChannel();
         sAsyncChannel.sendMessage(START_WPS, 0, putListener(listener), config);
@@ -1807,7 +1983,7 @@
      * @throws IllegalStateException if the WifiManager instance needs to be
      * initialized again
      */
-    public void cancelWps(ActionListener listener) {
+    public void cancelWps(WpsCallback listener) {
         validateChannel();
         sAsyncChannel.sendMessage(CANCEL_WPS, 0, putListener(listener));
     }
@@ -2352,4 +2528,7 @@
             return 0;
         }
     }
+
+
+
 }